From: Denis Vlasenko Signed-off-by: Denis Vlasenko Signed-off-by: Andrew Morton --- drivers/net/wireless/tiacx/Changelog | 97 drivers/net/wireless/tiacx/README | 1 drivers/net/wireless/tiacx/acx_config.h | 14 drivers/net/wireless/tiacx/acx_func.h | 329 - drivers/net/wireless/tiacx/acx_struct.h | 378 +- drivers/net/wireless/tiacx/common.c | 3951 ++++++++++----------- drivers/net/wireless/tiacx/conv.c | 63 drivers/net/wireless/tiacx/ioctl.c | 1984 ++++------ drivers/net/wireless/tiacx/pci.c | 1765 ++++----- drivers/net/wireless/tiacx/usb.c | 483 +- drivers/net/wireless/tiacx/wlan.c | 21 drivers/net/wireless/tiacx/wlan_compat.h | 39 drivers/net/wireless/tiacx/wlan_mgmt.h | 24 13 files changed, 4411 insertions(+), 4738 deletions(-) diff -puN drivers/net/wireless/tiacx/acx_config.h~update-mm-acx-driver-to-version-0331 drivers/net/wireless/tiacx/acx_config.h --- devel/drivers/net/wireless/tiacx/acx_config.h~update-mm-acx-driver-to-version-0331 2006-01-31 18:11:09.000000000 -0800 +++ devel-akpm/drivers/net/wireless/tiacx/acx_config.h 2006-01-31 18:11:09.000000000 -0800 @@ -1,9 +1,10 @@ -#define ACX_RELEASE "v0.3.23" +#define ACX_RELEASE "v0.3.31" /* set to 0 if you don't want any debugging code to be compiled in */ /* set to 1 if you want some debugging */ /* set to 2 if you want extensive debug log */ #define ACX_DEBUG 1 +#define ACX_DEFAULT_MSG 0 /* assume 32bit I/O width * (16bit is also compatible with Compact Flash) */ @@ -21,12 +22,11 @@ * even if that probably means worse latency */ #define TX_CLEANUP_IN_SOFTIRQ 0 -/* set to 1 if you want to have 1 driver per card instead of 1 single driver - * managing all cards (of a particular bus type) in your system - * Useful e.g. if you need to reinitialize single cards from time to time - * LINUX 2.4.X ONLY!! (pci_for_each_dev()) Feel free to implement 2.6.x - * compatibility... */ -#define SEPARATE_DRIVER_INSTANCES 0 +/* if you want very experimental 802.11 power save mode features */ +#define POWER_SAVE_80211 0 + +/* if you want very early packet fragmentation bits and pieces */ +#define ACX_FRAGMENTATION 0 /* Locking: */ /* very talkative */ diff -puN drivers/net/wireless/tiacx/acx_func.h~update-mm-acx-driver-to-version-0331 drivers/net/wireless/tiacx/acx_func.h --- devel/drivers/net/wireless/tiacx/acx_func.h~update-mm-acx-driver-to-version-0331 2006-01-31 18:11:09.000000000 -0800 +++ devel-akpm/drivers/net/wireless/tiacx/acx_func.h 2006-01-31 18:11:09.000000000 -0800 @@ -171,7 +171,7 @@ mac_is_equal(const u8 *a, const u8 *b) static inline int mac_is_bcast(const u8 *mac) { - /* AND together 4 first bytes with sign-entended 2 last bytes + /* AND together 4 first bytes with sign-extended 2 last bytes ** Only bcast address gives 0xffffffff. +1 gives 0 */ return ( *(s32*)mac & ((s16*)mac)[2] ) + 1 == 0; } @@ -243,18 +243,18 @@ has_only_one_bit(u16 v) /*********************************************************************** ** LOCKING -** We have priv->sem and priv->lock. +** We have adev->sem and adev->lock. ** ** We employ following naming convention in order to get locking right: ** ** acx_e_xxxx - external entry points called from process context. -** It is okay to sleep. priv->sem is to be taken on entry. +** It is okay to sleep. adev->sem is to be taken on entry. ** acx_i_xxxx - external entry points possibly called from atomic context. ** Sleeping is not allowed (and thus down(sem) is not legal!) ** acx_s_xxxx - potentially sleeping functions. Do not ever call under lock! ** acx_l_xxxx - functions which expect lock to be already taken. ** rest - non-sleeping functions which do not require locking -** but may be run inder lock +** but may be run under lock ** ** A small number of local helpers do not have acx_[eisl]_ prefix. ** They are always close to caller and are to be revieved locally. @@ -288,55 +288,55 @@ has_only_one_bit(u16 v) #if defined(PARANOID_LOCKING) /* Lock debugging */ -void acx_lock_debug(wlandevice_t *priv, const char* where); -void acx_unlock_debug(wlandevice_t *priv, const char* where); -void acx_down_debug(wlandevice_t *priv, const char* where); -void acx_up_debug(wlandevice_t *priv, const char* where); +void acx_lock_debug(acx_device_t *adev, const char* where); +void acx_unlock_debug(acx_device_t *adev, const char* where); +void acx_down_debug(acx_device_t *adev, const char* where); +void acx_up_debug(acx_device_t *adev, const char* where); void acx_lock_unhold(void); void acx_sem_unhold(void); static inline void -acx_lock_helper(wlandevice_t *priv, unsigned long *fp, const char* where) +acx_lock_helper(acx_device_t *adev, unsigned long *fp, const char* where) { - acx_lock_debug(priv, where); - spin_lock_irqsave(&priv->lock, *fp); + acx_lock_debug(adev, where); + spin_lock_irqsave(&adev->lock, *fp); } static inline void -acx_unlock_helper(wlandevice_t *priv, unsigned long *fp, const char* where) +acx_unlock_helper(acx_device_t *adev, unsigned long *fp, const char* where) { - acx_unlock_debug(priv, where); - spin_unlock_irqrestore(&priv->lock, *fp); + acx_unlock_debug(adev, where); + spin_unlock_irqrestore(&adev->lock, *fp); } static inline void -acx_down_helper(wlandevice_t *priv, const char* where) +acx_down_helper(acx_device_t *adev, const char* where) { - acx_down_debug(priv, where); + acx_down_debug(adev, where); } static inline void -acx_up_helper(wlandevice_t *priv, const char* where) +acx_up_helper(acx_device_t *adev, const char* where) { - acx_up_debug(priv, where); + acx_up_debug(adev, where); } -#define acx_lock(priv, flags) acx_lock_helper(priv, &(flags), __FILE__ ":" STRING(__LINE__)) -#define acx_unlock(priv, flags) acx_unlock_helper(priv, &(flags), __FILE__ ":" STRING(__LINE__)) -#define acx_sem_lock(priv) acx_down_helper(priv, __FILE__ ":" STRING(__LINE__)) -#define acx_sem_unlock(priv) acx_up_helper(priv, __FILE__ ":" STRING(__LINE__)) +#define acx_lock(adev, flags) acx_lock_helper(adev, &(flags), __FILE__ ":" STRING(__LINE__)) +#define acx_unlock(adev, flags) acx_unlock_helper(adev, &(flags), __FILE__ ":" STRING(__LINE__)) +#define acx_sem_lock(adev) acx_down_helper(adev, __FILE__ ":" STRING(__LINE__)) +#define acx_sem_unlock(adev) acx_up_helper(adev, __FILE__ ":" STRING(__LINE__)) #elif defined(DO_LOCKING) -#define acx_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags) -#define acx_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags) -#define acx_sem_lock(priv) down(&priv->sem) -#define acx_sem_unlock(priv) up(&priv->sem) +#define acx_lock(adev, flags) spin_lock_irqsave(&adev->lock, flags) +#define acx_unlock(adev, flags) spin_unlock_irqrestore(&adev->lock, flags) +#define acx_sem_lock(adev) down(&adev->sem) +#define acx_sem_unlock(adev) up(&adev->sem) #define acx_lock_unhold() ((void)0) #define acx_sem_unhold() ((void)0) #else /* no locking! :( */ -#define acx_lock(priv, flags) ((void)0) -#define acx_unlock(priv, flags) ((void)0) -#define acx_sem_lock(priv) ((void)0) -#define acx_sem_unlock(priv) ((void)0) +#define acx_lock(adev, flags) ((void)0) +#define acx_unlock(adev, flags) ((void)0) +#define acx_sem_lock(adev) ((void)0) +#define acx_sem_unlock(adev) ((void)0) #define acx_lock_unhold() ((void)0) #define acx_sem_unhold() ((void)0) @@ -352,52 +352,52 @@ acx_up_helper(wlandevice_t *priv, const ** IRQ -> acxpci_l_clean_txdesc -> acx_wake_queue ** Review carefully all callsites */ static inline void -acx_stop_queue(netdevice_t *dev, const char *msg) +acx_stop_queue(struct net_device *ndev, const char *msg) { - if (netif_queue_stopped(dev)) + if (netif_queue_stopped(ndev)) return; - netif_stop_queue(dev); + netif_stop_queue(ndev); if (msg) log(L_BUFT, "tx: stop queue %s\n", msg); } static inline int -acx_queue_stopped(netdevice_t *dev) +acx_queue_stopped(struct net_device *ndev) { - return netif_queue_stopped(dev); + return netif_queue_stopped(ndev); } /* static inline void -acx_start_queue(netdevice_t *dev, const char *msg) +acx_start_queue(struct net_device *ndev, const char *msg) { - netif_start_queue(dev); + netif_start_queue(ndev); if (msg) log(L_BUFT, "tx: start queue %s\n", msg); } */ static inline void -acx_wake_queue(netdevice_t *dev, const char *msg) +acx_wake_queue(struct net_device *ndev, const char *msg) { - netif_wake_queue(dev); + netif_wake_queue(ndev); if (msg) log(L_BUFT, "tx: wake queue %s\n", msg); } static inline void -acx_carrier_off(netdevice_t *dev, const char *msg) +acx_carrier_off(struct net_device *ndev, const char *msg) { - netif_carrier_off(dev); + netif_carrier_off(ndev); if (msg) log(L_BUFT, "tx: carrier off %s\n", msg); } static inline void -acx_carrier_on(netdevice_t *dev, const char *msg) +acx_carrier_on(struct net_device *ndev, const char *msg) { - netif_carrier_on(dev); + netif_carrier_on(ndev); if (msg) log(L_BUFT, "tx: carrier on %s\n", msg); } @@ -405,7 +405,7 @@ acx_carrier_on(netdevice_t *dev, const c /* This function does not need locking UNLESS you call it ** as acx_set_status(ACX_STATUS_4_ASSOCIATED), bacause this can ** wake queue. This can race with stop_queue elsewhere. */ -void acx_set_status(wlandevice_t *priv, u16 status); +void acx_set_status(acx_device_t *adev, u16 status); /*********************************************************************** @@ -417,50 +417,50 @@ void acx_set_status(wlandevice_t *priv, #if ACX_DEBUG /* We want to log cmd names */ -int acxpci_s_issue_cmd_timeo_debug(wlandevice_t *priv, unsigned cmd, void *param, unsigned len, unsigned timeout, const char* cmdstr); -int acxusb_s_issue_cmd_timeo_debug(wlandevice_t *priv, unsigned cmd, void *param, unsigned len, unsigned timeout, const char* cmdstr); +int acxpci_s_issue_cmd_timeo_debug(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout, const char* cmdstr); +int acxusb_s_issue_cmd_timeo_debug(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout, const char* cmdstr); static inline int -acx_s_issue_cmd_timeo_debug(wlandevice_t *priv, unsigned cmd, void *param, unsigned len, unsigned timeout, const char* cmdstr) +acx_s_issue_cmd_timeo_debug(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout, const char* cmdstr) { - if (IS_PCI(priv)) - return acxpci_s_issue_cmd_timeo_debug(priv, cmd, param, len, timeout, cmdstr); - return acxusb_s_issue_cmd_timeo_debug(priv, cmd, param, len, timeout, cmdstr); -} -#define acx_s_issue_cmd(priv,cmd,param,len) \ - acx_s_issue_cmd_timeo_debug(priv,cmd,param,len,ACX_CMD_TIMEOUT_DEFAULT,#cmd) -#define acx_s_issue_cmd_timeo(priv,cmd,param,len,timeo) \ - acx_s_issue_cmd_timeo_debug(priv,cmd,param,len,timeo,#cmd) -int acx_s_configure_debug(wlandevice_t *priv, void *pdr, int type, const char* str); -#define acx_s_configure(priv,pdr,type) \ - acx_s_configure_debug(priv,pdr,type,#type) -int acx_s_interrogate_debug(wlandevice_t *priv, void *pdr, int type, const char* str); -#define acx_s_interrogate(priv,pdr,type) \ - acx_s_interrogate_debug(priv,pdr,type,#type) + if (IS_PCI(adev)) + return acxpci_s_issue_cmd_timeo_debug(adev, cmd, param, len, timeout, cmdstr); + return acxusb_s_issue_cmd_timeo_debug(adev, cmd, param, len, timeout, cmdstr); +} +#define acx_s_issue_cmd(adev,cmd,param,len) \ + acx_s_issue_cmd_timeo_debug(adev,cmd,param,len,ACX_CMD_TIMEOUT_DEFAULT,#cmd) +#define acx_s_issue_cmd_timeo(adev,cmd,param,len,timeo) \ + acx_s_issue_cmd_timeo_debug(adev,cmd,param,len,timeo,#cmd) +int acx_s_configure_debug(acx_device_t *adev, void *pdr, int type, const char* str); +#define acx_s_configure(adev,pdr,type) \ + acx_s_configure_debug(adev,pdr,type,#type) +int acx_s_interrogate_debug(acx_device_t *adev, void *pdr, int type, const char* str); +#define acx_s_interrogate(adev,pdr,type) \ + acx_s_interrogate_debug(adev,pdr,type,#type) #else -int acxpci_s_issue_cmd_timeo(wlandevice_t *priv, unsigned cmd, void *param, unsigned len, unsigned timeout); -int acxusb_s_issue_cmd_timeo(wlandevice_t *priv, unsigned cmd, void *param, unsigned len, unsigned timeout); +int acxpci_s_issue_cmd_timeo(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout); +int acxusb_s_issue_cmd_timeo(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout); static inline int -acx_s_issue_cmd_timeo(wlandevice_t *priv, unsigned cmd, void *param, unsigned len, unsigned timeout) +acx_s_issue_cmd_timeo(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout) { - if (IS_PCI(priv)) - return acxpci_s_issue_cmd_timeo(priv, cmd, param, len, timeout); - return acxusb_s_issue_cmd_timeo(priv, cmd, param, len, timeout); + if (IS_PCI(adev)) + return acxpci_s_issue_cmd_timeo(adev, cmd, param, len, timeout); + return acxusb_s_issue_cmd_timeo(adev, cmd, param, len, timeout); } static inline int -acx_s_issue_cmd(wlandevice_t *priv, unsigned cmd, void *param, unsigned len) +acx_s_issue_cmd(acx_device_t *adev, unsigned cmd, void *param, unsigned len) { - if (IS_PCI(priv)) - return acxpci_s_issue_cmd_timeo(priv, cmd, param, len, ACX_CMD_TIMEOUT_DEFAULT); - return acxusb_s_issue_cmd_timeo(priv, cmd, param, len, ACX_CMD_TIMEOUT_DEFAULT); + if (IS_PCI(adev)) + return acxpci_s_issue_cmd_timeo(adev, cmd, param, len, ACX_CMD_TIMEOUT_DEFAULT); + return acxusb_s_issue_cmd_timeo(adev, cmd, param, len, ACX_CMD_TIMEOUT_DEFAULT); } -int acx_s_configure(wlandevice_t *priv, void *pdr, int type); -int acx_s_interrogate(wlandevice_t *priv, void *pdr, int type); +int acx_s_configure(acx_device_t *adev, void *pdr, int type); +int acx_s_interrogate(acx_device_t *adev, void *pdr, int type); #endif -void acx_s_cmd_start_scan(wlandevice_t *priv); +void acx_s_cmd_start_scan(acx_device_t *adev); /*********************************************************************** @@ -468,13 +468,13 @@ void acx_s_cmd_start_scan(wlandevice_t * */ int acx111pci_ioctl_info( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, struct iw_param *vwrq, char *extra); int acx100pci_ioctl_set_phy_amp_bias( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, struct iw_param *vwrq, char *extra); @@ -484,145 +484,132 @@ acx100pci_ioctl_set_phy_amp_bias( ** /proc */ #ifdef CONFIG_PROC_FS -int acx_proc_register_entries(const struct net_device *dev); -int acx_proc_unregister_entries(const struct net_device *dev); +int acx_proc_register_entries(const struct net_device *ndev); +int acx_proc_unregister_entries(const struct net_device *ndev); #else static inline int -acx_proc_register_entries(const struct net_device *dev) { return OK; } +acx_proc_register_entries(const struct net_device *ndev) { return OK; } static inline int -acx_proc_unregister_entries(const struct net_device *dev) { return OK; } +acx_proc_unregister_entries(const struct net_device *ndev) { return OK; } #endif /*********************************************************************** */ -#if USE_FW_LOADER_26 firmware_image_t *acx_s_read_fw(struct device *dev, const char *file, u32 *size); -#else -firmware_image_t *acx_s_read_fw(const char *file, u32 *size); -#define acx_s_read_fw(dev, file, size) acx_s_read_fw(file, size) -#endif -int acxpci_s_upload_radio(wlandevice_t *priv); +int acxpci_s_upload_radio(acx_device_t *adev); /*********************************************************************** ** Unsorted yet :) */ -int acxpci_s_read_phy_reg(wlandevice_t *priv, u32 reg, u8 *charbuf); -int acxusb_s_read_phy_reg(wlandevice_t *priv, u32 reg, u8 *charbuf); +int acxpci_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf); +int acxusb_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf); static inline int -acx_s_read_phy_reg(wlandevice_t *priv, u32 reg, u8 *charbuf) +acx_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf) { - if (IS_PCI(priv)) - return acxpci_s_read_phy_reg(priv, reg, charbuf); - return acxusb_s_read_phy_reg(priv, reg, charbuf); + if (IS_PCI(adev)) + return acxpci_s_read_phy_reg(adev, reg, charbuf); + return acxusb_s_read_phy_reg(adev, reg, charbuf); } -int acxpci_s_write_phy_reg(wlandevice_t *priv, u32 reg, u8 value); -int acxusb_s_write_phy_reg(wlandevice_t *priv, u32 reg, u8 value); +int acxpci_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value); +int acxusb_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value); static inline int -acx_s_write_phy_reg(wlandevice_t *priv, u32 reg, u8 value) +acx_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value) { - if (IS_PCI(priv)) - return acxpci_s_write_phy_reg(priv, reg, value); - return acxusb_s_write_phy_reg(priv, reg, value); + if (IS_PCI(adev)) + return acxpci_s_write_phy_reg(adev, reg, value); + return acxusb_s_write_phy_reg(adev, reg, value); } -tx_t* acxpci_l_alloc_tx(wlandevice_t *priv); -tx_t* acxusb_l_alloc_tx(wlandevice_t *priv); +tx_t* acxpci_l_alloc_tx(acx_device_t *adev); +tx_t* acxusb_l_alloc_tx(acx_device_t *adev); static inline tx_t* -acx_l_alloc_tx(wlandevice_t *priv) +acx_l_alloc_tx(acx_device_t *adev) { - if (IS_PCI(priv)) - return acxpci_l_alloc_tx(priv); - return acxusb_l_alloc_tx(priv); + if (IS_PCI(adev)) + return acxpci_l_alloc_tx(adev); + return acxusb_l_alloc_tx(adev); } void acxusb_l_dealloc_tx(tx_t *tx_opaque); static inline void -acx_l_dealloc_tx(wlandevice_t *priv, tx_t *tx_opaque) +acx_l_dealloc_tx(acx_device_t *adev, tx_t *tx_opaque) { - if (IS_USB(priv)) + if (IS_USB(adev)) acxusb_l_dealloc_tx(tx_opaque); } -void* acxpci_l_get_txbuf(wlandevice_t *priv, tx_t *tx_opaque); -void* acxusb_l_get_txbuf(wlandevice_t *priv, tx_t *tx_opaque); +void* acxpci_l_get_txbuf(acx_device_t *adev, tx_t *tx_opaque); +void* acxusb_l_get_txbuf(acx_device_t *adev, tx_t *tx_opaque); static inline void* -acx_l_get_txbuf(wlandevice_t *priv, tx_t *tx_opaque) +acx_l_get_txbuf(acx_device_t *adev, tx_t *tx_opaque) { - if (IS_PCI(priv)) - return acxpci_l_get_txbuf(priv, tx_opaque); - return acxusb_l_get_txbuf(priv, tx_opaque); + if (IS_PCI(adev)) + return acxpci_l_get_txbuf(adev, tx_opaque); + return acxusb_l_get_txbuf(adev, tx_opaque); } -void acxpci_l_tx_data(wlandevice_t *priv, tx_t *tx_opaque, int len); -void acxusb_l_tx_data(wlandevice_t *priv, tx_t *tx_opaque, int len); +void acxpci_l_tx_data(acx_device_t *adev, tx_t *tx_opaque, int len); +void acxusb_l_tx_data(acx_device_t *adev, tx_t *tx_opaque, int len); static inline void -acx_l_tx_data(wlandevice_t *priv, tx_t *tx_opaque, int len) +acx_l_tx_data(acx_device_t *adev, tx_t *tx_opaque, int len) { - if (IS_PCI(priv)) - acxpci_l_tx_data(priv, tx_opaque, len); + if (IS_PCI(adev)) + acxpci_l_tx_data(adev, tx_opaque, len); else - acxusb_l_tx_data(priv, tx_opaque, len); + acxusb_l_tx_data(adev, tx_opaque, len); } static inline wlan_hdr_t* -acx_get_wlan_hdr(wlandevice_t *priv, const rxbuffer_t *rxbuf) +acx_get_wlan_hdr(acx_device_t *adev, const rxbuffer_t *rxbuf) { - if (!(priv->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR)) - return (wlan_hdr_t*)&rxbuf->hdr_a3; + return (wlan_hdr_t*)((u8*)&rxbuf->hdr_a3 + adev->phy_header_len); +} - /* take into account phy header in front of packet */ - if (IS_ACX111(priv)) - return (wlan_hdr_t*)((u8*)&rxbuf->hdr_a3 + 8); - - return (wlan_hdr_t*)((u8*)&rxbuf->hdr_a3 + 4); -} - -void acxpci_l_power_led(wlandevice_t *priv, int enable); -int acxpci_read_eeprom_byte(wlandevice_t *priv, u32 addr, u8 *charbuf); -unsigned int acxpci_l_clean_txdesc(wlandevice_t *priv); -void acxpci_l_clean_txdesc_emergency(wlandevice_t *priv); -int acxpci_s_create_hostdesc_queues(wlandevice_t *priv); -void acxpci_create_desc_queues(wlandevice_t *priv, u32 tx_queue_start, u32 rx_queue_start); -void acxpci_free_desc_queues(wlandevice_t *priv); -char* acxpci_s_proc_diag_output(char *p, wlandevice_t *priv); -int acxpci_proc_eeprom_output(char *p, wlandevice_t *priv); -void acxpci_set_interrupt_mask(wlandevice_t *priv); -int acx100pci_s_set_tx_level(wlandevice_t *priv, u8 level_dbm); +void acxpci_l_power_led(acx_device_t *adev, int enable); +int acxpci_read_eeprom_byte(acx_device_t *adev, u32 addr, u8 *charbuf); +unsigned int acxpci_l_clean_txdesc(acx_device_t *adev); +void acxpci_l_clean_txdesc_emergency(acx_device_t *adev); +int acxpci_s_create_hostdesc_queues(acx_device_t *adev); +void acxpci_create_desc_queues(acx_device_t *adev, u32 tx_queue_start, u32 rx_queue_start); +void acxpci_free_desc_queues(acx_device_t *adev); +char* acxpci_s_proc_diag_output(char *p, acx_device_t *adev); +int acxpci_proc_eeprom_output(char *p, acx_device_t *adev); +void acxpci_set_interrupt_mask(acx_device_t *adev); +int acx100pci_s_set_tx_level(acx_device_t *adev, u8 level_dbm); void acx_s_msleep(int ms); -int acx_s_init_mac(wlandevice_t *priv); -void acx_set_reg_domain(wlandevice_t *priv, unsigned char reg_dom_id); -void acx_set_timer(wlandevice_t *priv, int timeout_us); -void acx_update_capabilities(wlandevice_t *priv); -void acx_s_start(wlandevice_t *priv); - -void acx_s_initialize_rx_config(wlandevice_t *priv); -void acx_s_update_card_settings(wlandevice_t *priv); -void acx_read_configoption(wlandevice_t *priv); -void acx_l_update_ratevector(wlandevice_t *priv); - -void acx_init_task_scheduler(wlandevice_t *priv); -void acx_schedule_task(wlandevice_t *priv, unsigned int set_flag); +int acx_s_init_mac(acx_device_t *adev); +void acx_set_reg_domain(acx_device_t *adev, unsigned char reg_dom_id); +void acx_set_timer(acx_device_t *adev, int timeout_us); +void acx_update_capabilities(acx_device_t *adev); +void acx_s_start(acx_device_t *adev); -int acx_e_ioctl_old(netdevice_t *dev, struct ifreq *ifr, int cmd); +void acx_s_update_card_settings(acx_device_t *adev); +void acx_s_parse_configoption(acx_device_t *adev, const acx111_ie_configoption_t *pcfg); +void acx_l_update_ratevector(acx_device_t *adev); -client_t *acx_l_sta_list_get(wlandevice_t *priv, const u8 *address); -void acx_l_sta_list_del(wlandevice_t *priv, client_t *clt); +void acx_init_task_scheduler(acx_device_t *adev); +void acx_schedule_task(acx_device_t *adev, unsigned int set_flag); -int acx_l_transmit_disassoc(wlandevice_t *priv, client_t *clt); +int acx_e_ioctl_old(struct net_device *ndev, struct ifreq *ifr, int cmd); + +client_t *acx_l_sta_list_get(acx_device_t *adev, const u8 *address); +void acx_l_sta_list_del(acx_device_t *adev, client_t *clt); + +int acx_l_transmit_disassoc(acx_device_t *adev, client_t *clt); void acx_i_timer(unsigned long a); -int acx_s_complete_scan(wlandevice_t *priv); +int acx_s_complete_scan(acx_device_t *adev); -struct sk_buff *acx_rxbuf_to_ether(struct wlandevice *priv, rxbuffer_t *rxbuf); -int acx_ether_to_txbuf(wlandevice_t *priv, void *txbuf, const struct sk_buff *skb); +struct sk_buff *acx_rxbuf_to_ether(acx_device_t *adev, rxbuffer_t *rxbuf); +int acx_ether_to_txbuf(acx_device_t *adev, void *txbuf, const struct sk_buff *skb); u8 acx_signal_determine_quality(u8 signal, u8 noise); -void acx_l_process_rxbuf(wlandevice_t *priv, rxbuffer_t *rxbuf); -void acx_l_handle_txrate_auto(wlandevice_t *priv, struct client *txc, +void acx_l_process_rxbuf(acx_device_t *adev, rxbuffer_t *rxbuf); +void acx_l_handle_txrate_auto(acx_device_t *adev, struct client *txc, u16 intended_rate, u8 rate100, u16 rate111, u8 error, int pkts_to_ignore); @@ -631,7 +618,7 @@ void acx_log_bad_eid(wlan_hdr_t* hdr, in u8 acx_rate111to100(u16); -void acx_s_set_defaults(wlandevice_t *priv); +void acx_s_set_defaults(acx_device_t *adev); #if !ACX_DEBUG static inline const char* acx_get_packet_type_string(u16 fc) { return ""; } @@ -640,20 +627,16 @@ const char* acx_get_packet_type_string(u #endif const char* acx_cmd_status_str(unsigned int state); -int acx_i_start_xmit(struct sk_buff *skb, netdevice_t *dev); - -int acx100_s_init_wep(wlandevice_t *priv); -int acx100_s_init_packet_templates(wlandevice_t *priv); -int acx111_s_init_packet_templates(wlandevice_t *priv); +int acx_i_start_xmit(struct sk_buff *skb, struct net_device *ndev); -void great_inquisitor(wlandevice_t *priv); +void great_inquisitor(acx_device_t *adev); -void acx_s_get_firmware_version(wlandevice_t *priv); -void acx_display_hardware_details(wlandevice_t *priv); +void acx_s_get_firmware_version(acx_device_t *adev); +void acx_display_hardware_details(acx_device_t *adev); -int acx_e_change_mtu(struct net_device *dev, int mtu); -struct net_device_stats* acx_e_get_stats(netdevice_t *dev); -struct iw_statistics* acx_e_get_wireless_stats(netdevice_t *dev); +int acx_e_change_mtu(struct net_device *ndev, int mtu); +struct net_device_stats* acx_e_get_stats(struct net_device *ndev); +struct iw_statistics* acx_e_get_wireless_stats(struct net_device *ndev); int __init acxpci_e_init_module(void); int __init acxusb_e_init_module(void); diff -puN drivers/net/wireless/tiacx/acx_struct.h~update-mm-acx-driver-to-version-0331 drivers/net/wireless/tiacx/acx_struct.h --- devel/drivers/net/wireless/tiacx/acx_struct.h~update-mm-acx-driver-to-version-0331 2006-01-31 18:11:09.000000000 -0800 +++ devel-akpm/drivers/net/wireless/tiacx/acx_struct.h 2006-01-31 18:11:09.000000000 -0800 @@ -34,7 +34,7 @@ ** Forward declarations of types */ typedef struct tx tx_t; -typedef struct wlandevice wlandevice_t; +typedef struct acx_device acx_device_t; typedef struct client client_t; typedef struct rxdesc rxdesc_t; typedef struct txdesc txdesc_t; @@ -81,28 +81,12 @@ enum { acx_debug = 0 }; /* Use worker_queues for 2.5/2.6 kernels and queue tasks for 2.4 kernels (used for the 'bottom half' of the interrupt routine) */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,41) #include -/* #define NEWER_KERNELS_ONLY 1 */ #define USE_WORKER_TASKS #define WORK_STRUCT struct work_struct #define SCHEDULE_WORK schedule_work #define FLUSH_SCHEDULED_WORK flush_scheduled_work -#else -#include -#define USE_QUEUE_TASKS -#define WORK_STRUCT struct tq_struct -#define SCHEDULE_WORK schedule_task -#define INIT_WORK(work, func, ndev) \ - do { \ - (work)->routine = (func); \ - (work)->data = (ndev); \ - } while (0) -#define FLUSH_SCHEDULED_WORK flush_scheduled_tasks - -#endif - /*********************************************************************** ** Constants @@ -114,31 +98,35 @@ enum { acx_debug = 0 }; #define CHIPTYPE_ACX100 1 #define CHIPTYPE_ACX111 2 -#define IS_ACX100(priv) ((priv)->chip_type == CHIPTYPE_ACX100) -#define IS_ACX111(priv) ((priv)->chip_type == CHIPTYPE_ACX111) +#define IS_ACX100(adev) ((adev)->chip_type == CHIPTYPE_ACX100) +#define IS_ACX111(adev) ((adev)->chip_type == CHIPTYPE_ACX111) /* Supported interfaces */ #define DEVTYPE_PCI 0 #define DEVTYPE_USB 1 +#if !defined(CONFIG_ACX_PCI) && !defined(CONFIG_ACX_USB) +#error Driver must include PCI and/or USB support. You selected neither. +#endif + #if defined(CONFIG_ACX_PCI) #if !defined(CONFIG_ACX_USB) - #define IS_PCI(priv) 1 + #define IS_PCI(adev) 1 #else - #define IS_PCI(priv) ((priv)->dev_type == DEVTYPE_PCI) + #define IS_PCI(adev) ((adev)->dev_type == DEVTYPE_PCI) #endif #else - #define IS_PCI(priv) 0 + #define IS_PCI(adev) 0 #endif #if defined(CONFIG_ACX_USB) #if !defined(CONFIG_ACX_PCI) - #define IS_USB(priv) 1 + #define IS_USB(adev) 1 #else - #define IS_USB(priv) ((priv)->dev_type == DEVTYPE_USB) + #define IS_USB(adev) ((adev)->dev_type == DEVTYPE_USB) #endif #else - #define IS_USB(priv) 0 + #define IS_USB(adev) 0 #endif /* Driver defaults */ @@ -258,6 +246,9 @@ DEF_IE(1xx_IE_SCAN_STATUS ,0x0009, 0x04 DEF_IE(1xx_IE_ASSOC_ID ,0x000a, 0x02); DEF_IE(1xx_IE_UNKNOWN_0B ,0x000b, -1); /* mapped to cfgInvalid in FW150 */ DEF_IE(100_IE_UNKNOWN_0C ,0x000c, -1); /* very small implementation in FW150! */ +/* ACX100 has an equivalent struct in the cmd mailbox directly after reset. + * 0x14c seems extremely large, will trash stack on failure (memset!) + * in case of small input struct --> OOPS! */ DEF_IE(111_IE_CONFIG_OPTIONS ,0x000c, 0x14c); DEF_IE(1xx_IE_FWREV ,0x000d, 0x18); DEF_IE(1xx_IE_FCS_ERROR_COUNT ,0x000e, 0x04); @@ -492,15 +483,15 @@ typedef struct phy_hdr { * Some seem to have different meanings... */ #define RXBUF_HDRSIZE 12 -#define PHY_HDR(rxbuf) ((phy_hdr_t*)&rxbuf->hdr_a3) -#define RXBUF_BYTES_RCVD(rxbuf) (le16_to_cpu(rxbuf->mac_cnt_rcvd) & 0xfff) +#define RXBUF_BYTES_RCVD(adev, rxbuf) \ + ((le16_to_cpu((rxbuf)->mac_cnt_rcvd) & 0xfff) - (adev)->phy_header_len) #define RXBUF_BYTES_USED(rxbuf) \ - ((le16_to_cpu(rxbuf->mac_cnt_rcvd) & 0xfff) + RXBUF_HDRSIZE) + ((le16_to_cpu((rxbuf)->mac_cnt_rcvd) & 0xfff) + RXBUF_HDRSIZE) /* USBism */ -#define RXBUF_IS_TXSTAT(rxbuf) (le16_to_cpu(rxbuf->mac_cnt_rcvd) & 0x8000) +#define RXBUF_IS_TXSTAT(rxbuf) (le16_to_cpu((rxbuf)->mac_cnt_rcvd) & 0x8000) /* mac_cnt_rcvd: - 12 bits: length of frame from control field to last byte of FCS + 12 bits: length of frame from control field to first byte of FCS 3 bits: reserved 1 bit: 1 = it's a tx status info, not a rx packet (USB only) @@ -642,7 +633,7 @@ typedef struct key_struct { /*--- Client (peer) info -----------------------------------------------------*/ -/* priv->sta_list[] is used for: +/* adev->sta_list[] is used for: ** accumulating and processing of scan results ** keeping client info in AP mode ** keeping AP info in STA mode (AP is the only one 'client') @@ -656,6 +647,8 @@ enum { CLIENT_JOIN_CANDIDATE = 4 }; struct client { + /* most frequent access first */ + u8 used; /* misnamed, more like 'status' */ struct client* next; unsigned long mtime; /* last time we heard it, in jiffies */ size_t essid_len; /* length of ESSID (without '\0') */ @@ -670,7 +663,6 @@ struct client { u16 rate_cfg; /* what is allowed (by iwconfig etc) */ u16 rate_cur; /* currently used rate mask */ u8 rate_100; /* currently used rate byte (acx100 only) */ - u8 used; /* misnamed, more like 'status' */ u8 address[ETH_ALEN]; u8 bssid[ETH_ALEN]; /* ad-hoc hosts can have bssid != mac */ u8 channel; @@ -994,7 +986,7 @@ typedef struct usb_txstatus { typedef struct usb_tx { unsigned busy:1; struct urb *urb; - wlandevice_t *priv; + acx_device_t *adev; /* actual USB bulk output data block is here: */ usb_txbuffer_t bulkout; } usb_tx_t; @@ -1002,14 +994,14 @@ typedef struct usb_tx { struct usb_rx_plain { unsigned busy:1; struct urb *urb; - wlandevice_t *priv; + acx_device_t *adev; rxbuffer_t bulkin; }; typedef struct usb_rx { unsigned busy:1; struct urb *urb; - wlandevice_t *priv; + acx_device_t *adev; rxbuffer_t bulkin; /* Make entire structure 4k. Report if it breaks something. */ u8 padding[4*1024 - sizeof(struct usb_rx_plain)]; @@ -1017,8 +1009,78 @@ typedef struct usb_rx { #endif /* ACX_USB */ +/* Config Option structs */ + +typedef struct co_antennas { + u8 type ACX_PACKED; + u8 len ACX_PACKED; + u8 list[2] ACX_PACKED; +} co_antennas_t; + +typedef struct co_powerlevels { + u8 type ACX_PACKED; + u8 len ACX_PACKED; + u16 list[8] ACX_PACKED; +} co_powerlevels_t; + +typedef struct co_datarates { + u8 type ACX_PACKED; + u8 len ACX_PACKED; + u8 list[8] ACX_PACKED; +} co_datarates_t; + +typedef struct co_domains { + u8 type ACX_PACKED; + u8 len ACX_PACKED; + u8 list[6] ACX_PACKED; +} co_domains_t; + +typedef struct co_product_id { + u8 type ACX_PACKED; + u8 len ACX_PACKED; + u8 list[128] ACX_PACKED; +} co_product_id_t; + +typedef struct co_manuf_id { + u8 type ACX_PACKED; + u8 len ACX_PACKED; + u8 list[128] ACX_PACKED; +} co_manuf_t; + +typedef struct co_fixed { + char NVSv[8] ACX_PACKED; +/* u16 NVS_vendor_offs; ACX111-only */ +/* u16 unknown; ACX111-only */ + u8 MAC[6] ACX_PACKED; /* ACX100-only */ + u16 probe_delay ACX_PACKED; /* ACX100-only */ + u32 eof_memory ACX_PACKED; + u8 dot11CCAModes ACX_PACKED; + u8 dot11Diversity ACX_PACKED; + u8 dot11ShortPreambleOption ACX_PACKED; + u8 dot11PBCCOption ACX_PACKED; + u8 dot11ChannelAgility ACX_PACKED; + u8 dot11PhyType ACX_PACKED; /* FIXME: does 802.11 call it "dot11PHYType"? */ + u8 dot11TempType ACX_PACKED; + u8 table_count ACX_PACKED; +} co_fixed_t; + +typedef struct acx111_ie_configoption { + u16 type ACX_PACKED; + u16 len ACX_PACKED; +/* Do not access below members directly, they are in fact variable length */ + co_fixed_t fixed ACX_PACKED; + co_antennas_t antennas ACX_PACKED; + co_powerlevels_t power_levels ACX_PACKED; + co_datarates_t data_rates ACX_PACKED; + co_domains_t domains ACX_PACKED; + co_product_id_t product_id ACX_PACKED; + co_manuf_t manufacturer ACX_PACKED; + u8 _padding[4]; +} acx111_ie_configoption_t; + + /*********************************************************************** -** Main acx per-device data structure (netdev_priv(dev)) +** Main acx per-device data structure */ #define ACX_STATE_FW_LOADED 0x01 #define ACX_STATE_IFACE_UP 0x02 @@ -1046,15 +1108,27 @@ typedef struct usb_rx { * acx_priv_t) */ /* non-firmware struct, no packing necessary */ -struct wlandevice { +struct acx_device { + /* most frequent accesses first (dereferencing and cache line!) */ + + /*** Locking ***/ + struct semaphore sem; + spinlock_t lock; +#if defined(PARANOID_LOCKING) /* Lock debugging */ + const char *last_sem; + const char *last_lock; + unsigned long sem_time; + unsigned long lock_time; +#endif + /*** Device chain ***/ - struct wlandevice *next; /* link for list of devices */ + struct acx_device *next; /* link for list of devices */ /*** Linux network device ***/ - struct net_device *netdev; /* pointer to linux netdevice */ + struct net_device *ndev; /* pointer to linux netdevice */ struct net_device *prev_nd; /* FIXME: We should not chain via our - * private struct wlandevice _and_ - * the struct net_device. */ + * private struct acx_device _and_ + * the struct net_device */ /*** Device statistics ***/ struct net_device_stats stats; /* net device statistics */ #ifdef WIRELESS_EXT @@ -1066,28 +1140,40 @@ struct wlandevice { /*** Management timer ***/ struct timer_list mgmt_timer; - /*** Locking ***/ - struct semaphore sem; - spinlock_t lock; -#if defined(PARANOID_LOCKING) /* Lock debugging */ - const char *last_sem; - const char *last_lock; - unsigned long sem_time; - unsigned long lock_time; -#endif - /*** Hardware identification ***/ - const char *chip_name; - u8 dev_type; - u8 chip_type; - u8 form_factor; - u8 radio_type; - u8 eeprom_version; + const char *chip_name; + u8 dev_type; + u8 chip_type; + u8 form_factor; + u8 radio_type; + u8 eeprom_version; + + /*** Config retrieved from EEPROM ***/ + char cfgopt_NVSv[8]; + u16 cfgopt_NVS_vendor_offs; + u8 cfgopt_MAC[6]; + u16 cfgopt_probe_delay; + u32 cfgopt_eof_memory; + u8 cfgopt_dot11CCAModes; + u8 cfgopt_dot11Diversity; + u8 cfgopt_dot11ShortPreambleOption; + u8 cfgopt_dot11PBCCOption; + u8 cfgopt_dot11ChannelAgility; + u8 cfgopt_dot11PhyType; + u8 cfgopt_dot11TempType; + co_antennas_t cfgopt_antennas; + co_powerlevels_t cfgopt_power_levels; + co_datarates_t cfgopt_data_rates; + co_domains_t cfgopt_domains; + co_product_id_t cfgopt_product_id; + co_manuf_t cfgopt_manufacturer; /*** Firmware identification ***/ char firmware_version[FW_ID_SIZE+1]; u32 firmware_numver; u32 firmware_id; + const u16 *ie_len; + const u16 *ie_len_dot11; /*** Device state ***/ u16 dev_state_mask; @@ -1120,6 +1206,7 @@ struct wlandevice { u8 ap[ETH_ALEN]; /* The AP we want, FF:FF:FF:FF:FF:FF is any */ u16 aid; /* The Association ID sent from the AP / last used AID if we're an AP */ u16 mode; /* mode from iwconfig */ + int monitor_type; /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_PRISM */ u16 status; /* 802.11 association status */ u8 essid_active; /* specific ESSID active, or select any? */ u8 essid_len; /* to avoid dozens of strlen() */ @@ -1143,9 +1230,9 @@ struct wlandevice { client_t *sta_hash_tab[64]; /* hash collisions are not likely */ client_t *ap_client; /* this one is our AP (STA mode only) */ - unsigned long dup_msg_expiry; int dup_count; int nondup_count; + unsigned long dup_msg_expiry; u16 last_seq_ctrl; /* duplicate packet detection */ /* 802.11 power save mode */ @@ -1153,7 +1240,8 @@ struct wlandevice { u8 ps_listen_interval; u8 ps_options; u8 ps_hangover_period; - u16 ps_enhanced_transition_time; + u32 ps_enhanced_transition_time; + u32 ps_beacon_rx_time; /*** PHY settings ***/ u8 fallback_threshold; @@ -1187,6 +1275,7 @@ struct wlandevice { u8 cca; /* clear channel assessment */ u16 rts_threshold; + u16 frag_threshold; u32 short_retry; u32 long_retry; u16 msdu_lifetime; @@ -1194,9 +1283,6 @@ struct wlandevice { u32 beacon_interval; u16 capabilities; - u8 capab_short; - u8 capab_pbcc; - u8 capab_agility; u8 rate_supported_len; u8 rate_supported[13]; @@ -1208,17 +1294,21 @@ struct wlandevice { wep_key_t wep_keys[DOT11_MAX_DEFAULT_WEP_KEYS]; /* the default WEP keys */ key_struct_t wep_key_struct[10]; + /*** Unknown ***/ + u8 dtim_interval; + /*** Card Rx/Tx management ***/ u16 rx_config_1; u16 rx_config_2; u16 memblocksize; - int tx_free; - int tx_head; - - /*** Unknown ***/ - u8 dtim_interval; + unsigned int tx_free; + unsigned int tx_head; /* keep as close as possible to Tx stuff below (cache line) */ + u16 phy_header_len; + +/************************************************************************* + *** PCI/USB/... must be last or else hw agnostic code breaks horribly *** + *************************************************************************/ -/*** PCI/USB/... must be last or else hw agnostic code breaks horribly ***/ /* hack to let common code compile. FIXME */ dma_addr_t rxhostdesc_startphy; @@ -1226,35 +1316,35 @@ struct wlandevice { #ifdef ACX_PCI /* pointers to tx buffers, tx host descriptors (in host memory) ** and tx descs in device memory */ + unsigned int tx_tail; u8 *txbuf_start; txhostdesc_t *txhostdesc_start; txdesc_t *txdesc_start; /* points to PCI-mapped memory */ - /* same for rx */ - rxbuffer_t *rxbuf_start; - rxhostdesc_t *rxhostdesc_start; - rxdesc_t *rxdesc_start; - /* physical addresses of above host memory areas */ - dma_addr_t rxbuf_startphy; - /* dma_addr_t rxhostdesc_startphy; */ dma_addr_t txbuf_startphy; dma_addr_t txhostdesc_startphy; /* sizes of above host memory areas */ unsigned int txbuf_area_size; unsigned int txhostdesc_area_size; - unsigned int rxbuf_area_size; - unsigned int rxhostdesc_area_size; unsigned int txdesc_size; /* size of txdesc; ACX111 = ACX100 + 4 */ - unsigned int tx_tail; - unsigned int rx_tail; - client_t *txc[TX_CNT]; u16 txr[TX_CNT]; + /* same for rx */ + unsigned int rx_tail; + rxbuffer_t *rxbuf_start; + rxhostdesc_t *rxhostdesc_start; + rxdesc_t *rxdesc_start; + /* physical addresses of above host memory areas */ + dma_addr_t rxbuf_startphy; + /* dma_addr_t rxhostdesc_startphy; */ + unsigned int rxbuf_area_size; + unsigned int rxhostdesc_area_size; + u8 need_radio_fw; u8 irqs_active; /* whether irq sending is activated */ - const u16 *io; /* points to ACX100 or ACX111 I/O register address set */ + const u16 *io; /* points to ACX100 or ACX111 PCI I/O register address set */ struct pci_dev *pdev; @@ -1266,11 +1356,6 @@ struct wlandevice { u8 __iomem *cmd_area; u8 __iomem *info_area; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10) - /* 2.6.9-rc3-mm2 (2.6.9-bk4, too) introduced a shorter API version, - then it made its way into 2.6.10 */ - u32 pci_state[16]; /* saved PCI state for suspend/resume */ -#endif u16 irq_mask; /* interrupt types to mask out (not wanted) with many IRQs activated */ u16 irq_mask_off; /* interrupt types to mask out (not wanted) with IRQs off */ unsigned int irq_loops_this_jiffy; @@ -1293,6 +1378,13 @@ struct wlandevice { }; +static inline acx_device_t* +ndev2adev(struct net_device *ndev) +{ + return netdev_priv(ndev); +} + + /* For use with ACX1xx_IE_RXCONFIG */ /* bit description * 13 include additional header (length etc.) *required* @@ -1413,23 +1505,8 @@ struct wlandevice { /*********************************************************************** ** Firmware loading */ -/* Doh, 2.4.x also has CONFIG_FW_LOADER_MODULE - * (but doesn't have the new device model yet which we require!) - * FIXME: exact version that introduced new device handling? */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) -#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) -#define USE_FW_LOADER_26 1 -#define USE_FW_LOADER_LEGACY 0 -#else -#define USE_FW_LOADER_26 0 -#define USE_FW_LOADER_LEGACY 1 -#endif -#endif - -#if USE_FW_LOADER_26 #include /* request_firmware() */ #include /* struct pci_device */ -#endif /*********************************************************************** @@ -1549,28 +1626,29 @@ typedef struct acx111_ie_tx_level { /* Enhanced PS mode: sleep until Rx Beacon w/ the STA's AID bit set ** in the TIM; newer firmwares only(?) */ #define PS_OPT_ENA_ENHANCED_PS 0x04 +#define PS_OPT_TX_PSPOLL 0x02 /* send PSPoll frame to fetch waiting frames from AP (on frame with matching AID) */ #define PS_OPT_STILL_RCV_BCASTS 0x01 -typedef struct acx100_ie_powermgmt { - u32 type ACX_PACKED; - u32 len ACX_PACKED; +typedef struct acx100_ie_powersave { + u16 type ACX_PACKED; + u16 len ACX_PACKED; u8 wakeup_cfg ACX_PACKED; u8 listen_interval ACX_PACKED; /* for EACH_ITVL: wake up every "beacon units" interval */ u8 options ACX_PACKED; u8 hangover_period ACX_PACKED; /* remaining wake time after Tx MPDU w/ PS bit, in values of 1/1024 seconds */ u16 enhanced_ps_transition_time ACX_PACKED; /* rem. wake time for Enh. PS */ -} acx100_ie_powermgmt_t; +} acx100_ie_powersave_t; -typedef struct acx111_ie_powermgmt { - u32 type ACX_PACKED; - u32 len ACX_PACKED; +typedef struct acx111_ie_powersave { + u16 type ACX_PACKED; + u16 len ACX_PACKED; u8 wakeup_cfg ACX_PACKED; u8 listen_interval ACX_PACKED; /* for EACH_ITVL: wake up every "beacon units" interval */ u8 options ACX_PACKED; u8 hangover_period ACX_PACKED; /* remaining wake time after Tx MPDU w/ PS bit, in values of 1/1024 seconds */ - u32 beaconRxTime ACX_PACKED; + u32 beacon_rx_time ACX_PACKED; u32 enhanced_ps_transition_time ACX_PACKED; /* rem. wake time for Enh. PS */ -} acx111_ie_powermgmt_t; +} acx111_ie_powersave_t; /*********************************************************************** @@ -1806,12 +1884,12 @@ typedef struct ie_dot11WEPDefaultKey { u8 action ACX_PACKED; u8 keySize ACX_PACKED; u8 defaultKeyNum ACX_PACKED; - u8 key[29] ACX_PACKED; /* check this! was Key[19]. */ + u8 key[29] ACX_PACKED; /* check this! was Key[19] */ } ie_dot11WEPDefaultKey_t; typedef struct acx111WEPDefaultKey { u8 MacAddr[ETH_ALEN] ACX_PACKED; - u16 action ACX_PACKED; /* NOTE: this is a u16, NOT a u8!! */ + u16 action ACX_PACKED; /* NOTE: this is a u16, NOT a u8!! */ u16 reserved ACX_PACKED; u8 keySize ACX_PACKED; u8 type ACX_PACKED; @@ -1834,9 +1912,11 @@ typedef struct acx100_cmd_wep_mgmt { u8 Key[29] ACX_PACKED; /* 29*8 == 232bits == WEP256 */ } acx100_cmd_wep_mgmt_t; +/* UNUSED? typedef struct defaultkey { u8 num; } defaultkey_t; +*/ typedef struct acx_ie_generic { u16 type ACX_PACKED; @@ -1851,73 +1931,6 @@ typedef struct acx_ie_generic { } m ACX_PACKED; } acx_ie_generic_t; -/* Config Option structs */ - -typedef struct co_antennas { - u8 type ACX_PACKED; - u8 len ACX_PACKED; - u8 list[2] ACX_PACKED; -} co_antennas_t; - -typedef struct co_powerlevels { - u8 type ACX_PACKED; - u8 len ACX_PACKED; - u16 list[8] ACX_PACKED; -} co_powerlevels_t; - -typedef struct co_datarates { - u8 type ACX_PACKED; - u8 len ACX_PACKED; - u8 list[8] ACX_PACKED; -} co_datarates_t; - -typedef struct co_domains { - u8 type ACX_PACKED; - u8 len ACX_PACKED; - u8 list[6] ACX_PACKED; -} co_domains_t; - -typedef struct co_product_id { - u8 type ACX_PACKED; - u8 len ACX_PACKED; - u8 list[128] ACX_PACKED; -} co_product_id_t; - -typedef struct co_manuf_id { - u8 type ACX_PACKED; - u8 len ACX_PACKED; - u8 list[128] ACX_PACKED; -} co_manuf_t; - -typedef struct co_fixed { - u8 type ACX_PACKED; - u8 len ACX_PACKED; - char NVSv[8] ACX_PACKED; - u8 MAC[6] ACX_PACKED; - u16 probe_delay ACX_PACKED; - u32 eof_memory ACX_PACKED; - u8 dot11CCAModes ACX_PACKED; - u8 dot11Diversity ACX_PACKED; - u8 dot11ShortPreambleOption ACX_PACKED; - u8 dot11PBCCOption ACX_PACKED; - u8 dot11ChannelAgility ACX_PACKED; - u8 dot11PhyType ACX_PACKED; -/* u8 dot11TempType ACX_PACKED; - u8 num_var ACX_PACKED; seems to be erased */ -} co_fixed_t; - - -typedef struct acx111_ie_configoption { - co_fixed_t configoption_fixed ACX_PACKED; - co_antennas_t antennas ACX_PACKED; - co_powerlevels_t power_levels ACX_PACKED; - co_datarates_t data_rates ACX_PACKED; - co_domains_t domains ACX_PACKED; - co_product_id_t product_id ACX_PACKED; - co_manuf_t manufacturer ACX_PACKED; -} acx111_ie_configoption_t; - - /*********************************************************************** */ #define CHECK_SIZEOF(type,size) { \ @@ -1932,6 +1945,8 @@ acx_struct_size_check(void) CHECK_SIZEOF(acx100_ie_memconfigoption_t, 24); CHECK_SIZEOF(acx100_ie_queueconfig_t, 0x20); CHECK_SIZEOF(acx_joinbss_t, 0x30); + /* IEs need 4 bytes for (type,len) tuple */ + CHECK_SIZEOF(acx111_ie_configoption_t, ACX111_IE_CONFIG_OPTIONS_LEN + 4); } @@ -1942,6 +1957,9 @@ extern const u8 acx_bitpos2ratebyte[]; extern const u8 acx_bitpos2rate100[]; extern const u8 acx_reg_domain_ids[]; -extern const u8 acx_reg_domain_ids_len; +extern const char * const acx_reg_domain_strings[]; +enum { + acx_reg_domain_ids_len = 8 +}; extern const struct iw_handler_def acx_ioctl_handler_def; diff -puN drivers/net/wireless/tiacx/Changelog~update-mm-acx-driver-to-version-0331 drivers/net/wireless/tiacx/Changelog --- devel/drivers/net/wireless/tiacx/Changelog~update-mm-acx-driver-to-version-0331 2006-01-31 18:11:09.000000000 -0800 +++ devel-akpm/drivers/net/wireless/tiacx/Changelog 2006-01-31 18:11:09.000000000 -0800 @@ -104,6 +104,103 @@ TODO: from Efthym : 13:14:13 wlan0: tx error 0x20, buf 07! 13:14:13 wlan0: tx error 0x20, buf 08! +[20060126] 0.3.31 +* fix bug uncovered by code added in support for firmware 2.3.1.31 + +[20060124] 0.3.30 +* fix breakage introduced by vda +* Bas Vermeulen : + support for firmware 2.3.1.31 + +[20060117] 0.3.29 +* Andreas Mohr : + - fix OOPS in acx_l_rxmonitor() (wrong ndev->type setting leading to memcpy + of negative size) by reworking monitor mode type setup and adding + missing sanity checks + - rename acx1XX_ie_powermgmt_t to more correct acx1XX_ie_powersave_t + - fix format string compile warnings + - add include apparently required for __iomem define + around Linux 2.6.8 + - rework eCPU init by replacing static msleep with faster, more intelligent + (hopefully) busy-wait +* acx_s_set_defaults slightly edited +* ioctls are changed to have correct prototypes + +[20060116] 0.3.28 +* Massive global replaces: priv->adev, netdev_priv->ndev2adev etc. + Minimal code changes + +[20060113] +* Andreas Mohr : + - add recommended cpu_relax() to busy-wait loops + - reorder struct wlandevice_t for better(??) cache use + - kill superfluous result variable in conv.c + - misc. small cleanup +* SEPARATE_DRIVER_INSTANCES is a 2.4ism, removed + +[20060112] 0.3.27 +* Andreas Mohr : + - add support for configopt parsing for ACX100 EEPROM version v5 + - only start another radio recalibration interval every 5 seconds + on ACX111 instead of every second + +[20060111] +* drop compatibility cruft for kernels < 2.6.10 + +[20060109] 0.3.26 +* From Andreas Mohr + - revert kzalloc change (too early, only Linux 2.6.14+ has support) + - add safe limit checks for probe_delay EEPROM values, log more + configopt values + - some early parts for packet fragmentation support + (I already know how to do it, I think, I just need some time + to implement it, and I *really* need this feature here with such + a BROKEN 3-wall connection here...) + - 802.11 power save mode improvements (not usable by mere mortals yet) + - switch fw cmd length structs depending on whether acx100 or acx111 + - fix log message rate limiting (as a benefit code is now faster, too) + - unify acx100/acx111 scanning, saving a couple hundred bytes + - set Ctl2_8 to 0 which it most likely should be (please report if + this breaks anything - but it shouldn't since it's being initialized + to 0 on driver init anyway...) + +[20060108] 0.3.25 +* fix scanning breakage +* fix cmd timeout breakage +* attempt to fix suspend/resume + +[20060104] 0.3.24 +* From Andreas Mohr + - activated acx100 configoption readout, unified acx100/acx111 parsing + - init NULL data template, required for 802.11 power save mode + - return actual, valid txpower levels in range ioctl (from configoption!) + fix bugs: + - fatal bug in 802.11 powersave structs + - some missing endianness conversions + - check for sane regulatory domain related settings on both SETting and GETting + - random optimizations making this much enhanced code *smaller* than the + previous version! + - optimized struct layout + - merge acx100_s_init_packet_templates and acx111_s_init_packet_templates + - use kzalloc instead of kmalloc where useful (yes, this driver is Linux 2.6.x + only, with x rather large) + - avoid some sprintf() and strlen() + - add support for new get_wireless_stats handling (...silence deprecation + warning!) + - add some unlikely() + - lower msleep() value in issue_cmd() in order to speed up card initialization + time (almost less than 1 second now, on P3/700!). should this lower msleep() + value be made init-only?? + - disable get sensitivity ioctl for USB (unfortunately not working yet) + - make sure to call synchronize_irq(), (semi-)required for SMP + - group together some closely related functions + - misc cleanups/code maintenance + So, configoptions are now working for acx100, too, and unified, and + 802.11 power save mode actually worked for acx100 when I tested it (large + delays during ping which indicate that it must be active, but I guess these + delays should be much reduced with a properly tuned implementation), but it's + not finished and thus not enabled by default. + [20051228] * Global s/acxlog/log/ diff -puN drivers/net/wireless/tiacx/common.c~update-mm-acx-driver-to-version-0331 drivers/net/wireless/tiacx/common.c --- devel/drivers/net/wireless/tiacx/common.c~update-mm-acx-driver-to-version-0331 2006-01-31 18:11:09.000000000 -0800 +++ devel-akpm/drivers/net/wireless/tiacx/common.c 2006-01-31 18:11:09.000000000 -0800 @@ -46,88 +46,46 @@ #include #include #include -#if WIRELESS_EXT >= 13 #include -#endif /* WE >= 13 */ #include "acx.h" /*********************************************************************** */ -static client_t *acx_l_sta_list_alloc(wlandevice_t *priv); -static client_t *acx_l_sta_list_get_from_hash(wlandevice_t *priv, const u8 *address); +static client_t *acx_l_sta_list_alloc(acx_device_t *adev); +static client_t *acx_l_sta_list_get_from_hash(acx_device_t *adev, const u8 *address); -static int acx_l_process_data_frame_master(wlandevice_t *priv, rxbuffer_t *rxbuf); -static int acx_l_process_data_frame_client(wlandevice_t *priv, rxbuffer_t *rxbuf); -/* static int acx_l_process_NULL_frame(wlandevice_t *priv, rxbuffer_t *rxbuf, int vala); */ -static int acx_l_process_mgmt_frame(wlandevice_t *priv, rxbuffer_t *rxbuf); -static void acx_l_process_disassoc_from_sta(wlandevice_t *priv, const wlan_fr_disassoc_t *req); -static void acx_l_process_disassoc_from_ap(wlandevice_t *priv, const wlan_fr_disassoc_t *req); -static void acx_l_process_deauth_from_sta(wlandevice_t *priv, const wlan_fr_deauthen_t *req); -static void acx_l_process_deauth_from_ap(wlandevice_t *priv, const wlan_fr_deauthen_t *req); -static int acx_l_process_probe_response(wlandevice_t *priv, wlan_fr_proberesp_t *req, const rxbuffer_t *rxbuf); -static int acx_l_process_assocresp(wlandevice_t *priv, const wlan_fr_assocresp_t *req); -static int acx_l_process_reassocresp(wlandevice_t *priv, const wlan_fr_reassocresp_t *req); -static int acx_l_process_authen(wlandevice_t *priv, const wlan_fr_authen_t *req); -static int acx_l_transmit_assocresp(wlandevice_t *priv, const wlan_fr_assocreq_t *req); -static int acx_l_transmit_reassocresp(wlandevice_t *priv, const wlan_fr_reassocreq_t *req); -static int acx_l_transmit_deauthen(wlandevice_t *priv, const u8 *addr, u16 reason); -static int acx_l_transmit_authen1(wlandevice_t *priv); -static int acx_l_transmit_authen2(wlandevice_t *priv, const wlan_fr_authen_t *req, client_t *clt); -static int acx_l_transmit_authen3(wlandevice_t *priv, const wlan_fr_authen_t *req); -static int acx_l_transmit_authen4(wlandevice_t *priv, const wlan_fr_authen_t *req); -static int acx_l_transmit_assoc_req(wlandevice_t *priv); +static int acx_l_process_data_frame_master(acx_device_t *adev, rxbuffer_t *rxbuf); +static int acx_l_process_data_frame_client(acx_device_t *adev, rxbuffer_t *rxbuf); +/* static int acx_l_process_NULL_frame(acx_device_t *adev, rxbuffer_t *rxbuf, int vala); */ +static int acx_l_process_mgmt_frame(acx_device_t *adev, rxbuffer_t *rxbuf); +static void acx_l_process_disassoc_from_sta(acx_device_t *adev, const wlan_fr_disassoc_t *req); +static void acx_l_process_disassoc_from_ap(acx_device_t *adev, const wlan_fr_disassoc_t *req); +static void acx_l_process_deauth_from_sta(acx_device_t *adev, const wlan_fr_deauthen_t *req); +static void acx_l_process_deauth_from_ap(acx_device_t *adev, const wlan_fr_deauthen_t *req); +static int acx_l_process_probe_response(acx_device_t *adev, wlan_fr_proberesp_t *req, const rxbuffer_t *rxbuf); +static int acx_l_process_assocresp(acx_device_t *adev, const wlan_fr_assocresp_t *req); +static int acx_l_process_reassocresp(acx_device_t *adev, const wlan_fr_reassocresp_t *req); +static int acx_l_process_authen(acx_device_t *adev, const wlan_fr_authen_t *req); +static int acx_l_transmit_assocresp(acx_device_t *adev, const wlan_fr_assocreq_t *req); +static int acx_l_transmit_reassocresp(acx_device_t *adev, const wlan_fr_reassocreq_t *req); +static int acx_l_transmit_deauthen(acx_device_t *adev, const u8 *addr, u16 reason); +static int acx_l_transmit_authen1(acx_device_t *adev); +static int acx_l_transmit_authen2(acx_device_t *adev, const wlan_fr_authen_t *req, client_t *clt); +static int acx_l_transmit_authen3(acx_device_t *adev, const wlan_fr_authen_t *req); +static int acx_l_transmit_authen4(acx_device_t *adev, const wlan_fr_authen_t *req); +static int acx_l_transmit_assoc_req(acx_device_t *adev); /*********************************************************************** */ #if ACX_DEBUG -unsigned int acx_debug = L_ASSOC|L_INIT; -#endif -#if USE_FW_LOADER_LEGACY -static char *firmware_dir; -#endif -#if SEPARATE_DRIVER_INSTANCES -static int card; -#endif - -/* introduced earlier than 2.6.10, but takes more memory, so don't use it - * if there's no compile warning by kernel */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) - -#if ACX_DEBUG +unsigned int acx_debug /* will add __read_mostly later */ = ACX_DEFAULT_MSG; /* parameter is 'debug', corresponding var is acx_debug */ module_param_named(debug, acx_debug, uint, 0); -#endif -#if USE_FW_LOADER_LEGACY -module_param(firmware_dir, charp, 0); -#endif - -#else - -#if ACX_DEBUG -/* doh, 2.6.x screwed up big time: here the define has its own ";" - * ("double ; detected"), yet in 2.4.x it DOESN'T (the sane thing to do), - * grrrrr! */ -MODULE_PARM(acx_debug, "i"); -#endif -#if USE_FW_LOADER_LEGACY -MODULE_PARM(firmware_dir, "s"); -#endif - -#endif - -#if ACX_DEBUG MODULE_PARM_DESC(debug, "Debug level mask (see L_xxx constants)"); #endif -#if USE_FW_LOADER_LEGACY -MODULE_PARM_DESC(firmware_dir, "Directory to load acx100 firmware files from"); -#endif -#if SEPARATE_DRIVER_INSTANCES -MODULE_PARM(card, "i"); -MODULE_PARM_DESC(card, "Associate only with card-th acx100 card from this driver instance"); -#endif #ifdef MODULE_LICENSE MODULE_LICENSE("Dual MPL/GPL"); @@ -139,7 +97,7 @@ MODULE_DESCRIPTION("Driver for TI ACX1xx /*********************************************************************** */ -/* Probably a number of acx's itermediate buffers for USB transfers, +/* Probably a number of acx's intermediate buffers for USB transfers, ** not to be confused with number of descriptors in tx/rx rings ** (which are not directly accessible to host in USB devices) */ #define USB_RX_CNT 10 @@ -152,13 +110,25 @@ MODULE_DESCRIPTION("Driver for TI ACX1xx /* minutes to wait until next radio recalibration: */ #define RECALIB_PAUSE 5 -const u8 acx_reg_domain_ids[] = +/* Please keep acx_reg_domain_ids_len in sync... */ +const u8 acx_reg_domain_ids[acx_reg_domain_ids_len] = { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40, 0x41, 0x51 }; -/* stupid workaround for the fact that in C the size of an external array - * cannot be determined from within a second file */ -const u8 acx_reg_domain_ids_len = sizeof(acx_reg_domain_ids); -static const u16 reg_domain_channel_masks[] = +static const u16 reg_domain_channel_masks[acx_reg_domain_ids_len] = { 0x07ff, 0x07ff, 0x1fff, 0x0600, 0x1e00, 0x2000, 0x3fff, 0x01fc }; +const char * const +acx_reg_domain_strings[] = { + /* 0 */ " 1-11 FCC (USA)", + /* 1 */ " 1-11 DOC/IC (Canada)", +/* BTW: WLAN use in ETSI is regulated by ETSI standard EN 300 328-2 V1.1.2 */ + /* 2 */ " 1-13 ETSI (Europe)", + /* 3 */ "10-11 Spain", + /* 4 */ "10-13 France", + /* 5 */ " 14 MKK (Japan)", + /* 6 */ " 1-14 MKK1", + /* 7 */ " 3-9 Israel (not all firmware versions)", + NULL /* needs to remain as last entry */ +}; + /*********************************************************************** @@ -182,45 +152,45 @@ sanitize_str(const char *s) } void -acx_lock_debug(wlandevice_t *priv, const char* where) +acx_lock_debug(acx_device_t *adev, const char* where) { - int count = 100*1000*1000; + unsigned int count = 100*1000*1000; where = sanitize_str(where); while (--count) { - if (!spin_is_locked(&priv->lock)) break; + if (!spin_is_locked(&adev->lock)) break; cpu_relax(); } if (!count) { - printk(KERN_EMERG "LOCKUP: already taken at %s!\n", priv->last_lock); + printk(KERN_EMERG "LOCKUP: already taken at %s!\n", adev->last_lock); BUG(); } - priv->last_lock = where; - rdtscl(priv->lock_time); + adev->last_lock = where; + rdtscl(adev->lock_time); } void -acx_unlock_debug(wlandevice_t *priv, const char* where) +acx_unlock_debug(acx_device_t *adev, const char* where) { #ifdef SMP - if (!spin_is_locked(&priv->lock)) { + if (!spin_is_locked(&adev->lock)) { where = sanitize_str(where); printk(KERN_EMERG "STRAY UNLOCK at %s!\n", where); BUG(); } #endif if (acx_debug & L_LOCK) { - unsigned diff; + unsigned long diff; rdtscl(diff); - diff -= priv->lock_time; + diff -= adev->lock_time; if (diff > max_lock_time) { where = sanitize_str(where); - printk("max lock hold time %d CPU ticks from %s " - "to %s\n", diff, priv->last_lock, where); + printk("max lock hold time %ld CPU ticks from %s " + "to %s\n", diff, adev->last_lock, where); max_lock_time = diff; } } } void -acx_down_debug(wlandevice_t *priv, const char* where) +acx_down_debug(acx_device_t *adev, const char* where) { int sem_count; unsigned long timeout = jiffies + 5*HZ; @@ -228,7 +198,7 @@ acx_down_debug(wlandevice_t *priv, const where = sanitize_str(where); for (;;) { - sem_count = atomic_read(&priv->sem.count); + sem_count = atomic_read(&adev->sem.count); if (sem_count) break; if (time_after(jiffies, timeout)) break; @@ -236,40 +206,40 @@ acx_down_debug(wlandevice_t *priv, const } if (!sem_count) { printk(KERN_EMERG "D STATE at %s! last sem at %s\n", - where, priv->last_sem); + where, adev->last_sem); dump_stack(); } - priv->last_sem = where; - priv->sem_time = jiffies; - down(&priv->sem); + adev->last_sem = where; + adev->sem_time = jiffies; + down(&adev->sem); if (acx_debug & L_LOCK) { printk("%s: sem_down %d -> %d\n", - where, sem_count, atomic_read(&priv->sem.count)); + where, sem_count, atomic_read(&adev->sem.count)); } } void -acx_up_debug(wlandevice_t *priv, const char* where) +acx_up_debug(acx_device_t *adev, const char* where) { - int sem_count = atomic_read(&priv->sem.count); + int sem_count = atomic_read(&adev->sem.count); if (sem_count) { where = sanitize_str(where); printk(KERN_EMERG "STRAY UP at %s! sem.count=%d\n", where, sem_count); dump_stack(); } if (acx_debug & L_LOCK) { - unsigned diff = jiffies - priv->sem_time; + unsigned long diff = jiffies - adev->sem_time; if (diff > max_sem_time) { where = sanitize_str(where); - printk("max sem hold time %d jiffies from %s " - "to %s\n", diff, priv->last_sem, where); + printk("max sem hold time %ld jiffies from %s " + "to %s\n", diff, adev->last_sem, where); max_sem_time = diff; } } - up(&priv->sem); + up(&adev->sem); if (acx_debug & L_LOCK) { where = sanitize_str(where); printk("%s: sem_up %d -> %d\n", - where, sem_count, atomic_read(&priv->sem.count)); + where, sem_count, atomic_read(&adev->sem.count)); } } #endif /* PARANOID_LOCKING */ @@ -382,7 +352,7 @@ acx_get_status_name(u16 status) "STOPPED", "SCANNING", "WAIT_AUTH", "AUTHENTICATED", "ASSOCIATED", "INVALID??" }; - if (status >= VEC_SIZE(str)) + if (status > VEC_SIZE(str)-1) status = VEC_SIZE(str)-1; return str[status]; @@ -411,26 +381,32 @@ acx_get_packet_type_string(u16 fc) "DATA/Data CFAck/CFPoll", "DATA/Null", "DATA/CFAck", "DATA/CFPoll", "DATA/CFAck/CFPoll" }; - const char *str = "UNKNOWN"; + const char *str; u8 fstype = (WF_FC_FSTYPE & fc) >> 4; u8 ctl; switch (WF_FC_FTYPE & fc) { case WF_FTYPE_MGMT: - str = "MGMT/UNKNOWN"; if (fstype < VEC_SIZE(mgmt_arr)) str = mgmt_arr[fstype]; + else + str = "MGMT/UNKNOWN"; break; case WF_FTYPE_CTL: ctl = fstype - 0x0a; - str = "CTL/UNKNOWN"; if (ctl < VEC_SIZE(ctl_arr)) str = ctl_arr[ctl]; + else + str = "CTL/UNKNOWN"; break; case WF_FTYPE_DATA: - str = "DATA/UNKNOWN"; if (fstype < VEC_SIZE(data_arr)) str = data_arr[fstype]; + else + str = "DATA/UNKNOWN"; + break; + default: + str = "UNKNOWN"; break; } return str; @@ -441,7 +417,7 @@ acx_get_packet_type_string(u16 fc) /*********************************************************************** ** acx_wlan_reason_str */ -static const char* +static inline const char* acx_wlan_reason_str(u16 reason) { static const char* const reason_str[] = { @@ -508,7 +484,7 @@ acx_cmd_status_str(unsigned int state) /*********************************************************************** ** get_status_string */ -static const char* +static inline const char* get_status_string(unsigned int status) { /* A bit shortened, but hopefully still understandable */ @@ -602,7 +578,7 @@ acx_dump_bytes(const void *data, int num ** acx_s_get_firmware_version */ void -acx_s_get_firmware_version(wlandevice_t *priv) +acx_s_get_firmware_version(acx_device_t *adev) { fw_ver_t fw; u8 hexarr[4] = { 0, 0, 0, 0 }; @@ -613,17 +589,17 @@ acx_s_get_firmware_version(wlandevice_t FN_ENTER; memset(fw.fw_id, 'E', FW_ID_SIZE); - acx_s_interrogate(priv, &fw, ACX1xx_IE_FWREV); - memcpy(priv->firmware_version, fw.fw_id, FW_ID_SIZE); - priv->firmware_version[FW_ID_SIZE] = '\0'; + acx_s_interrogate(adev, &fw, ACX1xx_IE_FWREV); + memcpy(adev->firmware_version, fw.fw_id, FW_ID_SIZE); + adev->firmware_version[FW_ID_SIZE] = '\0'; log(L_DEBUG, "fw_ver: fw_id='%s' hw_id=%08X\n", - priv->firmware_version, fw.hw_id); + adev->firmware_version, fw.hw_id); if (strncmp(fw.fw_id, "Rev ", 4) != 0) { printk("acx: strange firmware version string " - "'%s', please report\n", priv->firmware_version); - priv->firmware_numver = 0x01090407; /* assume 1.9.4.7 */ + "'%s', please report\n", adev->firmware_version); + adev->firmware_numver = 0x01090407; /* assume 1.9.4.7 */ } else { num = &fw.fw_id[4]; while (1) { @@ -642,44 +618,37 @@ acx_s_get_firmware_version(wlandevice_t val = val*16 + c; } - priv->firmware_numver = (u32)( + adev->firmware_numver = (u32)( (hexarr[0] << 24) + (hexarr[1] << 16) + (hexarr[2] << 8) + hexarr[3]); - log(L_DEBUG, "firmware_numver 0x%08X\n", priv->firmware_numver); + log(L_DEBUG, "firmware_numver 0x%08X\n", adev->firmware_numver); } - if (IS_ACX111(priv)) { - if (priv->firmware_numver == 0x00010011) { + if (IS_ACX111(adev)) { + if (adev->firmware_numver == 0x00010011) { /* This one does not survive floodpinging */ printk("acx: firmware '%s' is known to be buggy, " - "please upgrade\n", priv->firmware_version); - } - if (priv->firmware_numver == 0x02030131) { - /* With this one, all rx packets look mangled - ** Most probably we simply do not know how to use it - ** properly */ - printk("acx: firmware '%s' does not work well " - "with this driver\n", priv->firmware_version); + "please upgrade\n", adev->firmware_version); } } - priv->firmware_id = le32_to_cpu(fw.hw_id); + adev->firmware_id = le32_to_cpu(fw.hw_id); /* we're able to find out more detailed chip names now */ - switch (priv->firmware_id & 0xffff0000) { + switch (adev->firmware_id & 0xffff0000) { case 0x01010000: case 0x01020000: - priv->chip_name = "TNETW1100A"; + adev->chip_name = "TNETW1100A"; break; case 0x01030000: - priv->chip_name = "TNETW1100B"; + adev->chip_name = "TNETW1100B"; break; case 0x03000000: case 0x03010000: - priv->chip_name = "TNETW1130"; + adev->chip_name = "TNETW1130"; break; default: printk("acx: unknown chip ID 0x%08X, " - "please report\n", priv->firmware_id); + "please report\n", adev->firmware_id); break; } @@ -693,13 +662,13 @@ acx_s_get_firmware_version(wlandevice_t ** Displays hw/fw version, radio type etc... */ void -acx_display_hardware_details(wlandevice_t *priv) +acx_display_hardware_details(acx_device_t *adev) { const char *radio_str, *form_str; FN_ENTER; - switch (priv->radio_type) { + switch (adev->radio_type) { case RADIO_MAXIM_0D: /* hmm, the DWL-650+ seems to have two variants, * according to a windows driver changelog comment: @@ -728,7 +697,7 @@ acx_display_hardware_details(wlandevice_ break; } - switch (priv->form_factor) { + switch (adev->form_factor) { case 0x00: form_str = "unspecified"; break; @@ -749,9 +718,9 @@ acx_display_hardware_details(wlandevice_ printk("acx: form factor 0x%02X (%s), " "radio type 0x%02X (%s), EEPROM version 0x%02X, " "uploaded firmware '%s' (0x%08X)\n", - priv->form_factor, form_str, priv->radio_type, radio_str, - priv->eeprom_version, priv->firmware_version, - priv->firmware_id); + adev->form_factor, form_str, adev->radio_type, radio_str, + adev->eeprom_version, adev->firmware_version, + adev->firmware_id); FN_EXIT0; } @@ -760,7 +729,7 @@ acx_display_hardware_details(wlandevice_ /*********************************************************************** */ int -acx_e_change_mtu(struct net_device *dev, int mtu) +acx_e_change_mtu(struct net_device *ndev, int mtu) { enum { MIN_MTU = 256, @@ -770,7 +739,7 @@ acx_e_change_mtu(struct net_device *dev, if (mtu < MIN_MTU || mtu > MAX_MTU) return -EINVAL; - dev->mtu = mtu; + ndev->mtu = mtu; return 0; } @@ -779,17 +748,17 @@ acx_e_change_mtu(struct net_device *dev, ** acx_e_get_stats, acx_e_get_wireless_stats */ struct net_device_stats* -acx_e_get_stats(netdevice_t *dev) +acx_e_get_stats(struct net_device *ndev) { - wlandevice_t *priv = netdev_priv(dev); - return &priv->stats; + acx_device_t *adev = ndev2adev(ndev); + return &adev->stats; } struct iw_statistics* -acx_e_get_wireless_stats(netdevice_t *dev) +acx_e_get_wireless_stats(struct net_device *ndev) { - wlandevice_t *priv = netdev_priv(dev); - return &priv->wstats; + acx_device_t *adev = ndev2adev(ndev); + return &adev->wstats; } @@ -854,11 +823,66 @@ acx_signal_determine_quality(u8 signal, /*********************************************************************** ** Interrogate/configure commands */ + +/* FIXME: the lengths given here probably aren't always correct. + * They should be gradually replaced by proper "sizeof(acx1XX_ie_XXXX)-4", + * unless the firmware actually expects a different length than the struct length */ +static const u16 +acx100_ie_len[] = { + 0, + ACX100_IE_ACX_TIMER_LEN, + sizeof(acx100_ie_powersave_t)-4, /* is that 6 or 8??? */ + ACX1xx_IE_QUEUE_CONFIG_LEN, + ACX100_IE_BLOCK_SIZE_LEN, + ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN, + ACX1xx_IE_RATE_FALLBACK_LEN, + ACX100_IE_WEP_OPTIONS_LEN, + ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */ + 0, + ACX1xx_IE_ASSOC_ID_LEN, + 0, + ACX111_IE_CONFIG_OPTIONS_LEN, + ACX1xx_IE_FWREV_LEN, + ACX1xx_IE_FCS_ERROR_COUNT_LEN, + ACX1xx_IE_MEDIUM_USAGE_LEN, + ACX1xx_IE_RXCONFIG_LEN, + 0, + 0, + ACX1xx_IE_FIRMWARE_STATISTICS_LEN, + 0, + ACX1xx_IE_FEATURE_CONFIG_LEN, + ACX111_IE_KEY_CHOOSE_LEN, +}; + +static const u16 +acx100_ie_len_dot11[] = { + 0, + ACX1xx_IE_DOT11_STATION_ID_LEN, + 0, + ACX100_IE_DOT11_BEACON_PERIOD_LEN, + ACX1xx_IE_DOT11_DTIM_PERIOD_LEN, + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN, + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN, + ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN, + ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN, + 0, + ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN, + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN, + 0, + ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN, + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN, + ACX100_IE_DOT11_ED_THRESHOLD_LEN, + ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN, + 0, + 0, + 0, +}; + static const u16 -CtlLength[] = { +acx111_ie_len[] = { 0, ACX100_IE_ACX_TIMER_LEN, - ACX1xx_IE_POWER_MGMT_LEN, + sizeof(acx111_ie_powersave_t)-4, ACX1xx_IE_QUEUE_CONFIG_LEN, ACX100_IE_BLOCK_SIZE_LEN, ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN, @@ -882,7 +906,7 @@ CtlLength[] = { }; static const u16 -CtlLengthDot11[] = { +acx111_ie_len_dot11[] = { 0, ACX1xx_IE_DOT11_STATION_ID_LEN, 0, @@ -905,24 +929,25 @@ CtlLengthDot11[] = { 0, }; + #undef FUNC #define FUNC "configure" #if !ACX_DEBUG int -acx_s_configure(wlandevice_t *priv, void *pdr, int type) +acx_s_configure(acx_device_t *adev, void *pdr, int type) { #else int -acx_s_configure_debug(wlandevice_t *priv, void *pdr, int type, const char* typestr) +acx_s_configure_debug(acx_device_t *adev, void *pdr, int type, const char* typestr) { #endif u16 len; int res; if (type < 0x1000) - len = CtlLength[type]; + len = adev->ie_len[type]; else - len = CtlLengthDot11[type - 0x1000]; + len = adev->ie_len_dot11[type - 0x1000]; log(L_CTL, FUNC"(type:%s,len:%u)\n", typestr, len); if (unlikely(!len)) { @@ -931,12 +956,12 @@ acx_s_configure_debug(wlandevice_t *priv ((acx_ie_generic_t *)pdr)->type = cpu_to_le16(type); ((acx_ie_generic_t *)pdr)->len = cpu_to_le16(len); - res = acx_s_issue_cmd(priv, ACX1xx_CMD_CONFIGURE, pdr, len + 4); + res = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIGURE, pdr, len + 4); if (unlikely(OK != res)) { #if ACX_DEBUG - printk("%s: "FUNC"(type:%s) FAILED\n", priv->netdev->name, typestr); + printk("%s: "FUNC"(type:%s) FAILED\n", adev->ndev->name, typestr); #else - printk("%s: "FUNC"(type:0x%X) FAILED\n", priv->netdev->name, type); + printk("%s: "FUNC"(type:0x%X) FAILED\n", adev->ndev->name, type); #endif /* dump_stack() is already done in issue_cmd() */ } @@ -947,11 +972,11 @@ acx_s_configure_debug(wlandevice_t *priv #define FUNC "interrogate" #if !ACX_DEBUG int -acx_s_interrogate(wlandevice_t *priv, void *pdr, int type) +acx_s_interrogate(acx_device_t *adev, void *pdr, int type) { #else int -acx_s_interrogate_debug(wlandevice_t *priv, void *pdr, int type, +acx_s_interrogate_debug(acx_device_t *adev, void *pdr, int type, const char* typestr) { #endif @@ -959,19 +984,20 @@ acx_s_interrogate_debug(wlandevice_t *pr int res; if (type < 0x1000) - len = CtlLength[type]; + len = adev->ie_len[type]; else - len = CtlLengthDot11[type-0x1000]; + len = adev->ie_len_dot11[type-0x1000]; + log(L_CTL, FUNC"(type:%s,len:%u)\n", typestr, len); ((acx_ie_generic_t *)pdr)->type = cpu_to_le16(type); ((acx_ie_generic_t *)pdr)->len = cpu_to_le16(len); - res = acx_s_issue_cmd(priv, ACX1xx_CMD_INTERROGATE, pdr, len + 4); + res = acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, pdr, len + 4); if (unlikely(OK != res)) { #if ACX_DEBUG - printk("%s: "FUNC"(type:%s) FAILED\n", priv->netdev->name, typestr); + printk("%s: "FUNC"(type:%s) FAILED\n", adev->ndev->name, typestr); #else - printk("%s: "FUNC"(type:0x%X) FAILED\n", priv->netdev->name, type); + printk("%s: "FUNC"(type:0x%X) FAILED\n", adev->ndev->name, type); #endif /* dump_stack() is already done in issue_cmd() */ } @@ -980,7 +1006,7 @@ acx_s_interrogate_debug(wlandevice_t *pr #if CMD_DISCOVERY void -great_inquisitor(wlandevice_t *priv) +great_inquisitor(acx_device_t *adev) { static struct { u16 type ACX_PACKED; @@ -998,7 +1024,7 @@ great_inquisitor(wlandevice_t *priv) type = 0x1000; ie.type = cpu_to_le16(type); ie.len = cpu_to_le16(sizeof(ie) - 4); - acx_s_issue_cmd(priv, ACX1xx_CMD_INTERROGATE, &ie, sizeof(ie)); + acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, &ie, sizeof(ie)); } FN_EXIT0; } @@ -1015,14 +1041,14 @@ great_inquisitor(wlandevice_t *priv) ** ** Arguments: ** buf is a pointer to write output to -** priv is the usual pointer to our private struct wlandevice +** adev is the usual pointer to our private struct acx_device ** Returns: ** number of bytes actually written to buf ** Side effects: ** none */ static int -acx_l_proc_output(char *buf, wlandevice_t *priv) +acx_l_proc_output(char *buf, acx_device_t *adev) { char *p = buf; int i; @@ -1037,14 +1063,14 @@ acx_l_proc_output(char *buf, wlandevice_ "form factor:\t\t\t0x%02X\n" "EEPROM version:\t\t\t0x%02X\n" "firmware version:\t\t%s (0x%08X)\n", - priv->chip_name, priv->firmware_id, - priv->radio_type, - priv->form_factor, - priv->eeprom_version, - priv->firmware_version, priv->firmware_numver); + adev->chip_name, adev->firmware_id, + adev->radio_type, + adev->form_factor, + adev->eeprom_version, + adev->firmware_version, adev->firmware_numver); - for (i = 0; i < VEC_SIZE(priv->sta_list); i++) { - struct client *bss = &priv->sta_list[i]; + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + struct client *bss = &adev->sta_list[i]; if (!bss->used) continue; p += sprintf(p, "BSS %u BSSID "MACSTR" ESSID %s channel %u " "Cap 0x%X SIR %u SNR %u\n", @@ -1052,7 +1078,7 @@ acx_l_proc_output(char *buf, wlandevice_ bss->cap_info, bss->sir, bss->snr); } p += sprintf(p, "status:\t\t\t%u (%s)\n", - priv->status, acx_get_status_name(priv->status)); + adev->status, acx_get_status_name(adev->status)); FN_EXIT1(p - buf); return p - buf; @@ -1062,7 +1088,7 @@ acx_l_proc_output(char *buf, wlandevice_ /*********************************************************************** */ static int -acx_s_proc_diag_output(char *buf, wlandevice_t *priv) +acx_s_proc_diag_output(char *buf, acx_device_t *adev) { char *p = buf; fw_stats_t *fw_stats; @@ -1070,17 +1096,19 @@ acx_s_proc_diag_output(char *buf, wlande FN_ENTER; - fw_stats = kmalloc(sizeof(fw_stats_t), GFP_KERNEL); + /* TODO: may replace kmalloc/memset with kzalloc once + * Linux 2.6.14 is widespread */ + fw_stats = kmalloc(sizeof(*fw_stats), GFP_KERNEL); if (!fw_stats) { FN_EXIT1(0); return 0; } - memset(fw_stats, 0, sizeof(fw_stats_t)); + memset(fw_stats, 0, sizeof(*fw_stats)); - acx_lock(priv, flags); + acx_lock(adev, flags); - if (IS_PCI(priv)) - p = acxpci_s_proc_diag_output(p, priv); + if (IS_PCI(adev)) + p = acxpci_s_proc_diag_output(p, adev); p += sprintf(p, "\n" @@ -1089,36 +1117,38 @@ acx_s_proc_diag_output(char *buf, wlande "status %u (%s), " "mode %u, channel %u, " "reg_dom_id 0x%02X, reg_dom_chanmask 0x%04X, ", - priv->dev_state_mask, - priv->status, acx_get_status_name(priv->status), - priv->mode, priv->channel, - priv->reg_dom_id, priv->reg_dom_chanmask + adev->dev_state_mask, + adev->status, acx_get_status_name(adev->status), + adev->mode, adev->channel, + adev->reg_dom_id, adev->reg_dom_chanmask ); p += sprintf(p, "ESSID \"%s\", essid_active %d, essid_len %d, " "essid_for_assoc \"%s\", nick \"%s\"\n" "WEP ena %d, restricted %d, idx %d\n", - priv->essid, priv->essid_active, (int)priv->essid_len, - priv->essid_for_assoc, priv->nick, - priv->wep_enabled, priv->wep_restricted, - priv->wep_current_index); - p += sprintf(p, "dev_addr "MACSTR"\n", MAC(priv->dev_addr)); - p += sprintf(p, "bssid "MACSTR"\n", MAC(priv->bssid)); - p += sprintf(p, "ap_filter "MACSTR"\n", MAC(priv->ap)); + adev->essid, adev->essid_active, (int)adev->essid_len, + adev->essid_for_assoc, adev->nick, + adev->wep_enabled, adev->wep_restricted, + adev->wep_current_index); + p += sprintf(p, "dev_addr "MACSTR"\n", MAC(adev->dev_addr)); + p += sprintf(p, "bssid "MACSTR"\n", MAC(adev->bssid)); + p += sprintf(p, "ap_filter "MACSTR"\n", MAC(adev->ap)); p += sprintf(p, "\n" "** PHY status **\n" "tx_disabled %d, tx_level_dbm %d\n" /* "tx_level_val %d, tx_level_auto %d\n" */ "sensitivity %d, antenna 0x%02X, ed_threshold %d, cca %d, preamble_mode %d\n" - "rts_threshold %d, short_retry %d, long_retry %d, msdu_lifetime %d, listen_interval %d, beacon_interval %d\n", - priv->tx_disabled, priv->tx_level_dbm, /* priv->tx_level_val, priv->tx_level_auto, */ - priv->sensitivity, priv->antenna, priv->ed_threshold, priv->cca, priv->preamble_mode, - priv->rts_threshold, priv->short_retry, priv->long_retry, priv->msdu_lifetime, priv->listen_interval, priv->beacon_interval); + "rts_threshold %d, frag_threshold %d, short_retry %d, long_retry %d\n" + "msdu_lifetime %d, listen_interval %d, beacon_interval %d\n", + adev->tx_disabled, adev->tx_level_dbm, /* adev->tx_level_val, adev->tx_level_auto, */ + adev->sensitivity, adev->antenna, adev->ed_threshold, adev->cca, adev->preamble_mode, + adev->rts_threshold, adev->frag_threshold, adev->short_retry, adev->long_retry, + adev->msdu_lifetime, adev->listen_interval, adev->beacon_interval); - acx_unlock(priv, flags); + acx_unlock(adev, flags); - if (OK != acx_s_interrogate(priv, fw_stats, ACX1xx_IE_FIRMWARE_STATISTICS)) + if (OK != acx_s_interrogate(adev, fw_stats, ACX1xx_IE_FIRMWARE_STATISTICS)) p += sprintf(p, "\n" "** Firmware **\n" @@ -1133,7 +1163,7 @@ acx_s_proc_diag_output(char *buf, wlande "rx_dma_err %u, tx_dma_req %u, tx_dma_err %u, cmd_cplt %u, fiq %u\n" "rx_hdrs %u, rx_cmplt %u, rx_mem_overfl %u, rx_rdys %u, irqs %u\n" "acx_trans_procs %u, decrypt_done %u, dma_0_done %u, dma_1_done %u\n", - priv->firmware_version, + adev->firmware_version, le32_to_cpu(fw_stats->tx_desc_of), le32_to_cpu(fw_stats->rx_oom), le32_to_cpu(fw_stats->rx_hdr_of), @@ -1185,7 +1215,7 @@ acx_s_proc_diag_output(char *buf, wlande /*********************************************************************** */ static int -acx_s_proc_phy_output(char *buf, wlandevice_t *priv) +acx_s_proc_phy_output(char *buf, acx_device_t *adev) { char *p = buf; int i; @@ -1193,7 +1223,7 @@ acx_s_proc_phy_output(char *buf, wlandev FN_ENTER; /* - if (RADIO_RFMD_11 != priv->radio_type) { + if (RADIO_RFMD_11 != adev->radio_type) { printk("sorry, not yet adapted for radio types " "other than RFMD, please verify " "PHY size etc. first!\n"); @@ -1205,7 +1235,7 @@ acx_s_proc_phy_output(char *buf, wlandev * only have some page number registers with altered value, * all other registers remain the same. */ for (i = 0; i < 0x80; i++) { - acx_s_read_phy_reg(priv, i, p++); + acx_s_read_phy_reg(adev, i, p++); } FN_EXIT1(p - buf); @@ -1228,18 +1258,18 @@ static int acx_e_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *data) { - wlandevice_t *priv = (wlandevice_t *)data; + acx_device_t *adev = (acx_device_t*)data; unsigned long flags; int length; FN_ENTER; - acx_sem_lock(priv); - acx_lock(priv, flags); + acx_sem_lock(adev); + acx_lock(adev, flags); /* fill buf */ - length = acx_l_proc_output(buf, priv); - acx_unlock(priv, flags); - acx_sem_unlock(priv); + length = acx_l_proc_output(buf, adev); + acx_unlock(adev, flags); + acx_sem_unlock(adev); /* housekeeping */ if (length <= offset + count) @@ -1258,15 +1288,15 @@ static int acx_e_read_proc_diag(char *buf, char **start, off_t offset, int count, int *eof, void *data) { - wlandevice_t *priv = (wlandevice_t *)data; + acx_device_t *adev = (acx_device_t*)data; int length; FN_ENTER; - acx_sem_lock(priv); + acx_sem_lock(adev); /* fill buf */ - length = acx_s_proc_diag_output(buf, priv); - acx_sem_unlock(priv); + length = acx_s_proc_diag_output(buf, adev); + acx_sem_unlock(adev); /* housekeeping */ if (length <= offset + count) @@ -1285,17 +1315,17 @@ static int acx_e_read_proc_eeprom(char *buf, char **start, off_t offset, int count, int *eof, void *data) { - wlandevice_t *priv = (wlandevice_t *)data; + acx_device_t *adev = (acx_device_t*)data; int length; FN_ENTER; /* fill buf */ length = 0; - if (IS_PCI(priv)) { - acx_sem_lock(priv); - length = acxpci_proc_eeprom_output(buf, priv); - acx_sem_unlock(priv); + if (IS_PCI(adev)) { + acx_sem_lock(adev); + length = acxpci_proc_eeprom_output(buf, adev); + acx_sem_unlock(adev); } /* housekeeping */ @@ -1315,15 +1345,15 @@ static int acx_e_read_proc_phy(char *buf, char **start, off_t offset, int count, int *eof, void *data) { - wlandevice_t *priv = (wlandevice_t *)data; + acx_device_t *adev = (acx_device_t*)data; int length; FN_ENTER; - acx_sem_lock(priv); + acx_sem_lock(adev); /* fill buf */ - length = acx_s_proc_phy_output(buf, priv); - acx_sem_unlock(priv); + length = acx_s_proc_phy_output(buf, adev); + acx_sem_unlock(adev); /* housekeeping */ if (length <= offset + count) @@ -1354,23 +1384,23 @@ proc_funcs[] = { }; static int -manage_proc_entries(const struct net_device *dev, int remove) +manage_proc_entries(const struct net_device *ndev, int remove) { - /* doh, netdev_priv() doesn't have const! */ - wlandevice_t *priv = netdev_priv((struct net_device *)dev); + acx_device_t *adev = ndev2adev((struct net_device *)ndev); char procbuf[80]; int i; for (i = 0; i < VEC_SIZE(proc_files); i++) { - sprintf(procbuf, "driver/acx_%s%s", dev->name, proc_files[i]); + snprintf(procbuf, sizeof(procbuf), + "driver/acx_%s%s", ndev->name, proc_files[i]); + log(L_INIT, "%sing /proc entry %s\n", + remove ? "remov" : "creat", procbuf); if (!remove) { - log(L_INIT, "creating /proc entry %s\n", procbuf); - if (!create_proc_read_entry(procbuf, 0, 0, proc_funcs[i], priv)) { + if (!create_proc_read_entry(procbuf, 0, 0, proc_funcs[i], adev)) { printk("acx: cannot register /proc entry %s\n", procbuf); return NOT_OK; } } else { - log(L_INIT, "removing /proc entry %s\n", procbuf); remove_proc_entry(procbuf, NULL); } } @@ -1378,15 +1408,15 @@ manage_proc_entries(const struct net_dev } int -acx_proc_register_entries(const struct net_device *dev) +acx_proc_register_entries(const struct net_device *ndev) { - return manage_proc_entries(dev, 0); + return manage_proc_entries(ndev, 0); } int -acx_proc_unregister_entries(const struct net_device *dev) +acx_proc_unregister_entries(const struct net_device *ndev) { - return manage_proc_entries(dev, 1); + return manage_proc_entries(ndev, 1); } #endif /* CONFIG_PROC_FS */ @@ -1430,7 +1460,7 @@ rate111to5bits(unsigned int rate) } static void -acx_s_cmd_join_bssid(wlandevice_t *priv, const u8 *bssid) +acx_s_cmd_join_bssid(acx_device_t *adev, const u8 *bssid) { acx_joinbss_t tmp; int dtim_interval; @@ -1441,8 +1471,8 @@ acx_s_cmd_join_bssid(wlandevice_t *priv, FN_ENTER; - dtim_interval = (ACX_MODE_0_ADHOC == priv->mode) ? - 1 : priv->dtim_interval; + dtim_interval = (ACX_MODE_0_ADHOC == adev->mode) ? + 1 : adev->dtim_interval; memset(&tmp, 0, sizeof(tmp)); @@ -1450,33 +1480,33 @@ acx_s_cmd_join_bssid(wlandevice_t *priv, tmp.bssid[i] = bssid[ETH_ALEN-1 - i]; } - tmp.beacon_interval = cpu_to_le16(priv->beacon_interval); + tmp.beacon_interval = cpu_to_le16(adev->beacon_interval); /* Basic rate set. Control frame responses (such as ACK or CTS frames) ** are sent with one of these rates */ - if (IS_ACX111(priv)) { + if (IS_ACX111(adev)) { /* It was experimentally determined that rates_basic ** can take 11g rates as well, not only rates ** defined with JOINBSS_RATES_BASIC111_nnn. ** Just use RATE111_nnn constants... */ tmp.u.acx111.dtim_interval = dtim_interval; - tmp.u.acx111.rates_basic = cpu_to_le16(priv->rate_basic); + tmp.u.acx111.rates_basic = cpu_to_le16(adev->rate_basic); log(L_ASSOC, "rates_basic:%04X, rates_supported:%04X\n", - priv->rate_basic, priv->rate_oper); + adev->rate_basic, adev->rate_oper); } else { tmp.u.acx100.dtim_interval = dtim_interval; - tmp.u.acx100.rates_basic = rate111to5bits(priv->rate_basic); - tmp.u.acx100.rates_supported = rate111to5bits(priv->rate_oper); + tmp.u.acx100.rates_basic = rate111to5bits(adev->rate_basic); + tmp.u.acx100.rates_supported = rate111to5bits(adev->rate_oper); log(L_ASSOC, "rates_basic:%04X->%02X, " "rates_supported:%04X->%02X\n", - priv->rate_basic, tmp.u.acx100.rates_basic, - priv->rate_oper, tmp.u.acx100.rates_supported); + adev->rate_basic, tmp.u.acx100.rates_basic, + adev->rate_oper, tmp.u.acx100.rates_supported); } /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames ** will be sent (rate/modulation/preamble) */ - tmp.genfrm_txrate = bitpos2genframe_txrate[lowest_bit(priv->rate_basic)]; - tmp.genfrm_mod_pre = 0; /* FIXME: was = priv->capab_short (which is always 0); */ + tmp.genfrm_txrate = bitpos2genframe_txrate[lowest_bit(adev->rate_basic)]; + tmp.genfrm_mod_pre = 0; /* FIXME: was = adev->capab_short (which was always 0); */ /* we can use short pre *if* all peers can understand it */ /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */ @@ -1485,17 +1515,17 @@ acx_s_cmd_join_bssid(wlandevice_t *priv, ** but allows us to send anything (we really want to retain ** ability to tx arbitrary frames in MONITOR mode) */ - tmp.macmode = (priv->mode != ACX_MODE_MONITOR ? priv->mode : ACX_MODE_2_STA); - tmp.channel = priv->channel; - tmp.essid_len = priv->essid_len; + tmp.macmode = (adev->mode != ACX_MODE_MONITOR ? adev->mode : ACX_MODE_2_STA); + tmp.channel = adev->channel; + tmp.essid_len = adev->essid_len; /* NOTE: the code memcpy'd essid_len + 1 before, which is WRONG! */ - memcpy(tmp.essid, priv->essid, tmp.essid_len); - acx_s_issue_cmd(priv, ACX1xx_CMD_JOIN, &tmp, tmp.essid_len + 0x11); + memcpy(tmp.essid, adev->essid, tmp.essid_len); + acx_s_issue_cmd(adev, ACX1xx_CMD_JOIN, &tmp, tmp.essid_len + 0x11); log(L_ASSOC|L_DEBUG, "BSS_Type = %u\n", tmp.macmode); - acxlog_mac(L_ASSOC|L_DEBUG, "JoinBSSID MAC:", priv->bssid, "\n"); + acxlog_mac(L_ASSOC|L_DEBUG, "JoinBSSID MAC:", adev->bssid, "\n"); - acx_update_capabilities(priv); + acx_update_capabilities(adev); FN_EXIT0; } @@ -1504,57 +1534,54 @@ acx_s_cmd_join_bssid(wlandevice_t *priv, ** acx_s_cmd_start_scan ** ** Issue scan command to the hardware +** +** unified function for both ACX111 and ACX100 */ static void -acx100_s_scan_chan(wlandevice_t *priv) +acx_s_scan_chan(acx_device_t *adev) { - acx100_scan_t s; + union { + acx111_scan_t acx111; + acx100_scan_t acx100; + } s; FN_ENTER; memset(&s, 0, sizeof(s)); - s.count = cpu_to_le16(priv->scan_count); - s.start_chan = cpu_to_le16(1); - s.flags = cpu_to_le16(0x8000); - s.max_rate = priv->scan_rate; - s.options = priv->scan_mode; - s.chan_duration = cpu_to_le16(priv->scan_duration); - s.max_probe_delay = cpu_to_le16(priv->scan_probe_delay); - - acx_s_issue_cmd(priv, ACX1xx_CMD_SCAN, &s, sizeof(s)); - FN_EXIT0; -} - -static void -acx111_s_scan_chan(wlandevice_t *priv) -{ - acx111_scan_t s; - FN_ENTER; + /* first common positions... */ - memset(&s, 0, sizeof(s)); - s.count = cpu_to_le16(priv->scan_count); - s.channel_list_select = 0; /* scan every allowed channel */ - /*s.channel_list_select = 1;*/ /* scan given channels */ - s.rate = priv->scan_rate; - s.options = priv->scan_mode; - s.chan_duration = cpu_to_le16(priv->scan_duration); - s.max_probe_delay = cpu_to_le16(priv->scan_probe_delay); - /*s.modulation = 0x40;*/ /* long preamble? OFDM? -> only for active scan */ - s.modulation = 0; - /*s.channel_list[0] = 6; - s.channel_list[1] = 4;*/ + s.acx111.count = cpu_to_le16(adev->scan_count); + s.acx111.rate = adev->scan_rate; + s.acx111.options = adev->scan_mode; + s.acx111.chan_duration = cpu_to_le16(adev->scan_duration); + s.acx111.max_probe_delay = cpu_to_le16(adev->scan_probe_delay); + + /* ...then differences */ + + if (IS_ACX111(adev)) { + s.acx111.channel_list_select = 0; /* scan every allowed channel */ + /*s.acx111.channel_list_select = 1;*/ /* scan given channels */ + /*s.acx111.modulation = 0x40;*/ /* long preamble? OFDM? -> only for active scan */ + s.acx111.modulation = 0; + /*s.acx111.channel_list[0] = 6; + s.acx111.channel_list[1] = 4;*/ + } else { + s.acx100.start_chan = cpu_to_le16(1); + s.acx100.flags = cpu_to_le16(0x8000); + } - acx_s_issue_cmd(priv, ACX1xx_CMD_SCAN, &s, sizeof(s)); + acx_s_issue_cmd(adev, ACX1xx_CMD_SCAN, &s, sizeof(s)); FN_EXIT0; } + void -acx_s_cmd_start_scan(wlandevice_t *priv) +acx_s_cmd_start_scan(acx_device_t *adev) { /* time_before check is 'just in case' thing */ - if (!(priv->irq_status & HOST_INT_SCAN_COMPLETE) - && time_before(jiffies, priv->scan_start + 10*HZ) + if (!(adev->irq_status & HOST_INT_SCAN_COMPLETE) + && time_before(jiffies, adev->scan_start + 10*HZ) ) { log(L_INIT, "start_scan: seems like previous scan " "is still running. Not starting anew. Please report\n"); @@ -1563,14 +1590,10 @@ acx_s_cmd_start_scan(wlandevice_t *priv) log(L_INIT, "starting radio scan\n"); /* remember that fw is commanded to do scan */ - priv->scan_start = jiffies; - CLEAR_BIT(priv->irq_status, HOST_INT_SCAN_COMPLETE); + adev->scan_start = jiffies; + CLEAR_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE); /* issue it */ - if (IS_ACX100(priv)) { - acx100_s_scan_chan(priv); - } else { - acx111_s_scan_chan(priv); - } + acx_s_scan_chan(adev); } @@ -1578,41 +1601,41 @@ acx_s_cmd_start_scan(wlandevice_t *priv) ** acx111 feature config */ static int -acx111_s_get_feature_config(wlandevice_t *priv, +acx111_s_get_feature_config(acx_device_t *adev, u32 *feature_options, u32 *data_flow_options) { - struct acx111_ie_feature_config fc; + struct acx111_ie_feature_config feat; - if (!IS_ACX111(priv)) { + if (!IS_ACX111(adev)) { return NOT_OK; } - memset(&fc, 0, sizeof(fc)); + memset(&feat, 0, sizeof(feat)); - if (OK != acx_s_interrogate(priv, &fc, ACX1xx_IE_FEATURE_CONFIG)) { + if (OK != acx_s_interrogate(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) { return NOT_OK; } log(L_DEBUG, "got Feature option:0x%X, DataFlow option: 0x%X\n", - fc.feature_options, - fc.data_flow_options); + feat.feature_options, + feat.data_flow_options); if (feature_options) - *feature_options = le32_to_cpu(fc.feature_options); + *feature_options = le32_to_cpu(feat.feature_options); if (data_flow_options) - *data_flow_options = le32_to_cpu(fc.data_flow_options); + *data_flow_options = le32_to_cpu(feat.data_flow_options); return OK; } static int -acx111_s_set_feature_config(wlandevice_t *priv, +acx111_s_set_feature_config(acx_device_t *adev, u32 feature_options, u32 data_flow_options, unsigned int mode /* 0 == remove, 1 == add, 2 == set */) { - struct acx111_ie_feature_config fc; + struct acx111_ie_feature_config feat; - if (!IS_ACX111(priv)) { + if (!IS_ACX111(adev)) { return NOT_OK; } @@ -1621,29 +1644,29 @@ acx111_s_set_feature_config(wlandevice_t if (mode != 2) /* need to modify old data */ - acx111_s_get_feature_config(priv, &fc.feature_options, &fc.data_flow_options); + acx111_s_get_feature_config(adev, &feat.feature_options, &feat.data_flow_options); else { /* need to set a completely new value */ - fc.feature_options = 0; - fc.data_flow_options = 0; + feat.feature_options = 0; + feat.data_flow_options = 0; } if (mode == 0) { /* remove */ - CLEAR_BIT(fc.feature_options, cpu_to_le32(feature_options)); - CLEAR_BIT(fc.data_flow_options, cpu_to_le32(data_flow_options)); + CLEAR_BIT(feat.feature_options, cpu_to_le32(feature_options)); + CLEAR_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options)); } else { /* add or set */ - SET_BIT(fc.feature_options, cpu_to_le32(feature_options)); - SET_BIT(fc.data_flow_options, cpu_to_le32(data_flow_options)); + SET_BIT(feat.feature_options, cpu_to_le32(feature_options)); + SET_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options)); } log(L_DEBUG, "old: feature 0x%08X dataflow 0x%08X. mode: %u\n" "new: feature 0x%08X dataflow 0x%08X\n", feature_options, data_flow_options, mode, - le32_to_cpu(fc.feature_options), - le32_to_cpu(fc.data_flow_options)); + le32_to_cpu(feat.feature_options), + le32_to_cpu(feat.data_flow_options)); - if (OK != acx_s_configure(priv, &fc, ACX1xx_IE_FEATURE_CONFIG)) { + if (OK != acx_s_configure(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) { return NOT_OK; } @@ -1651,19 +1674,19 @@ acx111_s_set_feature_config(wlandevice_t } static inline int -acx111_s_feature_off(wlandevice_t *priv, u32 f, u32 d) +acx111_s_feature_off(acx_device_t *adev, u32 f, u32 d) { - return acx111_s_set_feature_config(priv, f, d, 0); + return acx111_s_set_feature_config(adev, f, d, 0); } static inline int -acx111_s_feature_on(wlandevice_t *priv, u32 f, u32 d) +acx111_s_feature_on(acx_device_t *adev, u32 f, u32 d) { - return acx111_s_set_feature_config(priv, f, d, 1); + return acx111_s_set_feature_config(adev, f, d, 1); } static inline int -acx111_s_feature_set(wlandevice_t *priv, u32 f, u32 d) +acx111_s_feature_set(acx_device_t *adev, u32 f, u32 d) { - return acx111_s_set_feature_config(priv, f, d, 2); + return acx111_s_set_feature_config(adev, f, d, 2); } @@ -1671,7 +1694,7 @@ acx111_s_feature_set(wlandevice_t *priv, ** acx100_s_init_memory_pools */ static int -acx100_s_init_memory_pools(wlandevice_t *priv, const acx_ie_memmap_t *mmt) +acx100_s_init_memory_pools(acx_device_t *adev, const acx_ie_memmap_t *mmt) { acx100_ie_memblocksize_t MemoryBlockSize; acx100_ie_memconfigoption_t MemoryConfigOption; @@ -1686,36 +1709,36 @@ acx100_s_init_memory_pools(wlandevice_t /* Let's see if we can follow this: first we select our memory block size (which I think is completely arbitrary) */ - MemoryBlockSize.size = cpu_to_le16(priv->memblocksize); + MemoryBlockSize.size = cpu_to_le16(adev->memblocksize); /* Then we alert the card to our decision of block size */ - if (OK != acx_s_configure(priv, &MemoryBlockSize, ACX100_IE_BLOCK_SIZE)) { + if (OK != acx_s_configure(adev, &MemoryBlockSize, ACX100_IE_BLOCK_SIZE)) { goto bad; } /* We figure out how many total blocks we can create, using the block size we chose, and the beginning and ending memory pointers, i.e.: end-start/size */ - TotalMemoryBlocks = (le32_to_cpu(mmt->PoolEnd) - le32_to_cpu(mmt->PoolStart)) / priv->memblocksize; + TotalMemoryBlocks = (le32_to_cpu(mmt->PoolEnd) - le32_to_cpu(mmt->PoolStart)) / adev->memblocksize; log(L_DEBUG, "TotalMemoryBlocks=%u (%u bytes)\n", - TotalMemoryBlocks, TotalMemoryBlocks*priv->memblocksize); + TotalMemoryBlocks, TotalMemoryBlocks*adev->memblocksize); /* MemoryConfigOption.DMA_config bitmask: - // access to ACX memory is to be done: - 0x00080000 // using PCI conf space?! - 0x00040000 // using IO instructions? - 0x00000000 // using memory access instructions - 0x00020000 // use local memory block linked list (else what?) - 0x00010000 // use host indirect descriptors (else host must access ACX memory?) + access to ACX memory is to be done: + 0x00080000 using PCI conf space?! + 0x00040000 using IO instructions? + 0x00000000 using memory access instructions + 0x00020000 using local memory block linked list (else what?) + 0x00010000 using host indirect descriptors (else host must access ACX memory?) */ - if (IS_PCI(priv)) { + if (IS_PCI(adev)) { MemoryConfigOption.DMA_config = cpu_to_le32(0x30000); /* Declare start of the Rx host pool */ - MemoryConfigOption.pRxHostDesc = cpu2acx(priv->rxhostdesc_startphy); + MemoryConfigOption.pRxHostDesc = cpu2acx(adev->rxhostdesc_startphy); log(L_DEBUG, "pRxHostDesc 0x%08X, rxhostdesc_startphy 0x%lX\n", acx2cpu(MemoryConfigOption.pRxHostDesc), - (long)priv->rxhostdesc_startphy); + (long)adev->rxhostdesc_startphy); } else { MemoryConfigOption.DMA_config = cpu_to_le32(0x20000); } @@ -1729,8 +1752,8 @@ acx100_s_init_memory_pools(wlandevice_t MemoryConfigOption.RxBlockNum = cpu_to_le16(RxBlockNum); /* size of the tx and rx descriptor queues */ - TotalTxBlockSize = TxBlockNum * priv->memblocksize; - TotalRxBlockSize = RxBlockNum * priv->memblocksize; + TotalTxBlockSize = TxBlockNum * adev->memblocksize; + TotalRxBlockSize = RxBlockNum * adev->memblocksize; log(L_DEBUG, "TxBlockNum %u RxBlockNum %u TotalTxBlockSize %u " "TotalTxBlockSize %u\n", TxBlockNum, RxBlockNum, TotalTxBlockSize, TotalRxBlockSize); @@ -1748,12 +1771,12 @@ acx100_s_init_memory_pools(wlandevice_t MemoryConfigOption.tx_mem, MemoryConfigOption.rx_mem); /* alert the device to our decision */ - if (OK != acx_s_configure(priv, &MemoryConfigOption, ACX1xx_IE_MEMORY_CONFIG_OPTIONS)) { + if (OK != acx_s_configure(adev, &MemoryConfigOption, ACX1xx_IE_MEMORY_CONFIG_OPTIONS)) { goto bad; } /* and tell the device to kick it into gear */ - if (OK != acx_s_issue_cmd(priv, ACX100_CMD_INIT_MEMORY, NULL, 0)) { + if (OK != acx_s_issue_cmd(adev, ACX100_CMD_INIT_MEMORY, NULL, 0)) { goto bad; } FN_EXIT1(OK); @@ -1771,7 +1794,7 @@ bad: ** lock it (we need to sleep). Not a problem since IRQs can't happen */ static int -acx100_s_create_dma_regions(wlandevice_t *priv) +acx100_s_create_dma_regions(acx_device_t *adev) { acx100_ie_queueconfig_t queueconf; acx_ie_memmap_t memmap; @@ -1781,7 +1804,7 @@ acx100_s_create_dma_regions(wlandevice_t FN_ENTER; /* read out the acx100 physical start address for the queues */ - if (OK != acx_s_interrogate(priv, &memmap, ACX1xx_IE_MEMORY_MAP)) { + if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) { goto fail; } @@ -1793,7 +1816,7 @@ acx100_s_create_dma_regions(wlandevice_t memset(&queueconf, 0, sizeof(queueconf)); /* Not needed for PCI, so we can avoid setting them altogether */ - if (IS_USB(priv)) { + if (IS_USB(adev)) { queueconf.NumTxDesc = USB_TX_CNT; queueconf.NumRxDesc = USB_RX_CNT; } @@ -1815,18 +1838,18 @@ acx100_s_create_dma_regions(wlandevice_t ); /* sets the beginning of the next queue */ queueconf.HostQueueEnd = cpu_to_le32(le32_to_cpu(queueconf.QueueEnd) + 8); - if (OK != acx_s_configure(priv, &queueconf, ACX1xx_IE_QUEUE_CONFIG)) { + if (OK != acx_s_configure(adev, &queueconf, ACX1xx_IE_QUEUE_CONFIG)) { goto fail; } - if (IS_PCI(priv)) { + if (IS_PCI(adev)) { /* sets the beginning of the rx descriptor queue, after the tx descrs */ - if (OK != acxpci_s_create_hostdesc_queues(priv)) + if (OK != acxpci_s_create_hostdesc_queues(adev)) goto fail; - acxpci_create_desc_queues(priv, tx_queue_start, rx_queue_start); + acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start); } - if (OK != acx_s_interrogate(priv, &memmap, ACX1xx_IE_MEMORY_MAP)) { + if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) { goto fail; } @@ -1834,11 +1857,11 @@ acx100_s_create_dma_regions(wlandevice_t (le32_to_cpu(memmap.QueueEnd) + 4 + 0x1f) & ~0x1f ); - if (OK != acx_s_configure(priv, &memmap, ACX1xx_IE_MEMORY_MAP)) { + if (OK != acx_s_configure(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) { goto fail; } - if (OK != acx100_s_init_memory_pools(priv, &memmap)) { + if (OK != acx100_s_init_memory_pools(adev, &memmap)) { goto fail; } @@ -1847,8 +1870,8 @@ acx100_s_create_dma_regions(wlandevice_t fail: acx_s_msleep(1000); /* ? */ - if (IS_PCI(priv)) - acxpci_free_desc_queues(priv); + if (IS_PCI(adev)) + acxpci_free_desc_queues(adev); end: FN_EXIT1(res); return res; @@ -1858,13 +1881,13 @@ end: /*********************************************************************** ** acx111_s_create_dma_regions ** -** Note that this fn messes up heavily with hardware, but we cannot +** Note that this fn messes heavily with hardware, but we cannot ** lock it (we need to sleep). Not a problem since IRQs can't happen */ #define ACX111_PERCENT(percent) ((percent)/5) static int -acx111_s_create_dma_regions(wlandevice_t *priv) +acx111_s_create_dma_regions(acx_device_t *adev) { struct acx111_ie_memoryconfig memconf; struct acx111_ie_queueconfig queueconf; @@ -1875,17 +1898,17 @@ acx111_s_create_dma_regions(wlandevice_t /* Calculate memory positions and queue sizes */ /* Set up our host descriptor pool + data pool */ - if (IS_PCI(priv)) { - if (OK != acxpci_s_create_hostdesc_queues(priv)) + if (IS_PCI(adev)) { + if (OK != acxpci_s_create_hostdesc_queues(adev)) goto fail; } memset(&memconf, 0, sizeof(memconf)); /* the number of STAs (STA contexts) to support ** NB: was set to 1 and everything seemed to work nevertheless... */ - memconf.no_of_stations = cpu_to_le16(VEC_SIZE(priv->sta_list)); + memconf.no_of_stations = cpu_to_le16(VEC_SIZE(adev->sta_list)); /* specify the memory block size. Default is 256 */ - memconf.memory_block_size = cpu_to_le16(priv->memblocksize); + memconf.memory_block_size = cpu_to_le16(adev->memblocksize); /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */ memconf.tx_rx_memory_block_allocation = ACX111_PERCENT(50); /* set the count of our queues @@ -1904,8 +1927,8 @@ acx111_s_create_dma_regions(wlandevice_t memconf.rx_queue1_count_descs = RX_CNT; memconf.rx_queue1_type = 7; /* must be set to 7 */ /* done by memset: memconf.rx_queue1_prio = 0; low prio */ - if (IS_PCI(priv)) { - memconf.rx_queue1_host_rx_start = cpu2acx(priv->rxhostdesc_startphy); + if (IS_PCI(adev)) { + memconf.rx_queue1_host_rx_start = cpu2acx(adev->rxhostdesc_startphy); } /* Tx descriptor queue config */ memconf.tx_queue1_count_descs = TX_CNT; @@ -1917,11 +1940,11 @@ acx111_s_create_dma_regions(wlandevice_t ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_IE_QUEUE_CONFIG) ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig ** which is 4 bytes larger. what a mess. TODO: clean it up) */ - if (OK != acx_s_configure(priv, &memconf, ACX1xx_IE_QUEUE_CONFIG)) { + if (OK != acx_s_configure(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG)) { goto fail; } - acx_s_interrogate(priv, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS); + acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS); tx_queue_start = le32_to_cpu(queueconf.tx1_queue_address); rx_queue_start = le32_to_cpu(queueconf.rx1_queue_address); @@ -1932,20 +1955,20 @@ acx111_s_create_dma_regions(wlandevice_t "rx_memory_block_address: %X\n" "tx1_queue address: %X\n" "rx1_queue address: %X\n", - le16_to_cpu(queueconf.len), - le32_to_cpu(queueconf.tx_memory_block_address), - le32_to_cpu(queueconf.rx_memory_block_address), - tx_queue_start, - rx_queue_start); + le16_to_cpu(queueconf.len), + le32_to_cpu(queueconf.tx_memory_block_address), + le32_to_cpu(queueconf.rx_memory_block_address), + tx_queue_start, + rx_queue_start); - if (IS_PCI(priv)) - acxpci_create_desc_queues(priv, tx_queue_start, rx_queue_start); + if (IS_PCI(adev)) + acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start); FN_EXIT1(OK); return OK; fail: - if (IS_PCI(priv)) - acxpci_free_desc_queues(priv); + if (IS_PCI(adev)) + acxpci_free_desc_queues(adev); FN_EXIT1(NOT_OK); return NOT_OK; @@ -1953,146 +1976,265 @@ fail: /*********************************************************************** +*/ +static void +acx_s_initialize_rx_config(acx_device_t *adev) +{ + struct { + u16 id ACX_PACKED; + u16 len ACX_PACKED; + u16 rx_cfg1 ACX_PACKED; + u16 rx_cfg2 ACX_PACKED; + } cfg; + + switch (adev->mode) { + case ACX_MODE_OFF: + adev->rx_config_1 = (u16) (0 + /* | RX_CFG1_INCLUDE_RXBUF_HDR */ + /* | RX_CFG1_FILTER_SSID */ + /* | RX_CFG1_FILTER_BCAST */ + /* | RX_CFG1_RCV_MC_ADDR1 */ + /* | RX_CFG1_RCV_MC_ADDR0 */ + /* | RX_CFG1_FILTER_ALL_MULTI */ + /* | RX_CFG1_FILTER_BSSID */ + /* | RX_CFG1_FILTER_MAC */ + /* | RX_CFG1_RCV_PROMISCUOUS */ + /* | RX_CFG1_INCLUDE_FCS */ + /* | RX_CFG1_INCLUDE_PHY_HDR */ + ); + adev->rx_config_2 = (u16) (0 + /*| RX_CFG2_RCV_ASSOC_REQ */ + /*| RX_CFG2_RCV_AUTH_FRAMES */ + /*| RX_CFG2_RCV_BEACON_FRAMES */ + /*| RX_CFG2_RCV_CONTENTION_FREE */ + /*| RX_CFG2_RCV_CTRL_FRAMES */ + /*| RX_CFG2_RCV_DATA_FRAMES */ + /*| RX_CFG2_RCV_BROKEN_FRAMES */ + /*| RX_CFG2_RCV_MGMT_FRAMES */ + /*| RX_CFG2_RCV_PROBE_REQ */ + /*| RX_CFG2_RCV_PROBE_RESP */ + /*| RX_CFG2_RCV_ACK_FRAMES */ + /*| RX_CFG2_RCV_OTHER */ + ); + break; + case ACX_MODE_MONITOR: + adev->rx_config_1 = (u16) (0 + /* | RX_CFG1_INCLUDE_RXBUF_HDR */ + /* | RX_CFG1_FILTER_SSID */ + /* | RX_CFG1_FILTER_BCAST */ + /* | RX_CFG1_RCV_MC_ADDR1 */ + /* | RX_CFG1_RCV_MC_ADDR0 */ + /* | RX_CFG1_FILTER_ALL_MULTI */ + /* | RX_CFG1_FILTER_BSSID */ + /* | RX_CFG1_FILTER_MAC */ + | RX_CFG1_RCV_PROMISCUOUS + /* | RX_CFG1_INCLUDE_FCS */ + /* | RX_CFG1_INCLUDE_PHY_HDR */ + ); + adev->rx_config_2 = (u16) (0 + | RX_CFG2_RCV_ASSOC_REQ + | RX_CFG2_RCV_AUTH_FRAMES + | RX_CFG2_RCV_BEACON_FRAMES + | RX_CFG2_RCV_CONTENTION_FREE + | RX_CFG2_RCV_CTRL_FRAMES + | RX_CFG2_RCV_DATA_FRAMES + | RX_CFG2_RCV_BROKEN_FRAMES + | RX_CFG2_RCV_MGMT_FRAMES + | RX_CFG2_RCV_PROBE_REQ + | RX_CFG2_RCV_PROBE_RESP + | RX_CFG2_RCV_ACK_FRAMES + | RX_CFG2_RCV_OTHER + ); + break; + default: + adev->rx_config_1 = (u16) (0 + /* | RX_CFG1_INCLUDE_RXBUF_HDR */ + /* | RX_CFG1_FILTER_SSID */ + /* | RX_CFG1_FILTER_BCAST */ + /* | RX_CFG1_RCV_MC_ADDR1 */ + /* | RX_CFG1_RCV_MC_ADDR0 */ + /* | RX_CFG1_FILTER_ALL_MULTI */ + /* | RX_CFG1_FILTER_BSSID */ + | RX_CFG1_FILTER_MAC + /* | RX_CFG1_RCV_PROMISCUOUS */ + /* | RX_CFG1_INCLUDE_FCS */ + /* | RX_CFG1_INCLUDE_PHY_HDR */ + ); + adev->rx_config_2 = (u16) (0 + | RX_CFG2_RCV_ASSOC_REQ + | RX_CFG2_RCV_AUTH_FRAMES + | RX_CFG2_RCV_BEACON_FRAMES + | RX_CFG2_RCV_CONTENTION_FREE + | RX_CFG2_RCV_CTRL_FRAMES + | RX_CFG2_RCV_DATA_FRAMES + /*| RX_CFG2_RCV_BROKEN_FRAMES */ + | RX_CFG2_RCV_MGMT_FRAMES + | RX_CFG2_RCV_PROBE_REQ + | RX_CFG2_RCV_PROBE_RESP + /*| RX_CFG2_RCV_ACK_FRAMES */ + | RX_CFG2_RCV_OTHER + ); + break; + } + adev->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR; + + if ((adev->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR) + || (adev->firmware_numver >= 0x02000000)) + adev->phy_header_len = IS_ACX111(adev) ? 8 : 4; + else + adev->phy_header_len = 0; + + log(L_INIT, "setting RXconfig to %04X:%04X\n", + adev->rx_config_1, adev->rx_config_2); + cfg.rx_cfg1 = cpu_to_le16(adev->rx_config_1); + cfg.rx_cfg2 = cpu_to_le16(adev->rx_config_2); + acx_s_configure(adev, &cfg, ACX1xx_IE_RXCONFIG); +} + + +/*********************************************************************** ** acx_s_set_defaults */ void -acx_s_set_defaults(wlandevice_t *priv) +acx_s_set_defaults(acx_device_t *adev) { unsigned long flags; FN_ENTER; + /* do it before getting settings, prevent bogus channel 0 warning */ + adev->channel = 1; + /* query some settings from the card. * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial - * query is REQUIRED, otherwise the card won't work correctly!! */ - priv->get_mask = GETSET_ANTENNA|GETSET_SENSITIVITY|GETSET_STATION_ID|GETSET_REG_DOMAIN; + * query is REQUIRED, otherwise the card won't work correctly! */ + adev->get_mask = GETSET_ANTENNA|GETSET_SENSITIVITY|GETSET_STATION_ID|GETSET_REG_DOMAIN; /* Only ACX100 supports ED and CCA */ - if (IS_ACX100(priv)) - priv->get_mask |= GETSET_CCA|GETSET_ED_THRESH; + if (IS_ACX100(adev)) + adev->get_mask |= GETSET_CCA|GETSET_ED_THRESH; - acx_s_update_card_settings(priv); + acx_s_update_card_settings(adev); - acx_lock(priv, flags); + acx_lock(adev, flags); /* set our global interrupt mask */ - if (IS_PCI(priv)) - acxpci_set_interrupt_mask(priv); + if (IS_PCI(adev)) + acxpci_set_interrupt_mask(adev); - priv->led_power = 1; /* LED is active on startup */ - priv->brange_max_quality = 60; /* LED blink max quality is 60 */ - priv->brange_time_last_state_change = jiffies; + adev->led_power = 1; /* LED is active on startup */ + adev->brange_max_quality = 60; /* LED blink max quality is 60 */ + adev->brange_time_last_state_change = jiffies; /* copy the MAC address we just got from the card * into our MAC address used during current 802.11 session */ - MAC_COPY(priv->dev_addr, priv->netdev->dev_addr); - sprintf(priv->essid, "STA%02X%02X%02X", - priv->dev_addr[3], priv->dev_addr[4], priv->dev_addr[5]); - priv->essid_len = sizeof("STAxxxxxx") - 1; /* make sure to adapt if changed above! */ - priv->essid_active = 1; + MAC_COPY(adev->dev_addr, adev->ndev->dev_addr); + MAC_BCAST(adev->ap); + + adev->essid_len = + snprintf(adev->essid, sizeof(adev->essid), "STA%02X%02X%02X", + adev->dev_addr[3], adev->dev_addr[4], adev->dev_addr[5]); + adev->essid_active = 1; /* we have a nick field to waste, so why not abuse it * to announce the driver version? ;-) */ - strncpy(priv->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE); + strncpy(adev->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE); - if (IS_PCI(priv)) { - if (IS_ACX111(priv)) { - /* Hope this is correct, only tested with domain 0x30 */ - acxpci_read_eeprom_byte(priv, 0x16F, &priv->reg_dom_id); - } else if (priv->eeprom_version < 5) { - acxpci_read_eeprom_byte(priv, 0x16F, &priv->reg_dom_id); - } else { - acxpci_read_eeprom_byte(priv, 0x171, &priv->reg_dom_id); - } + if (IS_PCI(adev)) { /* FIXME: this should be made to apply to USB, too! */ + /* first regulatory domain entry in EEPROM == default reg. domain */ + adev->reg_dom_id = adev->cfgopt_domains.list[0]; } - priv->channel = 1; /* 0xffff would be better, but then we won't get a "scan complete" * interrupt, so our current infrastructure will fail: */ - priv->scan_count = 1; - priv->scan_mode = ACX_SCAN_OPT_ACTIVE; + adev->scan_count = 1; + adev->scan_mode = ACX_SCAN_OPT_ACTIVE; + adev->scan_duration = 100; + adev->scan_probe_delay = 200; + /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */ + adev->scan_rate = ACX_SCAN_RATE_1; + + adev->mode = ACX_MODE_2_STA; + adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM; + adev->listen_interval = 100; + adev->beacon_interval = DEFAULT_BEACON_INTERVAL; + adev->dtim_interval = DEFAULT_DTIM_INTERVAL; - priv->scan_duration = 100; - priv->scan_probe_delay = 200; - priv->scan_rate = ACX_SCAN_RATE_1; - - priv->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM; - priv->preamble_mode = 2; /* auto */ - priv->listen_interval = 100; - priv->beacon_interval = DEFAULT_BEACON_INTERVAL; - priv->mode = ACX_MODE_2_STA; - priv->dtim_interval = DEFAULT_DTIM_INTERVAL; + adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME; - priv->msdu_lifetime = DEFAULT_MSDU_LIFETIME; - SET_BIT(priv->set_mask, SET_MSDU_LIFETIME); - - priv->rts_threshold = DEFAULT_RTS_THRESHOLD; + adev->rts_threshold = DEFAULT_RTS_THRESHOLD; + adev->frag_threshold = 2346; /* use standard default values for retry limits */ - priv->short_retry = 7; /* max. retries for (short) non-RTS packets */ - priv->long_retry = 4; /* max. retries for long (RTS) packets */ - SET_BIT(priv->set_mask, GETSET_RETRY); - - priv->fallback_threshold = 3; - priv->stepup_threshold = 10; - priv->rate_bcast = RATE111_1; - priv->rate_bcast100 = RATE100_1; - priv->rate_basic = RATE111_1 | RATE111_2; - priv->rate_auto = 1; - if (IS_ACX111(priv)) { - priv->rate_oper = RATE111_ALL; + adev->short_retry = 7; /* max. retries for (short) non-RTS packets */ + adev->long_retry = 4; /* max. retries for long (RTS) packets */ + + adev->preamble_mode = 2; /* auto */ + adev->fallback_threshold = 3; + adev->stepup_threshold = 10; + adev->rate_bcast = RATE111_1; + adev->rate_bcast100 = RATE100_1; + adev->rate_basic = RATE111_1 | RATE111_2; + adev->rate_auto = 1; + if (IS_ACX111(adev)) { + adev->rate_oper = RATE111_ALL; } else { - priv->rate_oper = RATE111_ACX100_COMPAT; + adev->rate_oper = RATE111_ACX100_COMPAT; } - /* configure card to do rate fallback when in auto rate mode. */ - SET_BIT(priv->set_mask, SET_RATE_FALLBACK); - /* Supported Rates element - the rates here are given in units of * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */ - acx_l_update_ratevector(priv); - - priv->capab_short = 0; - priv->capab_pbcc = 1; - priv->capab_agility = 0; - - SET_BIT(priv->set_mask, SET_RXCONFIG); + acx_l_update_ratevector(adev); /* set some more defaults */ - if (IS_ACX111(priv)) { + if (IS_ACX111(adev)) { /* 30mW (15dBm) is default, at least in my acx111 card: */ - priv->tx_level_dbm = 15; + adev->tx_level_dbm = 15; } else { /* don't use max. level, since it might be dangerous * (e.g. WRT54G people experience * excessive Tx power damage!) */ - priv->tx_level_dbm = 18; + adev->tx_level_dbm = 18; } - /* priv->tx_level_auto = 1; */ - SET_BIT(priv->set_mask, GETSET_TXPOWER); - - if (IS_ACX111(priv)) { + /* adev->tx_level_auto = 1; */ + if (IS_ACX111(adev)) { /* start with sensitivity level 1 out of 3: */ - priv->sensitivity = 1; + adev->sensitivity = 1; } - /* better re-init the antenna value we got above */ - SET_BIT(priv->set_mask, GETSET_ANTENNA); - - priv->ps_wakeup_cfg = 0; - priv->ps_listen_interval = 0; - priv->ps_options = 0; - priv->ps_hangover_period = 0; - priv->ps_enhanced_transition_time = 0; -#ifdef POWER_SAVE_80211 - SET_BIT(priv->set_mask, GETSET_POWER_80211); +/* #define ENABLE_POWER_SAVE */ +#ifdef ENABLE_POWER_SAVE + adev->ps_wakeup_cfg = PS_CFG_ENABLE | PS_CFG_WAKEUP_ALL_BEAC; + adev->ps_listen_interval = 1; + adev->ps_options = PS_OPT_ENA_ENHANCED_PS | PS_OPT_TX_PSPOLL | PS_OPT_STILL_RCV_BCASTS; + adev->ps_hangover_period = 30; + adev->ps_enhanced_transition_time = 0; +#else + adev->ps_wakeup_cfg = 0; + adev->ps_listen_interval = 0; + adev->ps_options = 0; + adev->ps_hangover_period = 0; + adev->ps_enhanced_transition_time = 0; #endif - MAC_BCAST(priv->ap); + /* These settings will be set in fw on ifup */ + adev->set_mask = 0 + | GETSET_RETRY + | SET_MSDU_LIFETIME + /* configure card to do rate fallback when in auto rate mode */ + | SET_RATE_FALLBACK + | SET_RXCONFIG + | GETSET_TXPOWER + /* better re-init the antenna value we got above */ + | GETSET_ANTENNA +#if POWER_SAVE_80211 + | GETSET_POWER_80211 +#endif + ; - acx_unlock(priv, flags); - acx_lock_unhold(); // hold time 844814 CPU ticks @2GHz + acx_unlock(adev, flags); + acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */ - acx_s_initialize_rx_config(priv); + acx_s_initialize_rx_config(adev); FN_EXIT0; } @@ -2107,7 +2249,7 @@ acx_s_set_defaults(wlandevice_t *priv) ** instead which then manages Tx level programming :-\ */ static int -acx111_s_set_tx_level(wlandevice_t *priv, u8 level_dbm) +acx111_s_set_tx_level(acx_device_t *adev, u8 level_dbm) { struct acx111_ie_tx_level tx_level; @@ -2115,31 +2257,33 @@ acx111_s_set_tx_level(wlandevice_t *priv * 1 (30mW) [15dBm] * 2 (10mW) [10dBm] * For now, just assume all other acx111 cards have the same. - * Ideally we would query it here, but we first need a - * standard way to query individual configoptions easily. */ + * FIXME: Ideally we would query it here, but we first need a + * standard way to query individual configoptions easily. + * Well, now we have proper cfgopt txpower variables, but this still + * hasn't been done yet, since it also requires dBm <-> mW conversion here... */ if (level_dbm <= 12) { tx_level.level = 2; /* 10 dBm */ - priv->tx_level_dbm = 10; + adev->tx_level_dbm = 10; } else { tx_level.level = 1; /* 15 dBm */ - priv->tx_level_dbm = 15; + adev->tx_level_dbm = 15; } - if (level_dbm != priv->tx_level_dbm) + if (level_dbm != adev->tx_level_dbm) log(L_INIT, "acx111 firmware has specific " "power levels only: adjusted %d dBm to %d dBm!\n", - level_dbm, priv->tx_level_dbm); + level_dbm, adev->tx_level_dbm); - return acx_s_configure(priv, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL); + return acx_s_configure(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL); } static int -acx_s_set_tx_level(wlandevice_t *priv, u8 level_dbm) +acx_s_set_tx_level(acx_device_t *adev, u8 level_dbm) { - if (IS_ACX111(priv)) { - return acx111_s_set_tx_level(priv, level_dbm); + if (IS_ACX111(adev)) { + return acx111_s_set_tx_level(adev, level_dbm); } - if (IS_PCI(priv)) { - return acx100pci_s_set_tx_level(priv, level_dbm); + if (IS_PCI(adev)) { + return acx100pci_s_set_tx_level(adev, level_dbm); } return OK; } @@ -2150,79 +2294,23 @@ acx_s_set_tx_level(wlandevice_t *priv, u #ifdef UNUSED /* Returns the current tx level (ACX111) */ static u8 -acx111_s_get_tx_level(wlandevice_t *priv) +acx111_s_get_tx_level(acx_device_t *adev) { struct acx111_ie_tx_level tx_level; tx_level.level = 0; - acx_s_interrogate(priv, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL); + acx_s_interrogate(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL); return tx_level.level; } #endif /*********************************************************************** -** acx_s_init_mac +** acx_l_rxmonitor +** Called from IRQ context only */ -int -acx_s_init_mac(wlandevice_t *priv) -{ - int result = NOT_OK; - - FN_ENTER; - - if (IS_PCI(priv)) { - priv->memblocksize = 256; /* 256 is default */ - /* try to load radio for both ACX100 and ACX111, since both - * chips have at least some firmware versions making use of an - * external radio module */ - acxpci_s_upload_radio(priv); - } else { - priv->memblocksize = 128; - } - - if (IS_ACX111(priv)) { - /* for ACX111, the order is different from ACX100 - 1. init packet templates - 2. create station context and create dma regions - 3. init wep default keys - */ - if (OK != acx111_s_init_packet_templates(priv)) - goto fail; - if (OK != acx111_s_create_dma_regions(priv)) { - printk("%s: acx111_create_dma_regions FAILED\n", - priv->netdev->name); - goto fail; - } - } else { - if (OK != acx100_s_init_wep(priv)) - goto fail; - if (OK != acx100_s_init_packet_templates(priv)) - goto fail; - if (OK != acx100_s_create_dma_regions(priv)) { - printk("%s: acx100_create_dma_regions FAILED\n", - priv->netdev->name); - goto fail; - } - } - - MAC_COPY(priv->netdev->dev_addr, priv->dev_addr); - result = OK; - -fail: - if (result) - printk("acx: init_mac() FAILED\n"); - FN_EXIT1(result); - return result; -} - - -/*---------------------------------------------------------------- -* acx_l_rxmonitor -* Called from IRQ context only -*----------------------------------------------------------------*/ static void -acx_l_rxmonitor(wlandevice_t *priv, const rxbuffer_t *rxbuf) +acx_l_rxmonitor(acx_device_t *adev, const rxbuffer_t *rxbuf) { wlansniffrm_t *msg; struct sk_buff *skb; @@ -2235,39 +2323,40 @@ acx_l_rxmonitor(wlandevice_t *priv, cons /* we are in big luck: the acx100 doesn't modify any of the fields */ /* in the 802.11 frame. just pass this packet into the PF_PACKET */ /* subsystem. yeah. */ - payload_offset = ((u8*)acx_get_wlan_hdr(priv, rxbuf) - (u8*)rxbuf); + payload_offset = ((u8*)acx_get_wlan_hdr(adev, rxbuf) - (u8*)rxbuf); skb_len = RXBUF_BYTES_USED(rxbuf) - payload_offset; /* sanity check */ if (unlikely(skb_len > WLAN_A4FR_MAXLEN_WEP)) { printk("%s: monitor mode panic: oversized frame!\n", - priv->netdev->name); + adev->ndev->name); goto end; } - if (priv->netdev->type == ARPHRD_IEEE80211_PRISM) + if (adev->ndev->type == ARPHRD_IEEE80211_PRISM) skb_len += sizeof(*msg); /* allocate skb */ skb = dev_alloc_skb(skb_len); if (unlikely(!skb)) { printk("%s: no memory for skb (%u bytes)\n", - priv->netdev->name, skb_len); + adev->ndev->name, skb_len); goto end; } skb_put(skb, skb_len); + if (adev->ndev->type == ARPHRD_IEEE80211) { /* when in raw 802.11 mode, just copy frame as-is */ - if (priv->netdev->type == ARPHRD_IEEE80211) datap = skb->data; - else { /* otherwise, emulate prism header */ + } else if (adev->ndev->type == ARPHRD_IEEE80211_PRISM) { + /* emulate prism header */ msg = (wlansniffrm_t*)skb->data; datap = msg + 1; msg->msgcode = WLANSNIFFFRM; msg->msglen = sizeof(*msg); - strncpy(msg->devname, priv->netdev->name, sizeof(msg->devname)-1); + strncpy(msg->devname, adev->ndev->name, sizeof(msg->devname)-1); msg->devname[sizeof(msg->devname)-1] = '\0'; msg->hosttime.did = WLANSNIFFFRM_hosttime; @@ -2283,7 +2372,7 @@ acx_l_rxmonitor(wlandevice_t *priv, cons msg->channel.did = WLANSNIFFFRM_channel; msg->channel.status = WLANITEM_STATUS_data_ok; msg->channel.len = 4; - msg->channel.data = priv->channel; + msg->channel.data = adev->channel; msg->rssi.did = WLANSNIFFFRM_rssi; msg->rssi.status = WLANITEM_STATUS_no_value; @@ -2321,11 +2410,21 @@ acx_l_rxmonitor(wlandevice_t *priv, cons msg->frmlen.status = WLANITEM_STATUS_data_ok; msg->frmlen.len = 4; msg->frmlen.data = skb_len; + } else { + printk("acx: unsupported netdev type %d!\n", adev->ndev->type); + dev_kfree_skb(skb); + return; } + /* sanity check (keep it here) */ + if (unlikely((int)skb_len < 0)) { + printk("acx: skb_len=%d. Driver bug, please report\n", (int)skb_len); + dev_kfree_skb(skb); + return; + } memcpy(datap, ((unsigned char*)rxbuf)+payload_offset, skb_len); - skb->dev = priv->netdev; + skb->dev = adev->ndev; skb->dev->last_rx = jiffies; skb->mac.raw = skb->data; @@ -2334,8 +2433,9 @@ acx_l_rxmonitor(wlandevice_t *priv, cons skb->protocol = htons(ETH_P_80211_RAW); netif_rx(skb); - priv->stats.rx_packets++; - priv->stats.rx_bytes += skb->len; + adev->stats.rx_packets++; + adev->stats.rx_bytes += skb->len; + end: FN_EXIT0; } @@ -2359,35 +2459,35 @@ end: ** subtract a $smallint from dup_count in order to ** avoid "2 DUPs in 19 packets" messages */ static inline int -acx_l_handle_dup(wlandevice_t *priv, u16 seq) +acx_l_handle_dup(acx_device_t *adev, u16 seq) { - if (priv->dup_count) { - priv->nondup_count++; - if (time_after(jiffies, priv->dup_msg_expiry)) { + if (adev->dup_count) { + adev->nondup_count++; + if (time_after(jiffies, adev->dup_msg_expiry)) { /* Log only if more than 1 dup in 64 packets */ - if (priv->nondup_count/8 < priv->dup_count-5) { + if (adev->nondup_count/8 < adev->dup_count-5) { printk(KERN_INFO "%s: rx: %d DUPs in " "%d packets received in 10 secs\n", - priv->netdev->name, - priv->dup_count, - priv->nondup_count); + adev->ndev->name, + adev->dup_count, + adev->nondup_count); } - priv->dup_count = 0; - priv->nondup_count = 0; + adev->dup_count = 0; + adev->nondup_count = 0; } } - if (unlikely(seq == priv->last_seq_ctrl)) { - if (!priv->dup_count++) - priv->dup_msg_expiry = jiffies + 10*HZ; - priv->stats.rx_errors++; + if (unlikely(seq == adev->last_seq_ctrl)) { + if (!adev->dup_count++) + adev->dup_msg_expiry = jiffies + 10*HZ; + adev->stats.rx_errors++; return 1; /* a dup */ } - priv->last_seq_ctrl = seq; + adev->last_seq_ctrl = seq; return 0; } static int -acx_l_rx_ieee802_11_frame(wlandevice_t *priv, rxbuffer_t *rxbuf) +acx_l_rx_ieee802_11_frame(acx_device_t *adev, rxbuffer_t *rxbuf) { unsigned int ftype, fstype; const wlan_hdr_t *hdr; @@ -2395,7 +2495,7 @@ acx_l_rx_ieee802_11_frame(wlandevice_t * FN_ENTER; - hdr = acx_get_wlan_hdr(priv, rxbuf); + hdr = acx_get_wlan_hdr(adev, rxbuf); /* see IEEE 802.11-1999.pdf chapter 7 "MAC frame formats" */ if (unlikely((hdr->fc & WF_FC_PVERi) != 0)) { @@ -2411,23 +2511,23 @@ acx_l_rx_ieee802_11_frame(wlandevice_t * case WF_FTYPE_DATAi: switch (fstype) { case WF_FSTYPE_DATAONLYi: - if (acx_l_handle_dup(priv, hdr->seq)) + if (acx_l_handle_dup(adev, hdr->seq)) break; /* a dup, simply discard it */ /* TODO: if (WF_FC_FROMTODSi == (hdr->fc & WF_FC_FROMTODSi)) { - result = acx_l_process_data_frame_wds(priv, rxbuf); + result = acx_l_process_data_frame_wds(adev, rxbuf); break; } */ - switch (priv->mode) { + switch (adev->mode) { case ACX_MODE_3_AP: - result = acx_l_process_data_frame_master(priv, rxbuf); + result = acx_l_process_data_frame_master(adev, rxbuf); break; case ACX_MODE_0_ADHOC: case ACX_MODE_2_STA: - result = acx_l_process_data_frame_client(priv, rxbuf); + result = acx_l_process_data_frame_client(adev, rxbuf); break; } case WF_FSTYPE_DATA_CFACKi: @@ -2436,10 +2536,10 @@ acx_l_rx_ieee802_11_frame(wlandevice_t * case WF_FSTYPE_CFPOLLi: case WF_FSTYPE_CFACK_CFPOLLi: /* see above. - acx_process_class_frame(priv, rxbuf, 3); */ + acx_process_class_frame(adev, rxbuf, 3); */ break; case WF_FSTYPE_NULLi: - /* acx_l_process_NULL_frame(priv, rxbuf, 3); */ + /* acx_l_process_NULL_frame(adev, rxbuf, 3); */ break; /* FIXME: same here, see above */ case WF_FSTYPE_CFACKi: @@ -2448,7 +2548,7 @@ acx_l_rx_ieee802_11_frame(wlandevice_t * } break; case WF_FTYPE_MGMTi: - result = acx_l_process_mgmt_frame(priv, rxbuf); + result = acx_l_process_mgmt_frame(adev, rxbuf); break; case WF_FTYPE_CTLi: if (fstype == WF_FSTYPE_PSPOLLi) @@ -2456,7 +2556,7 @@ acx_l_rx_ieee802_11_frame(wlandevice_t * /* this call is irrelevant, since * acx_process_class_frame is a stub, so return * immediately instead. - * return acx_process_class_frame(priv, rxbuf, 3); */ + * return acx_process_class_frame(adev, rxbuf, 3); */ break; default: break; @@ -2473,17 +2573,17 @@ end: ** NB: used by USB code also */ void -acx_l_process_rxbuf(wlandevice_t *priv, rxbuffer_t *rxbuf) +acx_l_process_rxbuf(acx_device_t *adev, rxbuffer_t *rxbuf) { struct wlan_hdr *hdr; - unsigned int buf_len; unsigned int qual; + int buf_len; u16 fc; - hdr = acx_get_wlan_hdr(priv, rxbuf); - /* length of frame from control field to last byte of FCS */ + hdr = acx_get_wlan_hdr(adev, rxbuf); fc = le16_to_cpu(hdr->fc); - buf_len = RXBUF_BYTES_RCVD(rxbuf); + /* length of frame from control field to first byte of FCS */ + buf_len = RXBUF_BYTES_RCVD(adev, rxbuf); if ( ((WF_FC_FSTYPE & fc) != WF_FSTYPE_BEACON) || (acx_debug & L_XFER_BEACON) @@ -2499,7 +2599,7 @@ acx_l_process_rxbuf(wlandevice_t *priv, rxbuf->mac_status, rxbuf->phy_stat_baseband, rxbuf->phy_plcp_signal, - priv->status); + adev->status); } if (unlikely(acx_debug & L_DATA)) { @@ -2511,10 +2611,10 @@ acx_l_process_rxbuf(wlandevice_t *priv, * discard broken packets - but NOT for monitor!) * and update Rx packet statistics here */ - if (unlikely(priv->mode == ACX_MODE_MONITOR)) { - acx_l_rxmonitor(priv, rxbuf); + if (unlikely(adev->mode == ACX_MODE_MONITOR)) { + acx_l_rxmonitor(adev, rxbuf); } else if (likely(buf_len >= WLAN_HDR_A3_LEN)) { - acx_l_rx_ieee802_11_frame(priv, rxbuf); + acx_l_rx_ieee802_11_frame(adev, rxbuf); } else { log(L_DEBUG|L_XFER|L_DATA, "rx: NOT receiving packet (%s): " @@ -2535,20 +2635,20 @@ acx_l_process_rxbuf(wlandevice_t *priv, * address of the device that's managing our BSSID. * Disable it for now, since it removes information (levels * from different peers) and slows the Rx path. */ - if (priv->ap_client - && mac_is_equal(hdr->a2, priv->ap_client->address)) { + if (adev->ap_client + && mac_is_equal(hdr->a2, adev->ap_client->address)) { #endif - priv->wstats.qual.level = acx_signal_to_winlevel(rxbuf->phy_level); - priv->wstats.qual.noise = acx_signal_to_winlevel(rxbuf->phy_snr); + adev->wstats.qual.level = acx_signal_to_winlevel(rxbuf->phy_level); + adev->wstats.qual.noise = acx_signal_to_winlevel(rxbuf->phy_snr); #ifndef OLD_QUALITY - qual = acx_signal_determine_quality(priv->wstats.qual.level, - priv->wstats.qual.noise); + qual = acx_signal_determine_quality(adev->wstats.qual.level, + adev->wstats.qual.noise); #else - qual = (priv->wstats.qual.noise <= 100) ? - 100 - priv->wstats.qual.noise : 0; + qual = (adev->wstats.qual.noise <= 100) ? + 100 - adev->wstats.qual.noise : 0; #endif - priv->wstats.qual.qual = qual; - priv->wstats.qual.updated = 7; /* all 3 indicators updated */ + adev->wstats.qual.qual = qual; + adev->wstats.qual.updated = 7; /* all 3 indicators updated */ #ifdef FROM_SCAN_SOURCE_ONLY } #endif @@ -2602,7 +2702,7 @@ rate100to111(u8 r) void -acx_l_handle_txrate_auto(wlandevice_t *priv, struct client *txc, +acx_l_handle_txrate_auto(acx_device_t *adev, struct client *txc, u16 cur, u8 rate100, u16 rate111, u8 error, int pkts_to_ignore) { @@ -2626,7 +2726,7 @@ acx_l_handle_txrate_auto(wlandevice_t *p /* do some preparations, i.e. calculate the one rate that was * used to send this packet */ - if (IS_ACX111(priv)) { + if (IS_ACX111(adev)) { sent_rate = 1 << highest_bit(rate111 & RATE111_ALL); } else { sent_rate = rate100to111(rate100); @@ -2639,8 +2739,8 @@ acx_l_handle_txrate_auto(wlandevice_t *p "__=%u/%u ^^=%u/%u\n", (txc->ignore_count > 0) ? "[IGN] " : "", txc, MAC(txc->address), sent_rate, cur, txc->rate_cfg, - txc->fallback_count, priv->fallback_threshold, - txc->stepup_count, priv->stepup_threshold + txc->fallback_count, adev->fallback_threshold, + txc->stepup_count, adev->stepup_threshold ); /* we need to ignore old packets already in the tx queue since @@ -2658,7 +2758,7 @@ acx_l_handle_txrate_auto(wlandevice_t *p if (slower_rate_was_used || error) { txc->stepup_count = 0; - if (++txc->fallback_count <= priv->fallback_threshold) + if (++txc->fallback_count <= adev->fallback_threshold) return; txc->fallback_count = 0; @@ -2672,7 +2772,7 @@ acx_l_handle_txrate_auto(wlandevice_t *p } else { /* there was neither lower rate nor error */ txc->fallback_count = 0; - if (++txc->stepup_count <= priv->stepup_threshold) + if (++txc->stepup_count <= adev->stepup_threshold) return; txc->stepup_count = 0; @@ -2699,7 +2799,7 @@ acx_l_handle_txrate_auto(wlandevice_t *p txc->rate_cur = cur; txc->ignore_count = pkts_to_ignore; /* calculate acx100 style rate byte if needed */ - if (IS_ACX100(priv)) { + if (IS_ACX100(adev)) { txc->rate_100 = acx_bitpos2rate100[highest_bit(cur)]; } } @@ -2711,9 +2811,9 @@ acx_l_handle_txrate_auto(wlandevice_t *p ** Called by network core. Can be called outside of process context. */ int -acx_i_start_xmit(struct sk_buff *skb, netdevice_t *dev) +acx_i_start_xmit(struct sk_buff *skb, struct net_device *ndev) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); tx_t *tx; void *txbuf; unsigned long flags; @@ -2727,63 +2827,63 @@ acx_i_start_xmit(struct sk_buff *skb, ne txresult = OK; goto end_no_unlock; } - if (unlikely(!priv)) { + if (unlikely(!adev)) { goto end_no_unlock; } - acx_lock(priv, flags); + acx_lock(adev, flags); - if (unlikely(!(priv->dev_state_mask & ACX_STATE_IFACE_UP))) { + if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) { goto end; } - if (unlikely(priv->mode == ACX_MODE_OFF)) { + if (unlikely(adev->mode == ACX_MODE_OFF)) { goto end; } - if (unlikely(acx_queue_stopped(dev))) { + if (unlikely(acx_queue_stopped(ndev))) { log(L_DEBUG, "%s: called when queue stopped\n", __func__); goto end; } - if (unlikely(ACX_STATUS_4_ASSOCIATED != priv->status)) { + if (unlikely(ACX_STATUS_4_ASSOCIATED != adev->status)) { log(L_XFER, "trying to xmit, but not associated yet: " "aborting...\n"); /* silently drop the packet, since we're not connected yet */ txresult = OK; /* ...but indicate an error nevertheless */ - priv->stats.tx_errors++; + adev->stats.tx_errors++; goto end; } - tx = acx_l_alloc_tx(priv); + tx = acx_l_alloc_tx(adev); if (unlikely(!tx)) { printk_ratelimited("%s: start_xmit: txdesc ring is full, " - "dropping tx\n", dev->name); + "dropping tx\n", ndev->name); txresult = NOT_OK; goto end; } - txbuf = acx_l_get_txbuf(priv, tx); + txbuf = acx_l_get_txbuf(adev, tx); if (unlikely(!txbuf)) { /* Card was removed */ txresult = NOT_OK; - acx_l_dealloc_tx(priv, tx); + acx_l_dealloc_tx(adev, tx); goto end; } - len = acx_ether_to_txbuf(priv, txbuf, skb); + len = acx_ether_to_txbuf(adev, txbuf, skb); if (unlikely(len < 0)) { /* Error in packet conversion */ txresult = NOT_OK; - acx_l_dealloc_tx(priv, tx); + acx_l_dealloc_tx(adev, tx); goto end; } - acx_l_tx_data(priv, tx, len); - dev->trans_start = jiffies; + acx_l_tx_data(adev, tx, len); + ndev->trans_start = jiffies; txresult = OK; - priv->stats.tx_packets++; - priv->stats.tx_bytes += skb->len; + adev->stats.tx_packets++; + adev->stats.tx_bytes += skb->len; end: - acx_unlock(priv, flags); + acx_unlock(adev, flags); end_no_unlock: if ((txresult == OK) && skb) @@ -2797,7 +2897,7 @@ end_no_unlock: /*********************************************************************** ** acx_l_update_ratevector ** -** Updates priv->rate_supported[_len] according to rate_{basic,oper} +** Updates adev->rate_supported[_len] according to rate_{basic,oper} */ const u8 acx_bitpos2ratebyte[] = { @@ -2817,11 +2917,11 @@ acx_bitpos2ratebyte[] = { }; void -acx_l_update_ratevector(wlandevice_t *priv) +acx_l_update_ratevector(acx_device_t *adev) { - u16 bcfg = priv->rate_basic; - u16 ocfg = priv->rate_oper; - u8 *supp = priv->rate_supported; + u16 bcfg = adev->rate_basic; + u16 ocfg = adev->rate_oper; + u8 *supp = adev->rate_supported; const u8 *dot11 = acx_bitpos2ratebyte; FN_ENTER; @@ -2838,47 +2938,47 @@ acx_l_update_ratevector(wlandevice_t *pr ocfg >>= 1; bcfg >>= 1; } - priv->rate_supported_len = supp - priv->rate_supported; + adev->rate_supported_len = supp - adev->rate_supported; if (acx_debug & L_ASSOC) { printk("new ratevector: "); - acx_dump_bytes(priv->rate_supported, priv->rate_supported_len); + acx_dump_bytes(adev->rate_supported, adev->rate_supported_len); } FN_EXIT0; } -/*---------------------------------------------------------------- -* acx_l_sta_list_init -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_sta_list_init +*/ static void -acx_l_sta_list_init(wlandevice_t *priv) +acx_l_sta_list_init(acx_device_t *adev) { FN_ENTER; - memset(priv->sta_hash_tab, 0, sizeof(priv->sta_hash_tab)); - memset(priv->sta_list, 0, sizeof(priv->sta_list)); + memset(adev->sta_hash_tab, 0, sizeof(adev->sta_hash_tab)); + memset(adev->sta_list, 0, sizeof(adev->sta_list)); FN_EXIT0; } -/*---------------------------------------------------------------- -* acx_l_sta_list_get_from_hash -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_sta_list_get_from_hash +*/ static inline client_t* -acx_l_sta_list_get_from_hash(wlandevice_t *priv, const u8 *address) +acx_l_sta_list_get_from_hash(acx_device_t *adev, const u8 *address) { - return priv->sta_hash_tab[address[5] % VEC_SIZE(priv->sta_hash_tab)]; + return adev->sta_hash_tab[address[5] % VEC_SIZE(adev->sta_hash_tab)]; } -/*---------------------------------------------------------------- -* acx_l_sta_list_get -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_sta_list_get +*/ client_t* -acx_l_sta_list_get(wlandevice_t *priv, const u8 *address) +acx_l_sta_list_get(acx_device_t *adev, const u8 *address) { client_t *client; FN_ENTER; - client = acx_l_sta_list_get_from_hash(priv, address); + client = acx_l_sta_list_get_from_hash(adev, address); while (client) { if (mac_is_equal(address, client->address)) { client->mtime = jiffies; @@ -2891,15 +2991,15 @@ acx_l_sta_list_get(wlandevice_t *priv, c } -/*---------------------------------------------------------------- -* acx_l_sta_list_del -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_sta_list_del +*/ void -acx_l_sta_list_del(wlandevice_t *priv, client_t *victim) +acx_l_sta_list_del(acx_device_t *adev, client_t *victim) { client_t *client, *next; - client = acx_l_sta_list_get_from_hash(priv, victim->address); + client = acx_l_sta_list_get_from_hash(adev, victim->address); next = client; /* tricky. next = client on first iteration only, ** on all other iters next = client->next */ @@ -2916,13 +3016,13 @@ acx_l_sta_list_del(wlandevice_t *priv, c } -/*---------------------------------------------------------------- -* acx_l_sta_list_alloc -* -* Never fails - will evict oldest client if needed -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_sta_list_alloc +** +** Never fails - will evict oldest client if needed +*/ static client_t* -acx_l_sta_list_alloc(wlandevice_t *priv) +acx_l_sta_list_alloc(acx_device_t *adev) { int i; unsigned long age, oldest_age; @@ -2930,10 +3030,10 @@ acx_l_sta_list_alloc(wlandevice_t *priv) FN_ENTER; - oldest = &priv->sta_list[0]; + oldest = &adev->sta_list[0]; oldest_age = 0; - for (i = 0; i < VEC_SIZE(priv->sta_list); i++) { - client = &priv->sta_list[i]; + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + client = &adev->sta_list[i]; if (!client->used) { goto found; @@ -2945,7 +3045,7 @@ acx_l_sta_list_alloc(wlandevice_t *priv) } } } - acx_l_sta_list_del(priv, oldest); + acx_l_sta_list_del(adev, oldest); client = oldest; found: memset(client, 0, sizeof(*client)); @@ -2954,23 +3054,23 @@ found: } -/*---------------------------------------------------------------- -* acx_l_sta_list_add -* -* Never fails - will evict oldest client if needed -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_sta_list_add +** +** Never fails - will evict oldest client if needed +*/ /* In case we will reimplement it differently... */ #define STA_LIST_ADD_CAN_FAIL 0 static client_t* -acx_l_sta_list_add(wlandevice_t *priv, const u8 *address) +acx_l_sta_list_add(acx_device_t *adev, const u8 *address) { client_t *client; int index; FN_ENTER; - client = acx_l_sta_list_alloc(priv); + client = acx_l_sta_list_alloc(adev); client->mtime = jiffies; MAC_COPY(client->address, address); @@ -2981,13 +3081,13 @@ acx_l_sta_list_add(wlandevice_t *priv, c ** (needed because peer may do auth without probing us first, ** thus we'll have no idea of peer's ratevector yet). ** Will be overwritten by scanning or assoc code */ - client->rate_cap = priv->rate_basic; - client->rate_cfg = priv->rate_basic; - client->rate_cur = 1 << lowest_bit(priv->rate_basic); - - index = address[5] % VEC_SIZE(priv->sta_hash_tab); - client->next = priv->sta_hash_tab[index]; - priv->sta_hash_tab[index] = client; + client->rate_cap = adev->rate_basic; + client->rate_cfg = adev->rate_basic; + client->rate_cur = 1 << lowest_bit(adev->rate_basic); + + index = address[5] % VEC_SIZE(adev->sta_hash_tab); + client->next = adev->sta_hash_tab[index]; + adev->sta_hash_tab[index] = client; acxlog_mac(L_ASSOC, "sta_list_add: sta=", address, "\n"); @@ -2996,17 +3096,17 @@ acx_l_sta_list_add(wlandevice_t *priv, c } -/*---------------------------------------------------------------- -* acx_l_sta_list_get_or_add -* -* Never fails - will evict oldest client if needed -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_sta_list_get_or_add +** +** Never fails - will evict oldest client if needed +*/ static client_t* -acx_l_sta_list_get_or_add(wlandevice_t *priv, const u8 *address) +acx_l_sta_list_get_or_add(acx_device_t *adev, const u8 *address) { - client_t *client = acx_l_sta_list_get(priv, address); + client_t *client = acx_l_sta_list_get(adev, address); if (!client) - client = acx_l_sta_list_add(priv, address); + client = acx_l_sta_list_add(adev, address); return client; } @@ -3021,52 +3121,50 @@ acx_l_sta_list_get_or_add(wlandevice_t * ** wake queue. This can race with stop_queue elsewhere. ** See acx_stop_queue comment. */ void -acx_set_status(wlandevice_t *priv, u16 new_status) +acx_set_status(acx_device_t *adev, u16 new_status) { #define QUEUE_OPEN_AFTER_ASSOC 1 /* this really seems to be needed now */ - u16 old_status = priv->status; + u16 old_status = adev->status; FN_ENTER; log(L_ASSOC, "%s(%d):%s\n", __func__, new_status, acx_get_status_name(new_status)); -#if WIRELESS_EXT > 13 /* wireless_send_event() and SIOCGIWSCAN */ /* wireless_send_event never sleeps */ if (ACX_STATUS_4_ASSOCIATED == new_status) { union iwreq_data wrqu; wrqu.data.length = 0; wrqu.data.flags = 0; - wireless_send_event(priv->netdev, SIOCGIWSCAN, &wrqu, NULL); + wireless_send_event(adev->ndev, SIOCGIWSCAN, &wrqu, NULL); wrqu.data.length = 0; wrqu.data.flags = 0; - MAC_COPY(wrqu.ap_addr.sa_data, priv->bssid); + MAC_COPY(wrqu.ap_addr.sa_data, adev->bssid); wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(priv->netdev, SIOCGIWAP, &wrqu, NULL); + wireless_send_event(adev->ndev, SIOCGIWAP, &wrqu, NULL); } else { union iwreq_data wrqu; /* send event with empty BSSID to indicate we're not associated */ MAC_ZERO(wrqu.ap_addr.sa_data); wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(priv->netdev, SIOCGIWAP, &wrqu, NULL); + wireless_send_event(adev->ndev, SIOCGIWAP, &wrqu, NULL); } -#endif - priv->status = new_status; + adev->status = new_status; switch (new_status) { case ACX_STATUS_1_SCANNING: - priv->scan_retries = 0; + adev->scan_retries = 0; /* 1.0 s initial scan time */ - acx_set_timer(priv, 1000000); + acx_set_timer(adev, 1000000); break; case ACX_STATUS_2_WAIT_AUTH: case ACX_STATUS_3_AUTHENTICATED: - priv->auth_or_assoc_retries = 0; - acx_set_timer(priv, 1500000); /* 1.5 s */ + adev->auth_or_assoc_retries = 0; + acx_set_timer(adev, 1500000); /* 1.5 s */ break; } @@ -3075,14 +3173,14 @@ acx_set_status(wlandevice_t *priv, u16 n if (old_status < ACX_STATUS_4_ASSOCIATED) { /* ah, we're newly associated now, * so let's indicate carrier */ - acx_carrier_on(priv->netdev, "after association"); - acx_wake_queue(priv->netdev, "after association"); + acx_carrier_on(adev->ndev, "after association"); + acx_wake_queue(adev->ndev, "after association"); } } else { /* not associated any more, so let's kill carrier */ if (old_status >= ACX_STATUS_4_ASSOCIATED) { - acx_carrier_off(priv->netdev, "after losing association"); - acx_stop_queue(priv->netdev, "after losing association"); + acx_carrier_off(adev->ndev, "after losing association"); + acx_stop_queue(adev->ndev, "after losing association"); } } #endif @@ -3090,105 +3188,105 @@ acx_set_status(wlandevice_t *priv, u16 n } -/*------------------------------------------------------------------------------ - * acx_i_timer - * - * Fires up periodically. Used to kick scan/auth/assoc if something goes wrong - *----------------------------------------------------------------------------*/ +/*********************************************************************** +** acx_i_timer +** +** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong +*/ void acx_i_timer(unsigned long address) { unsigned long flags; - wlandevice_t *priv = (wlandevice_t *)address; + acx_device_t *adev = (acx_device_t*)address; FN_ENTER; - acx_lock(priv, flags); + acx_lock(adev, flags); - log(L_DEBUG|L_ASSOC, "%s: priv->status=%d (%s)\n", - __func__, priv->status, acx_get_status_name(priv->status)); + log(L_DEBUG|L_ASSOC, "%s: adev->status=%d (%s)\n", + __func__, adev->status, acx_get_status_name(adev->status)); - switch (priv->status) { + switch (adev->status) { case ACX_STATUS_1_SCANNING: /* was set to 0 by set_status() */ - if (++priv->scan_retries < 7) { - acx_set_timer(priv, 1000000); + if (++adev->scan_retries < 7) { + acx_set_timer(adev, 1000000); /* used to interrogate for scan status. ** We rely on SCAN_COMPLETE IRQ instead */ log(L_ASSOC, "continuing scan (%d sec)\n", - priv->scan_retries); + adev->scan_retries); } else { log(L_ASSOC, "stopping scan\n"); /* send stop_scan cmd when we leave the interrupt context, * and make a decision what to do next (COMPLETE_SCAN) */ - acx_schedule_task(priv, + acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_STOP_SCAN + ACX_AFTER_IRQ_COMPLETE_SCAN); } break; case ACX_STATUS_2_WAIT_AUTH: /* was set to 0 by set_status() */ - if (++priv->auth_or_assoc_retries < 10) { + if (++adev->auth_or_assoc_retries < 10) { log(L_ASSOC, "resend authen1 request (attempt %d)\n", - priv->auth_or_assoc_retries + 1); - acx_l_transmit_authen1(priv); + adev->auth_or_assoc_retries + 1); + acx_l_transmit_authen1(adev); } else { /* time exceeded: fall back to scanning mode */ log(L_ASSOC, "authen1 request reply timeout, giving up\n"); /* we are a STA, need to find AP anyhow */ - acx_set_status(priv, ACX_STATUS_1_SCANNING); - acx_schedule_task(priv, ACX_AFTER_IRQ_RESTART_SCAN); + acx_set_status(adev, ACX_STATUS_1_SCANNING); + acx_schedule_task(adev, ACX_AFTER_IRQ_RESTART_SCAN); } /* used to be 1500000, but some other driver uses 2.5s */ - acx_set_timer(priv, 2500000); + acx_set_timer(adev, 2500000); break; case ACX_STATUS_3_AUTHENTICATED: /* was set to 0 by set_status() */ - if (++priv->auth_or_assoc_retries < 10) { + if (++adev->auth_or_assoc_retries < 10) { log(L_ASSOC, "resend assoc request (attempt %d)\n", - priv->auth_or_assoc_retries + 1); - acx_l_transmit_assoc_req(priv); + adev->auth_or_assoc_retries + 1); + acx_l_transmit_assoc_req(adev); } else { /* time exceeded: give up */ log(L_ASSOC, "association request reply timeout, giving up\n"); /* we are a STA, need to find AP anyhow */ - acx_set_status(priv, ACX_STATUS_1_SCANNING); - acx_schedule_task(priv, ACX_AFTER_IRQ_RESTART_SCAN); + acx_set_status(adev, ACX_STATUS_1_SCANNING); + acx_schedule_task(adev, ACX_AFTER_IRQ_RESTART_SCAN); } - acx_set_timer(priv, 2500000); /* see above */ + acx_set_timer(adev, 2500000); /* see above */ break; case ACX_STATUS_4_ASSOCIATED: default: break; } - acx_unlock(priv, flags); + acx_unlock(adev, flags); FN_EXIT0; } -/*------------------------------------------------------------------------------ - * acx_set_timer - * - * Sets the 802.11 state management timer's timeout. - *----------------------------------------------------------------------------*/ +/*********************************************************************** +** acx_set_timer +** +** Sets the 802.11 state management timer's timeout. +*/ void -acx_set_timer(wlandevice_t *priv, int timeout_us) +acx_set_timer(acx_device_t *adev, int timeout_us) { FN_ENTER; log(L_DEBUG|L_IRQ, "%s(%u ms)\n", __func__, timeout_us/1000); - if (!(priv->dev_state_mask & ACX_STATE_IFACE_UP)) { + if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) { printk("attempt to set the timer " "when the card interface is not up!\n"); goto end; } /* first check if the timer was already initialized, THEN modify it */ - if (priv->mgmt_timer.function) { - mod_timer(&priv->mgmt_timer, + if (adev->mgmt_timer.function) { + mod_timer(&adev->mgmt_timer, jiffies + (timeout_us * HZ / 1000000)); } end: @@ -3196,11 +3294,11 @@ end: } -/*---------------------------------------------------------------- -* acx_l_transmit_assocresp -* -* We are an AP here -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_transmit_assocresp +** +** We are an AP here +*/ static const u8 dot11ratebyte[] = { DOT11RATEBYTE_1, @@ -3243,7 +3341,7 @@ add_bits_to_ratemasks(u8* ratevec, int l } static int -acx_l_transmit_assocresp(wlandevice_t *priv, const wlan_fr_assocreq_t *req) +acx_l_transmit_assocresp(acx_device_t *adev, const wlan_fr_assocreq_t *req) { struct tx *tx; struct wlan_hdr_mgmt *head; @@ -3260,7 +3358,7 @@ acx_l_transmit_assocresp(wlandevice_t *p da = req->hdr->a2; bssid = req->hdr->a3; - clt = acx_l_sta_list_get(priv, da); + clt = acx_l_sta_list_get(adev, da); if (!clt) goto ok; @@ -3269,14 +3367,14 @@ acx_l_transmit_assocresp(wlandevice_t *p ** we won't be rude */ if (clt->used != CLIENT_AUTHENTICATED_2 && clt->used != CLIENT_ASSOCIATED_3) { - acx_l_transmit_deauthen(priv, da, WLAN_MGMT_REASON_CLASS2_NONAUTH); + acx_l_transmit_deauthen(adev, da, WLAN_MGMT_REASON_CLASS2_NONAUTH); goto bad; } clt->used = CLIENT_ASSOCIATED_3; if (clt->aid == 0) - clt->aid = ++priv->aid; + clt->aid = ++adev->aid; clt->cap_info = ieee2host16(*(req->cap_info)); /* We cheat here a bit. We don't really care which rates are flagged @@ -3290,20 +3388,20 @@ acx_l_transmit_assocresp(wlandevice_t *p req->ext_rates->len, &clt->rate_cap, &clt->rate_cap); /* We can check that client supports all basic rates, ** and deny assoc if not. But let's be liberal, right? ;) */ - clt->rate_cfg = clt->rate_cap & priv->rate_oper; - if (!clt->rate_cfg) clt->rate_cfg = 1 << lowest_bit(priv->rate_oper); + clt->rate_cfg = clt->rate_cap & adev->rate_oper; + if (!clt->rate_cfg) clt->rate_cfg = 1 << lowest_bit(adev->rate_oper); clt->rate_cur = 1 << lowest_bit(clt->rate_cfg); - if (IS_ACX100(priv)) + if (IS_ACX100(adev)) clt->rate_100 = acx_bitpos2rate100[lowest_bit(clt->rate_cfg)]; clt->fallback_count = clt->stepup_count = 0; clt->ignore_count = 16; - tx = acx_l_alloc_tx(priv); + tx = acx_l_alloc_tx(adev); if (!tx) goto bad; - head = acx_l_get_txbuf(priv, tx); + head = acx_l_get_txbuf(adev, tx); if (!head) { - acx_l_dealloc_tx(priv, tx); + acx_l_dealloc_tx(adev, tx); goto bad; } body = (void*)(head + 1); @@ -3311,19 +3409,19 @@ acx_l_transmit_assocresp(wlandevice_t *p head->fc = WF_FSTYPE_ASSOCRESPi; head->dur = req->hdr->dur; MAC_COPY(head->da, da); - MAC_COPY(head->sa, priv->dev_addr); + MAC_COPY(head->sa, adev->dev_addr); MAC_COPY(head->bssid, bssid); head->seq = req->hdr->seq; - body->cap_info = host2ieee16(priv->capabilities); + body->cap_info = host2ieee16(adev->capabilities); body->status = host2ieee16(0); body->aid = host2ieee16(clt->aid); - p = wlan_fill_ie_rates((u8*)&body->rates, priv->rate_supported_len, - priv->rate_supported); - p = wlan_fill_ie_rates_ext(p, priv->rate_supported_len, - priv->rate_supported); + p = wlan_fill_ie_rates((u8*)&body->rates, adev->rate_supported_len, + adev->rate_supported); + p = wlan_fill_ie_rates_ext(p, adev->rate_supported_len, + adev->rate_supported); - acx_l_tx_data(priv, tx, p - (u8*)head); + acx_l_tx_data(adev, tx, p - (u8*)head); ok: FN_EXIT1(OK); return OK; @@ -3333,10 +3431,10 @@ bad: } -/*---------------------------------------------------------------- +/*********************************************************************** * acx_l_transmit_reassocresp -You may be wondering, just like me, what a hell is ReAuth. +You may be wondering, just like me, what the hell ReAuth is. In practice it was seen sent by STA when STA feels like losing connection. [802.11] @@ -3425,9 +3523,9 @@ Order Information 3 Association ID (AID) 4 Supported rates -*----------------------------------------------------------------*/ +*/ static int -acx_l_transmit_reassocresp(wlandevice_t *priv, const wlan_fr_reassocreq_t *req) +acx_l_transmit_reassocresp(acx_device_t *adev, const wlan_fr_reassocreq_t *req) { struct tx *tx; struct wlan_hdr_mgmt *head; @@ -3445,7 +3543,7 @@ acx_l_transmit_reassocresp(wlandevice_t bssid = req->hdr->a3; /* Must be already authenticated, so it must be in the list */ - clt = acx_l_sta_list_get(priv, da); + clt = acx_l_sta_list_get(adev, da); if (!clt) goto ok; @@ -3453,13 +3551,13 @@ acx_l_transmit_reassocresp(wlandevice_t /* Already assoc'ed STAs sending ReAssoc req are ok per 802.11 */ if (clt->used != CLIENT_AUTHENTICATED_2 && clt->used != CLIENT_ASSOCIATED_3) { - acx_l_transmit_deauthen(priv, da, WLAN_MGMT_REASON_CLASS2_NONAUTH); + acx_l_transmit_deauthen(adev, da, WLAN_MGMT_REASON_CLASS2_NONAUTH); goto bad; } clt->used = CLIENT_ASSOCIATED_3; if (clt->aid == 0) { - clt->aid = ++priv->aid; + clt->aid = ++adev->aid; } if (req->cap_info) clt->cap_info = ieee2host16(*(req->cap_info)); @@ -3475,21 +3573,21 @@ acx_l_transmit_reassocresp(wlandevice_t req->ext_rates->len, &clt->rate_cap, &clt->rate_cap); /* We can check that client supports all basic rates, ** and deny assoc if not. But let's be liberal, right? ;) */ - clt->rate_cfg = clt->rate_cap & priv->rate_oper; - if (!clt->rate_cfg) clt->rate_cfg = 1 << lowest_bit(priv->rate_oper); + clt->rate_cfg = clt->rate_cap & adev->rate_oper; + if (!clt->rate_cfg) clt->rate_cfg = 1 << lowest_bit(adev->rate_oper); clt->rate_cur = 1 << lowest_bit(clt->rate_cfg); - if (IS_ACX100(priv)) + if (IS_ACX100(adev)) clt->rate_100 = acx_bitpos2rate100[lowest_bit(clt->rate_cfg)]; clt->fallback_count = clt->stepup_count = 0; clt->ignore_count = 16; - tx = acx_l_alloc_tx(priv); + tx = acx_l_alloc_tx(adev); if (!tx) goto ok; - head = acx_l_get_txbuf(priv, tx); + head = acx_l_get_txbuf(adev, tx); if (!head) { - acx_l_dealloc_tx(priv, tx); + acx_l_dealloc_tx(adev, tx); goto ok; } body = (void*)(head + 1); @@ -3497,24 +3595,24 @@ acx_l_transmit_reassocresp(wlandevice_t head->fc = WF_FSTYPE_REASSOCRESPi; head->dur = req->hdr->dur; MAC_COPY(head->da, da); - MAC_COPY(head->sa, priv->dev_addr); + MAC_COPY(head->sa, adev->dev_addr); MAC_COPY(head->bssid, bssid); head->seq = req->hdr->seq; /* IEs: 1. caps */ - body->cap_info = host2ieee16(priv->capabilities); + body->cap_info = host2ieee16(adev->capabilities); /* 2. status code */ body->status = host2ieee16(0); /* 3. AID */ body->aid = host2ieee16(clt->aid); /* 4. supp rates */ - p = wlan_fill_ie_rates((u8*)&body->rates, priv->rate_supported_len, - priv->rate_supported); + p = wlan_fill_ie_rates((u8*)&body->rates, adev->rate_supported_len, + adev->rate_supported); /* 5. ext supp rates */ - p = wlan_fill_ie_rates_ext(p, priv->rate_supported_len, - priv->rate_supported); + p = wlan_fill_ie_rates_ext(p, adev->rate_supported_len, + adev->rate_supported); - acx_l_tx_data(priv, tx, p - (u8*)head); + acx_l_tx_data(adev, tx, p - (u8*)head); ok: FN_EXIT1(OK); return OK; @@ -3524,11 +3622,11 @@ bad: } -/*---------------------------------------------------------------- -* acx_l_process_disassoc_from_sta -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_process_disassoc_from_sta +*/ static void -acx_l_process_disassoc_from_sta(wlandevice_t *priv, const wlan_fr_disassoc_t *req) +acx_l_process_disassoc_from_sta(acx_device_t *adev, const wlan_fr_disassoc_t *req) { const u8 *ta; client_t *clt; @@ -3536,7 +3634,7 @@ acx_l_process_disassoc_from_sta(wlandevi FN_ENTER; ta = req->hdr->a2; - clt = acx_l_sta_list_get(priv, ta); + clt = acx_l_sta_list_get(adev, ta); if (!clt) goto end; @@ -3546,7 +3644,7 @@ acx_l_process_disassoc_from_sta(wlandevi ** not even authenticated! Let it know that */ acxlog_mac(L_ASSOC|L_XFER, "peer ", ta, "has sent disassoc " "req but it is not even auth'ed! sending deauth\n"); - acx_l_transmit_deauthen(priv, ta, + acx_l_transmit_deauthen(adev, ta, WLAN_MGMT_REASON_CLASS2_NONAUTH); clt->used = CLIENT_EXIST_1; } else { @@ -3558,11 +3656,11 @@ end: } -/*---------------------------------------------------------------- -* acx_l_process_deauthen_from_sta -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_process_deauthen_from_sta +*/ static void -acx_l_process_deauth_from_sta(wlandevice_t *priv, const wlan_fr_deauthen_t *req) +acx_l_process_deauth_from_sta(acx_device_t *adev, const wlan_fr_deauthen_t *req) { const wlan_hdr_t *hdr; client_t *client; @@ -3572,20 +3670,18 @@ acx_l_process_deauth_from_sta(wlandevice hdr = req->hdr; if (acx_debug & L_ASSOC) { - acx_print_mac("DEAUTHEN priv->addr=", priv->dev_addr, " "); - acx_print_mac("a1", hdr->a1, " "); - acx_print_mac("a2", hdr->a2, " "); - acx_print_mac("a3", hdr->a3, " "); - acx_print_mac("priv->bssid", priv->bssid, "\n"); + acx_print_mac("got deauth from sta:", hdr->a2, " "); + acx_print_mac("a1:", hdr->a1, " "); + acx_print_mac("a3:", hdr->a3, " "); + acx_print_mac("adev->addr:", adev->dev_addr, " "); + acx_print_mac("adev->bssid:", adev->bssid, "\n"); } - if (!mac_is_equal(priv->dev_addr, hdr->a1)) { + if (!mac_is_equal(adev->dev_addr, hdr->a1)) { goto end; } - acxlog_mac(L_DEBUG, "STA ", hdr->a2, " sent us deauthen packet\n"); - - client = acx_l_sta_list_get(priv, hdr->a2); + client = acx_l_sta_list_get(adev, hdr->a2); if (!client) { goto end; } @@ -3595,95 +3691,91 @@ end: } -/*---------------------------------------------------------------- -* acx_l_process_disassoc_from_ap -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_process_disassoc_from_ap +*/ static void -acx_l_process_disassoc_from_ap(wlandevice_t *priv, const wlan_fr_disassoc_t *req) +acx_l_process_disassoc_from_ap(acx_device_t *adev, const wlan_fr_disassoc_t *req) { FN_ENTER; - if (!priv->ap_client) { + if (!adev->ap_client) { /* Hrm, we aren't assoc'ed yet anyhow... */ goto end; } printk("%s: got disassoc frame with reason %d (%s)\n", - priv->netdev->name, *req->reason, + adev->ndev->name, *req->reason, acx_wlan_reason_str(*req->reason)); - if (mac_is_equal(priv->dev_addr, req->hdr->a1)) { - acx_l_transmit_deauthen(priv, priv->bssid, + if (mac_is_equal(adev->dev_addr, req->hdr->a1)) { + acx_l_transmit_deauthen(adev, adev->bssid, WLAN_MGMT_REASON_DEAUTH_LEAVING); - SET_BIT(priv->set_mask, GETSET_RESCAN); - acx_schedule_task(priv, ACX_AFTER_IRQ_UPDATE_CARD_CFG); + SET_BIT(adev->set_mask, GETSET_RESCAN); + acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG); } end: FN_EXIT0; } -/*---------------------------------------------------------------- -* acx_l_process_deauth_from_ap -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_process_deauth_from_ap +*/ static void -acx_l_process_deauth_from_ap(wlandevice_t *priv, const wlan_fr_deauthen_t *req) +acx_l_process_deauth_from_ap(acx_device_t *adev, const wlan_fr_deauthen_t *req) { FN_ENTER; - if (!priv->ap_client) { + if (!adev->ap_client) { /* Hrm, we aren't assoc'ed yet anyhow... */ goto end; } printk("%s: got deauth frame with reason %d (%s)\n", - priv->netdev->name, *req->reason, + adev->ndev->name, *req->reason, acx_wlan_reason_str(*req->reason)); - /* Chk: is ta is verified to be from our AP? */ - if (mac_is_equal(priv->dev_addr, req->hdr->a1)) { + /* Chk: is ta verified to be from our AP? */ + if (mac_is_equal(adev->dev_addr, req->hdr->a1)) { log(L_DEBUG, "AP sent us deauth packet\n"); - SET_BIT(priv->set_mask, GETSET_RESCAN); - acx_schedule_task(priv, ACX_AFTER_IRQ_UPDATE_CARD_CFG); + SET_BIT(adev->set_mask, GETSET_RESCAN); + acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG); } end: FN_EXIT0; } -/*------------------------------------------------------------------------------ - * acx_l_rx - * - * The end of the Rx path. Pulls data from a rxhostdesc into a socket - * buffer and feeds it to the network stack via netif_rx(). - * - * Arguments: - * rxdesc: the rxhostdesc to pull the data from - * priv: the acx100 private struct of the interface - *----------------------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_rx +** +** The end of the Rx path. Pulls data from a rxhostdesc into a socket +** buffer and feeds it to the network stack via netif_rx(). +*/ static void -acx_l_rx(wlandevice_t *priv, rxbuffer_t *rxbuf) +acx_l_rx(acx_device_t *adev, rxbuffer_t *rxbuf) { FN_ENTER; - if (likely(priv->dev_state_mask & ACX_STATE_IFACE_UP)) { + if (likely(adev->dev_state_mask & ACX_STATE_IFACE_UP)) { struct sk_buff *skb; - skb = acx_rxbuf_to_ether(priv, rxbuf); + skb = acx_rxbuf_to_ether(adev, rxbuf); if (likely(skb)) { netif_rx(skb); - priv->netdev->last_rx = jiffies; - priv->stats.rx_packets++; - priv->stats.rx_bytes += skb->len; + adev->ndev->last_rx = jiffies; + adev->stats.rx_packets++; + adev->stats.rx_bytes += skb->len; } } FN_EXIT0; } -/*---------------------------------------------------------------- -* acx_l_process_data_frame_master -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_process_data_frame_master +*/ static int -acx_l_process_data_frame_master(wlandevice_t *priv, rxbuffer_t *rxbuf) +acx_l_process_data_frame_master(acx_device_t *adev, rxbuffer_t *rxbuf) { struct wlan_hdr *hdr; struct tx *tx; @@ -3693,7 +3785,7 @@ acx_l_process_data_frame_master(wlandevi FN_ENTER; - hdr = acx_get_wlan_hdr(priv, rxbuf); + hdr = acx_get_wlan_hdr(adev, rxbuf); switch (WF_FC_FROMTODSi & hdr->fc) { case 0: @@ -3703,24 +3795,24 @@ acx_l_process_data_frame_master(wlandevi case WF_FC_TODSi: break; default: /* WF_FC_FROMTODSi */ - log(L_DEBUG, "wds data frame ignored (todo)\n"); + log(L_DEBUG, "wds data frame ignored (TODO)\n"); goto done; } /* check if it is our BSSID, if not, leave */ - if (!mac_is_equal(priv->bssid, hdr->a1)) { + if (!mac_is_equal(adev->bssid, hdr->a1)) { goto done; } - if (mac_is_equal(priv->dev_addr, hdr->a3)) { + if (mac_is_equal(adev->dev_addr, hdr->a3)) { /* this one is for us */ - acx_l_rx(priv, rxbuf); + acx_l_rx(adev, rxbuf); } else { if (mac_is_bcast(hdr->a3)) { /* this one is bcast, rx it too */ - acx_l_rx(priv, rxbuf); + acx_l_rx(adev, rxbuf); } - tx = acx_l_alloc_tx(priv); + tx = acx_l_alloc_tx(adev); if (!tx) { goto fail; } @@ -3728,17 +3820,17 @@ acx_l_process_data_frame_master(wlandevi /* order is important, we do it in-place */ MAC_COPY(hdr->a1, hdr->a3); MAC_COPY(hdr->a3, hdr->a2); - MAC_COPY(hdr->a2, priv->bssid); + MAC_COPY(hdr->a2, adev->bssid); /* To_DS = 0, From_DS = 1 */ hdr->fc = WF_FC_FROMDSi + WF_FTYPE_DATAi; - len = RXBUF_BYTES_RCVD(rxbuf); - txbuf = acx_l_get_txbuf(priv, tx); + txbuf = acx_l_get_txbuf(adev, tx); if (txbuf) { - memcpy(txbuf, &rxbuf->hdr_a3, len); - acx_l_tx_data(priv, tx, len); + len = RXBUF_BYTES_RCVD(adev, rxbuf); + memcpy(txbuf, hdr, len); + acx_l_tx_data(adev, tx, len); } else { - acx_l_dealloc_tx(priv, tx); + acx_l_dealloc_tx(adev, tx); } } done: @@ -3749,34 +3841,34 @@ fail: } -/*---------------------------------------------------------------- -* acx_l_process_data_frame_client -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_process_data_frame_client +*/ static int -acx_l_process_data_frame_client(wlandevice_t *priv, rxbuffer_t *rxbuf) +acx_l_process_data_frame_client(acx_device_t *adev, rxbuffer_t *rxbuf) { const u8 *da, *bssid; const wlan_hdr_t *hdr; - netdevice_t *dev = priv->netdev; + struct net_device *ndev = adev->ndev; int result = NOT_OK; FN_ENTER; - if (ACX_STATUS_4_ASSOCIATED != priv->status) + if (ACX_STATUS_4_ASSOCIATED != adev->status) goto drop; - hdr = acx_get_wlan_hdr(priv, rxbuf); + hdr = acx_get_wlan_hdr(adev, rxbuf); switch (WF_FC_FROMTODSi & hdr->fc) { case 0: - if (priv->mode != ACX_MODE_0_ADHOC) { + if (adev->mode != ACX_MODE_0_ADHOC) { log(L_DEBUG, "adhoc->adhoc data frame ignored\n"); goto drop; } bssid = hdr->a3; break; case WF_FC_FROMDSi: - if (priv->mode != ACX_MODE_2_STA) { + if (adev->mode != ACX_MODE_2_STA) { log(L_DEBUG, "ap->sta data frame ignored\n"); goto drop; } @@ -3795,22 +3887,22 @@ acx_l_process_data_frame_client(wlandevi if (unlikely(acx_debug & L_DEBUG)) { acx_print_mac("rx: da=", da, ""); acx_print_mac(" bssid=", bssid, ""); - acx_print_mac(" priv->bssid=", priv->bssid, ""); - acx_print_mac(" priv->addr=", priv->dev_addr, "\n"); + acx_print_mac(" adev->bssid=", adev->bssid, ""); + acx_print_mac(" adev->addr=", adev->dev_addr, "\n"); } /* promiscuous mode --> receive all packets */ - if (unlikely(dev->flags & IFF_PROMISC)) + if (unlikely(ndev->flags & IFF_PROMISC)) goto process; /* FIRST, check if it is our BSSID */ - if (!mac_is_equal(priv->bssid, bssid)) { + if (!mac_is_equal(adev->bssid, bssid)) { /* is not our BSSID, so bail out */ goto drop; } /* then, check if it is our address */ - if (mac_is_equal(priv->dev_addr, da)) { + if (mac_is_equal(adev->dev_addr, da)) { goto process; } @@ -3821,10 +3913,10 @@ acx_l_process_data_frame_client(wlandevi if (mac_is_mcast(da)) { /* unconditionally receive all multicasts */ - if (dev->flags & IFF_ALLMULTI) + if (ndev->flags & IFF_ALLMULTI) goto process; - /* FIXME: check against the list of + /* FIXME: need to check against the list of * multicast addresses that are configured * for the interface (ifconfig) */ log(L_XFER, "FIXME: multicast packet, need to check " @@ -3838,7 +3930,7 @@ acx_l_process_data_frame_client(wlandevi goto drop; process: /* receive packet */ - acx_l_rx(priv, rxbuf); + acx_l_rx(adev, rxbuf); result = OK; drop: @@ -3847,14 +3939,13 @@ drop: } -/*---------------------------------------------------------------- -* acx_l_process_mgmt_frame -* -* Theory of operation: mgmt packet gets parsed (to make it easy -* to access variable-sized IEs), results stored in 'parsed'. -* Then we react to the packet. -* NB: wlan_mgmt_decode_XXX are dev-independent (shoudnt have been named acx_XXX) -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_process_mgmt_frame +** +** Theory of operation: mgmt packet gets parsed (to make it easy +** to access variable-sized IEs), results stored in 'parsed'. +** Then we react to the packet. +*/ typedef union parsed_mgmt_req { wlan_fr_mgmt_t mgmt; wlan_fr_assocreq_t assocreq; @@ -3871,7 +3962,7 @@ typedef union parsed_mgmt_req { void BUG_excessive_stack_usage(void); static int -acx_l_process_mgmt_frame(wlandevice_t *priv, rxbuffer_t *rxbuf) +acx_l_process_mgmt_frame(acx_device_t *adev, rxbuffer_t *rxbuf) { parsed_mgmt_req_t parsed; /* takes ~100 bytes of stack */ wlan_hdr_t *hdr; @@ -3883,7 +3974,7 @@ acx_l_process_mgmt_frame(wlandevice_t *p FN_ENTER; - hdr = acx_get_wlan_hdr(priv, rxbuf); + hdr = acx_get_wlan_hdr(adev, rxbuf); /* Management frames never have these set */ if (WF_FC_FROMTODSi & hdr->fc) { @@ -3891,16 +3982,16 @@ acx_l_process_mgmt_frame(wlandevice_t *p return NOT_OK; } - len = RXBUF_BYTES_RCVD(rxbuf); + len = RXBUF_BYTES_RCVD(adev, rxbuf); if (WF_FC_ISWEPi & hdr->fc) len -= 0x10; - adhoc = (priv->mode == ACX_MODE_0_ADHOC); - sta_scan = ((priv->mode == ACX_MODE_2_STA) - && (priv->status != ACX_STATUS_4_ASSOCIATED)); - sta = ((priv->mode == ACX_MODE_2_STA) - && (priv->status == ACX_STATUS_4_ASSOCIATED)); - ap = (priv->mode == ACX_MODE_3_AP); + adhoc = (adev->mode == ACX_MODE_0_ADHOC); + sta_scan = ((adev->mode == ACX_MODE_2_STA) + && (adev->status != ACX_STATUS_4_ASSOCIATED)); + sta = ((adev->mode == ACX_MODE_2_STA) + && (adev->status == ACX_STATUS_4_ASSOCIATED)); + ap = (adev->mode == ACX_MODE_3_AP); switch (WF_FC_FSTYPEi & hdr->fc) { /* beacons first, for speed */ @@ -3917,7 +4008,7 @@ acx_l_process_mgmt_frame(wlandevice_t *p } wlan_mgmt_decode_beacon(&parsed.beacon); /* beacon and probe response are very similar, so... */ - acx_l_process_probe_response(priv, &parsed.beacon, rxbuf); + acx_l_process_probe_response(adev, &parsed.beacon, rxbuf); break; case WF_FSTYPE_ASSOCREQi: if (!ap) @@ -3926,9 +4017,9 @@ acx_l_process_mgmt_frame(wlandevice_t *p parsed.assocreq.hdr = hdr; parsed.assocreq.len = len; wlan_mgmt_decode_assocreq(&parsed.assocreq); - if (mac_is_equal(hdr->a1, priv->bssid) - && mac_is_equal(hdr->a3, priv->bssid)) { - acx_l_transmit_assocresp(priv, &parsed.assocreq); + if (mac_is_equal(hdr->a1, adev->bssid) + && mac_is_equal(hdr->a3, adev->bssid)) { + acx_l_transmit_assocresp(adev, &parsed.assocreq); } break; case WF_FSTYPE_REASSOCREQi: @@ -3939,7 +4030,7 @@ acx_l_process_mgmt_frame(wlandevice_t *p parsed.assocreq.len = len; wlan_mgmt_decode_assocreq(&parsed.assocreq); /* reassocreq and assocreq are equivalent */ - acx_l_transmit_reassocresp(priv, &parsed.reassocreq); + acx_l_transmit_reassocresp(adev, &parsed.reassocreq); break; case WF_FSTYPE_ASSOCRESPi: if (!sta_scan) @@ -3948,7 +4039,7 @@ acx_l_process_mgmt_frame(wlandevice_t *p parsed.assocresp.hdr = hdr; parsed.assocresp.len = len; wlan_mgmt_decode_assocresp(&parsed.assocresp); - acx_l_process_assocresp(priv, &parsed.assocresp); + acx_l_process_assocresp(adev, &parsed.assocresp); break; case WF_FSTYPE_REASSOCRESPi: if (!sta_scan) @@ -3957,7 +4048,7 @@ acx_l_process_mgmt_frame(wlandevice_t *p parsed.assocresp.hdr = hdr; parsed.assocresp.len = len; wlan_mgmt_decode_assocresp(&parsed.assocresp); - acx_l_process_reassocresp(priv, &parsed.reassocresp); + acx_l_process_reassocresp(adev, &parsed.reassocresp); break; case WF_FSTYPE_PROBEREQi: if (ap || adhoc) { @@ -3972,7 +4063,7 @@ acx_l_process_mgmt_frame(wlandevice_t *p parsed.proberesp.hdr = hdr; parsed.proberesp.len = len; wlan_mgmt_decode_proberesp(&parsed.proberesp); - acx_l_process_probe_response(priv, &parsed.proberesp, rxbuf); + acx_l_process_probe_response(adev, &parsed.proberesp, rxbuf); break; case 6: case 7: @@ -3989,9 +4080,9 @@ acx_l_process_mgmt_frame(wlandevice_t *p parsed.disassoc.len = len; wlan_mgmt_decode_disassoc(&parsed.disassoc); if (sta) - acx_l_process_disassoc_from_ap(priv, &parsed.disassoc); + acx_l_process_disassoc_from_ap(adev, &parsed.disassoc); else - acx_l_process_disassoc_from_sta(priv, &parsed.disassoc); + acx_l_process_disassoc_from_sta(adev, &parsed.disassoc); break; case WF_FSTYPE_AUTHENi: if (!sta_scan && !ap) @@ -4000,7 +4091,7 @@ acx_l_process_mgmt_frame(wlandevice_t *p parsed.authen.hdr = hdr; parsed.authen.len = len; wlan_mgmt_decode_authen(&parsed.authen); - acx_l_process_authen(priv, &parsed.authen); + acx_l_process_authen(adev, &parsed.authen); break; case WF_FSTYPE_DEAUTHENi: if (!sta && !ap) @@ -4010,9 +4101,9 @@ acx_l_process_mgmt_frame(wlandevice_t *p parsed.deauthen.len = len; wlan_mgmt_decode_deauthen(&parsed.deauthen); if (sta) - acx_l_process_deauth_from_ap(priv, &parsed.deauthen); + acx_l_process_deauth_from_ap(adev, &parsed.deauthen); else - acx_l_process_deauth_from_sta(priv, &parsed.deauthen); + acx_l_process_deauth_from_sta(adev, &parsed.deauthen); break; } @@ -4022,25 +4113,25 @@ acx_l_process_mgmt_frame(wlandevice_t *p #ifdef UNUSED -/*---------------------------------------------------------------- -* acx_process_class_frame -* -* Called from IRQ context only -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_process_class_frame +** +** Called from IRQ context only +*/ static int -acx_process_class_frame(wlandevice_t *priv, rxbuffer_t *rxbuf, int vala) +acx_process_class_frame(acx_device_t *adev, rxbuffer_t *rxbuf, int vala) { return OK; } #endif -/*---------------------------------------------------------------- -* acx_l_process_NULL_frame -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_process_NULL_frame +*/ #ifdef BOGUS_ITS_NOT_A_NULL_FRAME_HANDLER_AT_ALL static int -acx_l_process_NULL_frame(wlandevice_t *priv, rxbuffer_t *rxbuf, int vala) +acx_l_process_NULL_frame(acx_device_t *adev, rxbuffer_t *rxbuf, int vala) { const signed char *esi; const u8 *ebx; @@ -4048,7 +4139,7 @@ acx_l_process_NULL_frame(wlandevice_t *p const client_t *client; int result = NOT_OK; - hdr = acx_get_wlan_hdr(priv, rxbuf); + hdr = acx_get_wlan_hdr(adev, rxbuf); switch (WF_FC_FROMTODSi & hdr->fc) { case 0: @@ -4073,13 +4164,13 @@ acx_l_process_NULL_frame(wlandevice_t *p goto done; } - client = acx_l_sta_list_get(priv, ebx); + client = acx_l_sta_list_get(adev, ebx); if (client) result = NOT_OK; else { #ifdef IS_IT_BROKEN log(L_DEBUG|L_XFER, "\n"); - acx_l_transmit_deauthen(priv, ebx, + acx_l_transmit_deauthen(adev, ebx, WLAN_MGMT_REASON_CLASS2_NONAUTH); #else log(L_DEBUG, "received NULL frame from unknown client! " @@ -4093,11 +4184,11 @@ done: #endif -/*---------------------------------------------------------------- -* acx_l_process_probe_response -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_process_probe_response +*/ static int -acx_l_process_probe_response(wlandevice_t *priv, wlan_fr_proberesp_t *req, +acx_l_process_probe_response(acx_device_t *adev, wlan_fr_proberesp_t *req, const rxbuffer_t *rxbuf) { struct client *bss; @@ -4107,23 +4198,23 @@ acx_l_process_probe_response(wlandevice_ hdr = req->hdr; - if (mac_is_equal(hdr->a3, priv->dev_addr)) { + if (mac_is_equal(hdr->a3, adev->dev_addr)) { log(L_ASSOC, "huh, scan found our own MAC!?\n"); goto ok; /* just skip this one silently */ } - bss = acx_l_sta_list_get_or_add(priv, hdr->a2); + bss = acx_l_sta_list_get_or_add(adev, hdr->a2); /* NB: be careful modifying bss data! It may be one - ** of already known clients (like our AP is we are a STA) + ** of the already known clients (like our AP if we are a STA) ** Thus do not blindly modify e.g. current ratemask! */ if (STA_LIST_ADD_CAN_FAIL && !bss) { /* uh oh, we found more sites/stations than we can handle with * our current setup: pull the emergency brake and stop scanning! */ - acx_schedule_task(priv, ACX_AFTER_IRQ_CMD_STOP_SCAN); + acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_STOP_SCAN); /* TODO: a nice comment what below call achieves --vda */ - acx_set_status(priv, ACX_STATUS_2_WAIT_AUTH); + acx_set_status(adev, ACX_STATUS_2_WAIT_AUTH); goto ok; } /* NB: get_or_add already filled bss->address = hdr->a2 */ @@ -4137,7 +4228,7 @@ acx_l_process_probe_response(wlandevice_ } else { /* Either no ESSID IE or oversized one */ printk("%s: received packet has bogus ESSID\n", - priv->netdev->name); + adev->ndev->name); } if (req->ds_parms) @@ -4159,7 +4250,7 @@ acx_l_process_probe_response(wlandevice_ /* Fix up any possible bogosity - code elsewhere * is not expecting empty masks */ if (!bss->rate_cap) - bss->rate_cap = priv->rate_basic; + bss->rate_cap = adev->rate_basic; if (!bss->rate_bas) bss->rate_bas = 1 << lowest_bit(bss->rate_cap); if (!bss->rate_cur) @@ -4178,26 +4269,27 @@ ok: } -/*---------------------------------------------------------------- -* acx_l_process_assocresp -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_process_assocresp +*/ static int -acx_l_process_assocresp(wlandevice_t *priv, const wlan_fr_assocresp_t *req) +acx_l_process_assocresp(acx_device_t *adev, const wlan_fr_assocresp_t *req) { const wlan_hdr_t *hdr; int res = OK; FN_ENTER; + hdr = req->hdr; - if ((ACX_MODE_2_STA == priv->mode) - && mac_is_equal(priv->dev_addr, hdr->a1)) { + if ((ACX_MODE_2_STA == adev->mode) + && mac_is_equal(adev->dev_addr, hdr->a1)) { u16 st = ieee2host16(*(req->status)); if (WLAN_MGMT_STATUS_SUCCESS == st) { - priv->aid = ieee2host16(*(req->aid)); + adev->aid = ieee2host16(*(req->aid)); /* tell the card we are associated when ** we are out of interrupt context */ - acx_schedule_task(priv, ACX_AFTER_IRQ_CMD_ASSOCIATE); + acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_ASSOCIATE); } else { /* TODO: we shall delete peer from sta_list, and try @@ -4205,7 +4297,7 @@ acx_l_process_assocresp(wlandevice_t *pr printk("%s: association FAILED: peer sent " "response code %d (%s)\n", - priv->netdev->name, st, get_status_string(st)); + adev->ndev->name, st, get_status_string(st)); res = NOT_OK; } } @@ -4215,30 +4307,31 @@ acx_l_process_assocresp(wlandevice_t *pr } -/*---------------------------------------------------------------- -* acx_l_process_reassocresp -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_process_reassocresp +*/ static int -acx_l_process_reassocresp(wlandevice_t *priv, const wlan_fr_reassocresp_t *req) +acx_l_process_reassocresp(acx_device_t *adev, const wlan_fr_reassocresp_t *req) { const wlan_hdr_t *hdr; int result = NOT_OK; u16 st; FN_ENTER; + hdr = req->hdr; - if (!mac_is_equal(priv->dev_addr, hdr->a1)) { + if (!mac_is_equal(adev->dev_addr, hdr->a1)) { goto end; } st = ieee2host16(*(req->status)); if (st == WLAN_MGMT_STATUS_SUCCESS) { - acx_set_status(priv, ACX_STATUS_4_ASSOCIATED); + acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); result = OK; } else { printk("%s: reassociation FAILED: peer sent " "response code %d (%s)\n", - priv->netdev->name, st, get_status_string(st)); + adev->ndev->name, st, get_status_string(st)); } end: FN_EXIT1(result); @@ -4246,13 +4339,13 @@ end: } -/*---------------------------------------------------------------- -* acx_l_process_authen -* -* Called only in STA_SCAN or AP mode -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_process_authen +** +** Called only in STA_SCAN or AP mode +*/ static int -acx_l_process_authen(wlandevice_t *priv, const wlan_fr_authen_t *req) +acx_l_process_authen(acx_device_t *adev, const wlan_fr_authen_t *req) { const wlan_hdr_t *hdr; client_t *clt; @@ -4265,15 +4358,15 @@ acx_l_process_authen(wlandevice_t *priv, hdr = req->hdr; if (acx_debug & L_ASSOC) { - acx_print_mac("AUTHEN priv->addr=", priv->dev_addr, " "); + acx_print_mac("AUTHEN adev->addr=", adev->dev_addr, " "); acx_print_mac("a1=", hdr->a1, " "); acx_print_mac("a2=", hdr->a2, " "); acx_print_mac("a3=", hdr->a3, " "); - acx_print_mac("priv->bssid=", priv->bssid, "\n"); + acx_print_mac("adev->bssid=", adev->bssid, "\n"); } - if (!mac_is_equal(priv->dev_addr, hdr->a1) - || !mac_is_equal(priv->bssid, hdr->a3)) { + if (!mac_is_equal(adev->dev_addr, hdr->a1) + || !mac_is_equal(adev->bssid, hdr->a3)) { result = OK; goto end; } @@ -4282,12 +4375,12 @@ acx_l_process_authen(wlandevice_t *priv, seq = ieee2host16(*(req->auth_seq)); status = ieee2host16(*(req->status)); - ap = (priv->mode == ACX_MODE_3_AP); + ap = (adev->mode == ACX_MODE_3_AP); - if (priv->auth_alg <= 1) { - if (priv->auth_alg != alg) { + if (adev->auth_alg <= 1) { + if (adev->auth_alg != alg) { log(L_ASSOC, "auth algorithm mismatch: " - "our:%d peer:%d\n", priv->auth_alg, alg); + "our:%d peer:%d\n", adev->auth_alg, alg); result = NOT_OK; goto end; } @@ -4295,17 +4388,17 @@ acx_l_process_authen(wlandevice_t *priv, log(L_ASSOC, "algorithm is ok\n"); if (ap) { - clt = acx_l_sta_list_get_or_add(priv, hdr->a2); + clt = acx_l_sta_list_get_or_add(adev, hdr->a2); if (STA_LIST_ADD_CAN_FAIL && !clt) { log(L_ASSOC, "could not allocate room for client\n"); result = NOT_OK; goto end; } } else { - clt = priv->ap_client; + clt = adev->ap_client; if (!mac_is_equal(clt->address, hdr->a2)) { printk("%s: malformed auth frame from AP?!\n", - priv->netdev->name); + adev->ndev->name); result = NOT_OK; goto end; } @@ -4318,26 +4411,26 @@ acx_l_process_authen(wlandevice_t *priv, case 1: if (!ap) break; - acx_l_transmit_authen2(priv, req, clt); + acx_l_transmit_authen2(adev, req, clt); break; case 2: if (ap) break; if (status == WLAN_MGMT_STATUS_SUCCESS) { if (alg == WLAN_AUTH_ALG_OPENSYSTEM) { - acx_set_status(priv, ACX_STATUS_3_AUTHENTICATED); - acx_l_transmit_assoc_req(priv); + acx_set_status(adev, ACX_STATUS_3_AUTHENTICATED); + acx_l_transmit_assoc_req(adev); } else if (alg == WLAN_AUTH_ALG_SHAREDKEY) { - acx_l_transmit_authen3(priv, req); + acx_l_transmit_authen3(adev, req); } } else { printk("%s: auth FAILED: peer sent " "response code %d (%s), " "still waiting for authentication\n", - priv->netdev->name, + adev->ndev->name, status, get_status_string(status)); - acx_set_status(priv, ACX_STATUS_2_WAIT_AUTH); + acx_set_status(adev, ACX_STATUS_2_WAIT_AUTH); } break; case 3: @@ -4354,7 +4447,7 @@ acx_l_process_authen(wlandevice_t *priv, || (chal->len != WLAN_CHALLENGE_LEN) ) break; - acx_l_transmit_authen4(priv, req); + acx_l_transmit_authen4(adev, req); MAC_COPY(clt->address, hdr->a2); clt->used = CLIENT_AUTHENTICATED_2; clt->auth_step = 4; @@ -4364,10 +4457,10 @@ acx_l_process_authen(wlandevice_t *priv, if (ap) break; /* ok, we're through: we're authenticated. Woohoo!! */ - acx_set_status(priv, ACX_STATUS_3_AUTHENTICATED); + acx_set_status(adev, ACX_STATUS_3_AUTHENTICATED); log(L_ASSOC, "Authenticated!\n"); /* now that we're authenticated, request association */ - acx_l_transmit_assoc_req(priv); + acx_l_transmit_assoc_req(adev); break; } result = NOT_OK; @@ -4377,10 +4470,10 @@ end: } -/*---------------------------------------------------------------- -* acx_gen_challenge -*----------------------------------------------------------------*/ -static void +/*********************************************************************** +** acx_gen_challenge +*/ +static inline void acx_gen_challenge(wlan_ie_challenge_t* d) { FN_ENTER; @@ -4391,11 +4484,11 @@ acx_gen_challenge(wlan_ie_challenge_t* d } -/*---------------------------------------------------------------- -* acx_l_transmit_deauthen -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_transmit_deauthen +*/ static int -acx_l_transmit_deauthen(wlandevice_t *priv, const u8 *addr, u16 reason) +acx_l_transmit_deauthen(acx_device_t *adev, const u8 *addr, u16 reason) { struct tx *tx; struct wlan_hdr_mgmt *head; @@ -4403,12 +4496,12 @@ acx_l_transmit_deauthen(wlandevice_t *pr FN_ENTER; - tx = acx_l_alloc_tx(priv); + tx = acx_l_alloc_tx(adev); if (!tx) goto bad; - head = acx_l_get_txbuf(priv, tx); + head = acx_l_get_txbuf(adev, tx); if (!head) { - acx_l_dealloc_tx(priv, tx); + acx_l_dealloc_tx(adev, tx); goto bad; } body = (void*)(head + 1); @@ -4416,8 +4509,8 @@ acx_l_transmit_deauthen(wlandevice_t *pr head->fc = (WF_FTYPE_MGMTi | WF_FSTYPE_DEAUTHENi); head->dur = 0; MAC_COPY(head->da, addr); - MAC_COPY(head->sa, priv->dev_addr); - MAC_COPY(head->bssid, priv->bssid); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, adev->bssid); head->seq = 0; log(L_DEBUG|L_ASSOC|L_XFER, @@ -4428,7 +4521,7 @@ acx_l_transmit_deauthen(wlandevice_t *pr /* body is fixed size here, but beware of cutting-and-pasting this - ** do not use sizeof(*body) for variable sized mgmt packets! */ - acx_l_tx_data(priv, tx, WLAN_HDR_A3_LEN + sizeof(*body)); + acx_l_tx_data(adev, tx, WLAN_HDR_A3_LEN + sizeof(*body)); FN_EXIT1(OK); return OK; @@ -4438,11 +4531,11 @@ bad: } -/*---------------------------------------------------------------- -* acx_l_transmit_authen1 -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_transmit_authen1 +*/ static int -acx_l_transmit_authen1(wlandevice_t *priv) +acx_l_transmit_authen1(acx_device_t *adev) { struct tx *tx; struct wlan_hdr_mgmt *head; @@ -4453,28 +4546,28 @@ acx_l_transmit_authen1(wlandevice_t *pri log(L_ASSOC, "sending authentication1 request, " "awaiting response\n"); - tx = acx_l_alloc_tx(priv); + tx = acx_l_alloc_tx(adev); if (!tx) goto bad; - head = acx_l_get_txbuf(priv, tx); + head = acx_l_get_txbuf(adev, tx); if (!head) { - acx_l_dealloc_tx(priv, tx); + acx_l_dealloc_tx(adev, tx); goto bad; } body = (void*)(head + 1); head->fc = WF_FSTYPE_AUTHENi; head->dur = host2ieee16(0x8000); - MAC_COPY(head->da, priv->bssid); - MAC_COPY(head->sa, priv->dev_addr); - MAC_COPY(head->bssid, priv->bssid); + MAC_COPY(head->da, adev->bssid); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, adev->bssid); head->seq = 0; - body->auth_alg = host2ieee16(priv->auth_alg); + body->auth_alg = host2ieee16(adev->auth_alg); body->auth_seq = host2ieee16(1); body->status = host2ieee16(0); - acx_l_tx_data(priv, tx, WLAN_HDR_A3_LEN + 2 + 2 + 2); + acx_l_tx_data(adev, tx, WLAN_HDR_A3_LEN + 2 + 2 + 2); FN_EXIT1(OK); return OK; @@ -4484,11 +4577,11 @@ bad: } -/*---------------------------------------------------------------- -* acx_l_transmit_authen2 -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_transmit_authen2 +*/ static int -acx_l_transmit_authen2(wlandevice_t *priv, const wlan_fr_authen_t *req, +acx_l_transmit_authen2(acx_device_t *adev, const wlan_fr_authen_t *req, client_t *clt) { struct tx *tx; @@ -4509,12 +4602,12 @@ acx_l_transmit_authen2(wlandevice_t *pri clt->auth_step = 2; clt->seq = ieee2host16(req->hdr->seq); - tx = acx_l_alloc_tx(priv); + tx = acx_l_alloc_tx(adev); if (!tx) goto bad; - head = acx_l_get_txbuf(priv, tx); + head = acx_l_get_txbuf(adev, tx); if (!head) { - acx_l_dealloc_tx(priv, tx); + acx_l_dealloc_tx(adev, tx); goto bad; } body = (void*)(head + 1); @@ -4522,7 +4615,7 @@ acx_l_transmit_authen2(wlandevice_t *pri head->fc = WF_FSTYPE_AUTHENi; head->dur = req->hdr->dur; MAC_COPY(head->da, req->hdr->a2); - MAC_COPY(head->sa, priv->dev_addr); + MAC_COPY(head->sa, adev->dev_addr); MAC_COPY(head->bssid, req->hdr->a3); head->seq = req->hdr->seq; @@ -4543,7 +4636,7 @@ acx_l_transmit_authen2(wlandevice_t *pri acxlog_mac(L_ASSOC|L_XFER, "transmit_auth2: BSSID=", head->bssid, "\n"); - acx_l_tx_data(priv, tx, packet_len); + acx_l_tx_data(adev, tx, packet_len); ok: FN_EXIT1(OK); return OK; @@ -4553,11 +4646,11 @@ bad: } -/*---------------------------------------------------------------- -* acx_l_transmit_authen3 -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_transmit_authen3 +*/ static int -acx_l_transmit_authen3(wlandevice_t *priv, const wlan_fr_authen_t *req) +acx_l_transmit_authen3(acx_device_t *adev, const wlan_fr_authen_t *req) { struct tx *tx; struct wlan_hdr_mgmt *head; @@ -4566,12 +4659,12 @@ acx_l_transmit_authen3(wlandevice_t *pri FN_ENTER; - tx = acx_l_alloc_tx(priv); + tx = acx_l_alloc_tx(adev); if (!tx) goto ok; - head = acx_l_get_txbuf(priv, tx); + head = acx_l_get_txbuf(adev, tx); if (!head) { - acx_l_dealloc_tx(priv, tx); + acx_l_dealloc_tx(adev, tx); goto ok; } body = (void*)(head + 1); @@ -4581,9 +4674,9 @@ acx_l_transmit_authen3(wlandevice_t *pri head->dur = req->hdr->dur; head->seq = req->hdr->seq; */ - MAC_COPY(head->da, priv->bssid); - MAC_COPY(head->sa, priv->dev_addr); - MAC_COPY(head->bssid, priv->bssid); + MAC_COPY(head->da, adev->bssid); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, adev->bssid); /* already in IEEE format, no endianness conversion */ body->auth_alg = *(req->auth_alg); @@ -4594,18 +4687,18 @@ acx_l_transmit_authen3(wlandevice_t *pri log(L_ASSOC|L_XFER, "transmit_authen3!\n"); - acx_l_tx_data(priv, tx, packet_len); + acx_l_tx_data(adev, tx, packet_len); ok: FN_EXIT1(OK); return OK; } -/*---------------------------------------------------------------- -* acx_l_transmit_authen4 -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_transmit_authen4 +*/ static int -acx_l_transmit_authen4(wlandevice_t *priv, const wlan_fr_authen_t *req) +acx_l_transmit_authen4(acx_device_t *adev, const wlan_fr_authen_t *req) { struct tx *tx; struct wlan_hdr_mgmt *head; @@ -4613,12 +4706,12 @@ acx_l_transmit_authen4(wlandevice_t *pri FN_ENTER; - tx = acx_l_alloc_tx(priv); + tx = acx_l_alloc_tx(adev); if (!tx) goto ok; - head = acx_l_get_txbuf(priv, tx); + head = acx_l_get_txbuf(adev, tx); if (!head) { - acx_l_dealloc_tx(priv, tx); + acx_l_dealloc_tx(adev, tx); goto ok; } body = (void*)(head + 1); @@ -4626,7 +4719,7 @@ acx_l_transmit_authen4(wlandevice_t *pri head->fc = WF_FSTYPE_AUTHENi; /* 0xb0 */ head->dur = req->hdr->dur; MAC_COPY(head->da, req->hdr->a2); - MAC_COPY(head->sa, priv->dev_addr); + MAC_COPY(head->sa, adev->dev_addr); MAC_COPY(head->bssid, req->hdr->a3); head->seq = req->hdr->seq; @@ -4635,20 +4728,20 @@ acx_l_transmit_authen4(wlandevice_t *pri body->auth_seq = host2ieee16(4); body->status = host2ieee16(0); - acx_l_tx_data(priv, tx, WLAN_HDR_A3_LEN + 2 + 2 + 2); + acx_l_tx_data(adev, tx, WLAN_HDR_A3_LEN + 2 + 2 + 2); ok: FN_EXIT1(OK); return OK; } -/*---------------------------------------------------------------- -* acx_l_transmit_assoc_req -* -* priv->ap_client is a current candidate AP here -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_transmit_assoc_req +** +** adev->ap_client is a current candidate AP here +*/ static int -acx_l_transmit_assoc_req(wlandevice_t *priv) +acx_l_transmit_assoc_req(acx_device_t *adev) { struct tx *tx; struct wlan_hdr_mgmt *head; @@ -4660,21 +4753,21 @@ acx_l_transmit_assoc_req(wlandevice_t *p log(L_ASSOC, "sending association request, " "awaiting response. NOT ASSOCIATED YET\n"); - tx = acx_l_alloc_tx(priv); + tx = acx_l_alloc_tx(adev); if (!tx) goto bad; - head = acx_l_get_txbuf(priv, tx); + head = acx_l_get_txbuf(adev, tx); if (!head) { - acx_l_dealloc_tx(priv, tx); + acx_l_dealloc_tx(adev, tx); goto bad; } body = (void*)(head + 1); head->fc = WF_FSTYPE_ASSOCREQi; head->dur = host2ieee16(0x8000); - MAC_COPY(head->da, priv->bssid); - MAC_COPY(head->sa, priv->dev_addr); - MAC_COPY(head->bssid, priv->bssid); + MAC_COPY(head->da, adev->bssid); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, adev->bssid); head->seq = 0; p = body; @@ -4706,32 +4799,32 @@ acx_l_transmit_assoc_req(wlandevice_t *p /* this one used to be a check on wep_restricted, * but more likely it's wep_enabled instead */ - if (priv->wep_enabled) + if (adev->wep_enabled) SET_BIT(cap, WF_MGMT_CAP_PRIVACYi); /* Probably we can just set these always, because our hw is ** capable of shortpre and PBCC --vda */ /* only ask for short preamble if the peer station supports it */ - if (priv->ap_client->cap_info & WF_MGMT_CAP_SHORT) + if (adev->ap_client->cap_info & WF_MGMT_CAP_SHORT) SET_BIT(cap, WF_MGMT_CAP_SHORTi); /* only ask for PBCC support if the peer station supports it */ - if (priv->ap_client->cap_info & WF_MGMT_CAP_PBCC) + if (adev->ap_client->cap_info & WF_MGMT_CAP_PBCC) SET_BIT(cap, WF_MGMT_CAP_PBCCi); /* IEs: 1. caps */ *(u16*)p = cap; p += 2; /* 2. listen interval */ - *(u16*)p = host2ieee16(priv->listen_interval); p += 2; + *(u16*)p = host2ieee16(adev->listen_interval); p += 2; /* 3. ESSID */ p = wlan_fill_ie_ssid(p, - strlen(priv->essid_for_assoc), priv->essid_for_assoc); + strlen(adev->essid_for_assoc), adev->essid_for_assoc); /* 4. supp rates */ prate = p; p = wlan_fill_ie_rates(p, - priv->rate_supported_len, priv->rate_supported); + adev->rate_supported_len, adev->rate_supported); /* 5. ext supp rates */ p = wlan_fill_ie_rates_ext(p, - priv->rate_supported_len, priv->rate_supported); + adev->rate_supported_len, adev->rate_supported); if (acx_debug & L_DEBUG) { printk("association: rates element\n"); @@ -4742,9 +4835,9 @@ acx_l_transmit_assoc_req(wlandevice_t *p packet_len = WLAN_HDR_A3_LEN + (p - body); log(L_ASSOC, "association: requesting caps 0x%04X, ESSID '%s'\n", - cap, priv->essid_for_assoc); + cap, adev->essid_for_assoc); - acx_l_tx_data(priv, tx, packet_len); + acx_l_tx_data(adev, tx, packet_len); FN_EXIT1(OK); return OK; bad: @@ -4753,16 +4846,16 @@ bad: } -/*---------------------------------------------------------------- -* acx_l_transmit_disassoc -* -* FIXME: looks like incomplete implementation of a helper: -* acx_l_transmit_disassoc(priv, clt) - kick this client (we're an AP) -* acx_l_transmit_disassoc(priv, NULL) - leave BSSID (we're a STA) -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_l_transmit_disassoc +** +** FIXME: looks like incomplete implementation of a helper: +** acx_l_transmit_disassoc(adev, clt) - kick this client (we're an AP) +** acx_l_transmit_disassoc(adev, NULL) - leave BSSID (we're a STA) +*/ #ifdef BROKEN int -acx_l_transmit_disassoc(wlandevice_t *priv, client_t *clt) +acx_l_transmit_disassoc(acx_device_t *adev, client_t *clt) { struct tx *tx; struct wlan_hdr_mgmt *head; @@ -4770,12 +4863,12 @@ acx_l_transmit_disassoc(wlandevice_t *pr FN_ENTER; /* if (clt != NULL) { */ - tx = acx_l_alloc_tx(priv); + tx = acx_l_alloc_tx(adev); if (!tx) goto bad; - head = acx_l_get_txbuf(priv, tx); + head = acx_l_get_txbuf(adev, tx); if (!head) { - acx_l_dealloc_tx(priv, tx); + acx_l_dealloc_tx(adev, tx); goto bad; } body = (void*)(head + 1); @@ -4787,16 +4880,16 @@ acx_l_transmit_disassoc(wlandevice_t *pr /* huh? It muchly depends on whether we're STA or AP... ** sta->ap: da=bssid, sa=own, bssid=bssid ** ap->sta: da=sta, sa=bssid, bssid=bssid. FIXME! */ - MAC_COPY(head->da, priv->bssid); - MAC_COPY(head->sa, priv->dev_addr); - MAC_COPY(head->bssid, priv->dev_addr); + MAC_COPY(head->da, adev->bssid); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, adev->dev_addr); head->seq = 0; /* "Class 3 frame received from nonassociated station." */ body->reason = host2ieee16(7); /* fixed size struct, ok to sizeof */ - acx_l_tx_data(priv, tx, WLAN_HDR_A3_LEN + sizeof(*body)); + acx_l_tx_data(adev, tx, WLAN_HDR_A3_LEN + sizeof(*body)); /* } */ FN_EXIT1(OK); return OK; @@ -4807,26 +4900,26 @@ bad: #endif -/*---------------------------------------------------------------- -* acx_s_complete_scan -* -* Called either from after_interrupt_task() if: -* 1) there was Scan_Complete IRQ, or -* 2) scanning expired in timer() -* We need to decide which ESS or IBSS to join. -* Iterates thru priv->sta_list: -* if priv->ap is not bcast, will join only specified -* ESS or IBSS with this bssid -* checks peers' caps for ESS/IBSS bit -* checks peers' SSID, allows exact match or hidden SSID -* If station to join is chosen: -* points priv->ap_client to the chosen struct client -* sets priv->essid_for_assoc for future assoc attempt -* Auth/assoc is not yet performed -* Returns OK if there is no need to restart scan -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_s_complete_scan +** +** Called either from after_interrupt_task() if: +** 1) there was Scan_Complete IRQ, or +** 2) scanning expired in timer() +** We need to decide which ESS or IBSS to join. +** Iterates thru adev->sta_list: +** if adev->ap is not bcast, will join only specified +** ESS or IBSS with this bssid +** checks peers' caps for ESS/IBSS bit +** checks peers' SSID, allows exact match or hidden SSID +** If station to join is chosen: +** points adev->ap_client to the chosen struct client +** sets adev->essid_for_assoc for future assoc attempt +** Auth/assoc is not yet performed +** Returns OK if there is no need to restart scan +*/ int -acx_s_complete_scan(wlandevice_t *priv) +acx_s_complete_scan(acx_device_t *adev) { struct client *bss; unsigned long flags; @@ -4837,7 +4930,7 @@ acx_s_complete_scan(wlandevice_t *priv) FN_ENTER; - switch (priv->mode) { + switch (adev->mode) { case ACX_MODE_0_ADHOC: needed_cap = WF_MGMT_CAP_IBSS; /* 2, we require Ad-Hoc */ break; @@ -4845,24 +4938,24 @@ acx_s_complete_scan(wlandevice_t *priv) needed_cap = WF_MGMT_CAP_ESS; /* 1, we require Managed */ break; default: - printk("acx: driver bug: mode=%d in complete_scan()\n", priv->mode); + printk("acx: driver bug: mode=%d in complete_scan()\n", adev->mode); dump_stack(); goto end; } - acx_lock(priv, flags); + acx_lock(adev, flags); /* TODO: sta_iterator hiding implementation would be nice here... */ - for (i = 0; i < VEC_SIZE(priv->sta_list); i++) { - bss = &priv->sta_list[i]; + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + bss = &adev->sta_list[i]; if (!bss->used) continue; log(L_ASSOC, "scan table: SSID='%s' CH=%d SIR=%d SNR=%d\n", bss->essid, bss->channel, bss->sir, bss->snr); - if (!mac_is_bcast(priv->ap)) - if (!mac_is_equal(bss->bssid, priv->ap)) + if (!mac_is_bcast(adev->ap)) + if (!mac_is_equal(bss->bssid, adev->ap)) continue; /* keep looking */ /* broken peer with no mode flags set? */ @@ -4870,7 +4963,7 @@ acx_s_complete_scan(wlandevice_t *priv) printk("%s: strange peer "MACSTR" found with " "neither ESS (AP) nor IBSS (Ad-Hoc) " "capability - skipped\n", - priv->netdev->name, MAC(bss->address)); + adev->ndev->name, MAC(bss->address)); continue; } log(L_ASSOC, "peer_cap 0x%04X, needed_cap 0x%04X\n", @@ -4884,47 +4977,47 @@ acx_s_complete_scan(wlandevice_t *priv) if (unlikely(!bss->rate_bas)) { printk("%s: strange peer "MACSTR" with empty rate set " "- skipped\n", - priv->netdev->name, MAC(bss->address)); + adev->ndev->name, MAC(bss->address)); continue; } /* do we support all basic rates of this peer? */ - if ((bss->rate_bas & priv->rate_oper) != bss->rate_bas) { + if ((bss->rate_bas & adev->rate_oper) != bss->rate_bas) { /* we probably need to have all rates as operational rates, even in case of an 11M-only configuration */ #ifdef THIS_IS_TROUBLESOME printk("%s: peer "MACSTR": incompatible basic rates " "(AP requests 0x%04X, we have 0x%04X) " "- skipped\n", - priv->netdev->name, MAC(bss->address), - bss->rate_bas, priv->rate_oper); + adev->ndev->name, MAC(bss->address), + bss->rate_bas, adev->rate_oper); continue; #else printk("%s: peer "MACSTR": incompatible basic rates " "(AP requests 0x%04X, we have 0x%04X). " "Considering anyway...\n", - priv->netdev->name, MAC(bss->address), - bss->rate_bas, priv->rate_oper); + adev->ndev->name, MAC(bss->address), + bss->rate_bas, adev->rate_oper); #endif } - if ( !(priv->reg_dom_chanmask & (1<<(bss->channel-1))) ) { + if ( !(adev->reg_dom_chanmask & (1<<(bss->channel-1))) ) { printk("%s: warning: peer "MACSTR" is on channel %d " "outside of channel range of current " "regulatory domain - couldn't join " "even if other settings match. " "You might want to adapt your config\n", - priv->netdev->name, MAC(bss->address), + adev->ndev->name, MAC(bss->address), bss->channel); continue; /* keep looking */ } - if (!priv->essid_active || !strcmp(bss->essid, priv->essid)) { + if (!adev->essid_active || !strcmp(bss->essid, adev->essid)) { log(L_ASSOC, "found station with matching ESSID! ('%s' " "station, '%s' config)\n", bss->essid, - (priv->essid_active) ? priv->essid : "[any]"); + (adev->essid_active) ? adev->essid : "[any]"); /* TODO: continue looking for peer with better SNR */ bss->used = CLIENT_JOIN_CANDIDATE; idx_found = i; @@ -4932,7 +5025,7 @@ acx_s_complete_scan(wlandevice_t *priv) /* stop searching if this station is * on the current channel, otherwise * keep looking for an even better match */ - if (bss->channel == priv->channel) + if (bss->channel == adev->channel) break; } else if (!bss->essid[0] @@ -4956,7 +5049,7 @@ acx_s_complete_scan(wlandevice_t *priv) log(L_ASSOC, "ESSID doesn't match! ('%s' " "station, '%s' config)\n", bss->essid, - (priv->essid_active) ? priv->essid : "[any]"); + (adev->essid_active) ? adev->essid : "[any]"); } } @@ -4966,54 +5059,54 @@ acx_s_complete_scan(wlandevice_t *priv) char *essid_src; size_t essid_len; - bss = &priv->sta_list[idx_found]; - priv->ap_client = bss; + bss = &adev->sta_list[idx_found]; + adev->ap_client = bss; if (bss->essid[0] == '\0') { /* if the ESSID of the station we found is empty - * (no broadcast), then use user configured ESSID + * (no broadcast), then use user-configured ESSID * instead */ - essid_src = priv->essid; - essid_len = priv->essid_len; + essid_src = adev->essid; + essid_len = adev->essid_len; } else { essid_src = bss->essid; essid_len = strlen(bss->essid); } - acx_update_capabilities(priv); + acx_update_capabilities(adev); - memcpy(priv->essid_for_assoc, essid_src, essid_len); - priv->essid_for_assoc[essid_len] = '\0'; - priv->channel = bss->channel; - MAC_COPY(priv->bssid, bss->bssid); + memcpy(adev->essid_for_assoc, essid_src, essid_len); + adev->essid_for_assoc[essid_len] = '\0'; + adev->channel = bss->channel; + MAC_COPY(adev->bssid, bss->bssid); - bss->rate_cfg = (bss->rate_cap & priv->rate_oper); + bss->rate_cfg = (bss->rate_cap & adev->rate_oper); bss->rate_cur = 1 << lowest_bit(bss->rate_cfg); bss->rate_100 = acx_rate111to100(bss->rate_cur); acxlog_mac(L_ASSOC, - "matching station found: ", priv->bssid, ", joining\n"); + "matching station found: ", adev->bssid, ", joining\n"); /* TODO: do we need to switch to the peer's channel first? */ - if (ACX_MODE_0_ADHOC == priv->mode) { - acx_set_status(priv, ACX_STATUS_4_ASSOCIATED); + if (ACX_MODE_0_ADHOC == adev->mode) { + acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); } else { - acx_l_transmit_authen1(priv); - acx_set_status(priv, ACX_STATUS_2_WAIT_AUTH); + acx_l_transmit_authen1(adev); + acx_set_status(adev, ACX_STATUS_2_WAIT_AUTH); } } else { /* idx_found == -1 */ /* uh oh, no station found in range */ - if (ACX_MODE_0_ADHOC == priv->mode) { + if (ACX_MODE_0_ADHOC == adev->mode) { printk("%s: no matching station found in range, " "generating our own IBSS instead\n", - priv->netdev->name); - /* we do it hostap way: */ - MAC_COPY(priv->bssid, priv->dev_addr); - priv->bssid[0] |= 0x02; /* 'local assigned addr' bit */ + adev->ndev->name); + /* we do it the HostAP way: */ + MAC_COPY(adev->bssid, adev->dev_addr); + adev->bssid[0] |= 0x02; /* 'local assigned addr' bit */ /* add IBSS bit to our caps... */ - acx_update_capabilities(priv); - acx_set_status(priv, ACX_STATUS_4_ASSOCIATED); + acx_update_capabilities(adev); + acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); /* In order to cmd_join be called below */ idx_found = 0; } else { @@ -5021,22 +5114,22 @@ acx_s_complete_scan(wlandevice_t *priv) ** just temporarily powered off */ log(L_ASSOC, "no matching station found in range yet\n"); - acx_set_status(priv, ACX_STATUS_1_SCANNING); + acx_set_status(adev, ACX_STATUS_1_SCANNING); result = NOT_OK; } } - acx_unlock(priv, flags); + acx_unlock(adev, flags); if (idx_found != -1) { - if (ACX_MODE_0_ADHOC == priv->mode) { + if (ACX_MODE_0_ADHOC == adev->mode) { /* need to update channel in beacon template */ - SET_BIT(priv->set_mask, SET_TEMPLATES); - if (ACX_STATE_IFACE_UP & priv->dev_state_mask) - acx_s_update_card_settings(priv); + SET_BIT(adev->set_mask, SET_TEMPLATES); + if (ACX_STATE_IFACE_UP & adev->dev_state_mask) + acx_s_update_card_settings(adev); } /* Inform firmware on our decision to start or join BSS */ - acx_s_cmd_join_bssid(priv, priv->bssid); + acx_s_cmd_join_bssid(adev, adev->bssid); } end: @@ -5054,28 +5147,10 @@ end: ** 0 unable to load file ** pointer to firmware success */ -#if USE_FW_LOADER_26 firmware_image_t* acx_s_read_fw(struct device *dev, const char *file, u32 *size) -#else -#undef acx_s_read_fw -firmware_image_t* -acx_s_read_fw(const char *file, u32 *size) -#endif { firmware_image_t *res; - -#if USE_FW_LOADER_LEGACY - mm_segment_t orgfs; - unsigned long page; - char *buffer; - struct file *inf; - int retval; - int offset; - char *filename; -#endif - -#if USE_FW_LOADER_26 const struct firmware *fw_entry; res = NULL; @@ -5104,220 +5179,66 @@ release_ret: } printk("acx: firmware image '%s' was not provided. " "Check your hotplug scripts\n", file); -#endif - -#if USE_FW_LOADER_LEGACY - printk("acx: firmware upload via firmware_dir module parameter " - "is deprecated. Switch to using hotplug\n"); - - res = NULL; - orgfs = get_fs(); /* store original fs */ - set_fs(KERNEL_DS); - - /* Read in whole file then check the size */ - page = __get_free_page(GFP_KERNEL); - if (unlikely(0 == page)) { - printk("acx: no memory for firmware upload\n"); - goto fail; - } - - filename = kmalloc(PATH_MAX, GFP_KERNEL); - if (unlikely(!filename)) { - printk("acx: no memory for firmware upload\n"); - goto fail; - } - if (!firmware_dir) { - firmware_dir = "/usr/share/acx"; - log(L_DEBUG, "no firmware directory specified " - "via module parameter firmware_dir, " - "using default %s\n", firmware_dir); - } - snprintf(filename, PATH_MAX, "%s/%s", firmware_dir, file); - log(L_INIT, "reading firmware image '%s'\n", filename); - - buffer = (char*)page; - - /* Note that file must be given as absolute path: - * a relative path works on first loading, - * but any subsequent firmware loading during card - * eject/insert will fail, most likely since the first - * module loading happens in user space (and thus - * filp_open can figure out the absolute path from a - * relative path) whereas the card reinsert processing - * probably happens in kernel space where you don't have - * a current directory to be able to figure out an - * absolute path from a relative path... */ - inf = filp_open(filename, O_RDONLY, 0); - kfree(filename); - if (OK != IS_ERR(inf)) { - const char *err; - - switch (-PTR_ERR(inf)) { - case 2: err = "file not found"; - break; - default: - err = "unknown error"; - break; - } - printk("acx: error %ld trying to open file '%s': %s\n", - -PTR_ERR(inf), file, err); - goto fail; - } - - if (unlikely((NULL == inf->f_op) || (NULL == inf->f_op->read))) { - printk("acx: %s does not have a read method?!\n", file); - goto fail_close; - } - - offset = 0; - do { - retval = inf->f_op->read(inf, buffer, PAGE_SIZE, &inf->f_pos); - - if (unlikely(0 > retval)) { - printk("acx: error %d reading file '%s'\n", - -retval, file); - vfree(res); - res = NULL; - } else if (0 == retval) { - if (0 == offset) { - printk("acx: firmware image file " - "'%s' is empty?!\n", file); - } - } else if (0 < retval) { - /* allocate result buffer here if needed, - * since we don't want to waste resources/time - * (in case file opening/reading fails) - * by doing allocation in front of the loop instead. */ - if (NULL == res) { - *size = 8 + le32_to_cpu(*(u32 *)(4 + buffer)); - - res = vmalloc(*size); - if (NULL == res) { - printk("acx: unable to " - "allocate %u bytes for " - "firmware module upload\n", - *size); - goto fail_close; - } - log(L_DEBUG, "allocated %u bytes " - "for firmware module loading\n", - *size); - } - if ((unlikely(offset + retval > *size))) { - printk("acx: ERROR: allocation " - "was less than firmware image size?!\n"); - goto fail_close; - } - memcpy((u8*)res + offset, buffer, retval); - offset += retval; - } - } while (0 < retval); - -fail_close: - retval = filp_close(inf, NULL); - - if (unlikely(retval)) { - printk("acx: error %d closing file '%s'\n", -retval, file); - } - - if (unlikely((NULL != res) && (offset != le32_to_cpu(res->size) + 8))) { - printk("acx: firmware is reporting a different size " - "(0x%08X; 0x%08X was read)\n", - le32_to_cpu(res->size) + 8, offset); - vfree(res); - res = NULL; - } - -fail: - if (page) - free_page(page); - set_fs(orgfs); -#endif /* checksum will be verified in write_fw, so don't bother here */ return res; } -#ifdef POWER_SAVE_80211 -/*---------------------------------------------------------------- -* acx_s_activate_power_save_mode -*----------------------------------------------------------------*/ -static void -acx_s_activate_power_save_mode(wlandevice_t *priv) -{ - acx100_ie_powermgmt_t pm; - - FN_ENTER; - - acx_s_interrogate(priv, &pm, ACX1xx_IE_POWER_MGMT); - if (pm.wakeup_cfg != 0x81) - goto end; - - pm.wakeup_cfg = 0; - pm.options = 0; - pm.hangover_period = 0; - acx_s_configure(priv, &pm, ACX1xx_IE_POWER_MGMT); -end: - FN_EXIT0; -} -#endif - - /*********************************************************************** ** acx_s_set_wepkey */ static void -acx100_s_set_wepkey(wlandevice_t *priv) +acx100_s_set_wepkey(acx_device_t *adev) { ie_dot11WEPDefaultKey_t dk; int i; for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) { - if (priv->wep_keys[i].size != 0) { + if (adev->wep_keys[i].size != 0) { log(L_INIT, "setting WEP key: %d with " - "total size: %d\n", i, (int) priv->wep_keys[i].size); + "total size: %d\n", i, (int) adev->wep_keys[i].size); dk.action = 1; - dk.keySize = priv->wep_keys[i].size; + dk.keySize = adev->wep_keys[i].size; dk.defaultKeyNum = i; - memcpy(dk.key, priv->wep_keys[i].key, dk.keySize); - acx_s_configure(priv, &dk, ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE); + memcpy(dk.key, adev->wep_keys[i].key, dk.keySize); + acx_s_configure(adev, &dk, ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE); } } } static void -acx111_s_set_wepkey(wlandevice_t *priv) +acx111_s_set_wepkey(acx_device_t *adev) { acx111WEPDefaultKey_t dk; int i; for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) { - if (priv->wep_keys[i].size != 0) { + if (adev->wep_keys[i].size != 0) { log(L_INIT, "setting WEP key: %d with " - "total size: %d\n", i, (int) priv->wep_keys[i].size); + "total size: %d\n", i, (int) adev->wep_keys[i].size); memset(&dk, 0, sizeof(dk)); dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */ - dk.keySize = priv->wep_keys[i].size; + dk.keySize = adev->wep_keys[i].size; /* are these two lines necessary? */ dk.type = 0; /* default WEP key */ dk.index = 0; /* ignored when setting default key */ dk.defaultKeyNum = i; - memcpy(dk.key, priv->wep_keys[i].key, dk.keySize); - acx_s_issue_cmd(priv, ACX1xx_CMD_WEP_MGMT, &dk, sizeof(dk)); + memcpy(dk.key, adev->wep_keys[i].key, dk.keySize); + acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk, sizeof(dk)); } } } static void -acx_s_set_wepkey(wlandevice_t *priv) +acx_s_set_wepkey(acx_device_t *adev) { - if (IS_ACX111(priv)) - acx111_s_set_wepkey(priv); + if (IS_ACX111(adev)) + acx111_s_set_wepkey(adev); else - acx100_s_set_wepkey(priv); + acx100_s_set_wepkey(adev); } @@ -5328,8 +5249,8 @@ acx_s_set_wepkey(wlandevice_t *priv) ** management, but since we're also modifying the memory map layout here ** due to the WEP key space we want, we should take care... */ -int -acx100_s_init_wep(wlandevice_t *priv) +static int +acx100_s_init_wep(acx_device_t *adev) { acx100_ie_wep_options_t options; ie_dot11WEPDefaultKeyID_t dk; @@ -5338,7 +5259,7 @@ acx100_s_init_wep(wlandevice_t *priv) FN_ENTER; - if (OK != acx_s_interrogate(priv, &pt, ACX1xx_IE_MEMORY_MAP)) { + if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) { goto fail; } @@ -5347,7 +5268,7 @@ acx100_s_init_wep(wlandevice_t *priv) pt.WEPCacheStart = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4); pt.WEPCacheEnd = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4); - if (OK != acx_s_configure(priv, &pt, ACX1xx_IE_MEMORY_MAP)) { + if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) { goto fail; } @@ -5356,45 +5277,45 @@ acx100_s_init_wep(wlandevice_t *priv) options.WEPOption = 0x00; log(L_ASSOC, "%s: writing WEP options\n", __func__); - acx_s_configure(priv, &options, ACX100_IE_WEP_OPTIONS); + acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS); - acx100_s_set_wepkey(priv); + acx100_s_set_wepkey(adev); - if (priv->wep_keys[priv->wep_current_index].size != 0) { + if (adev->wep_keys[adev->wep_current_index].size != 0) { log(L_ASSOC, "setting active default WEP key number: %d\n", - priv->wep_current_index); - dk.KeyID = priv->wep_current_index; - acx_s_configure(priv, &dk, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */ + adev->wep_current_index); + dk.KeyID = adev->wep_current_index; + acx_s_configure(adev, &dk, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */ } - /* FIXME!!! wep_key_struct is filled nowhere! But priv + /* FIXME!!! wep_key_struct is filled nowhere! But adev * is initialized to 0, and we don't REALLY need those keys either */ /* for (i = 0; i < 10; i++) { - if (priv->wep_key_struct[i].len != 0) { - MAC_COPY(wep_mgmt.MacAddr, priv->wep_key_struct[i].addr); - wep_mgmt.KeySize = cpu_to_le16(priv->wep_key_struct[i].len); - memcpy(&wep_mgmt.Key, priv->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize)); + if (adev->wep_key_struct[i].len != 0) { + MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr); + wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len); + memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize)); wep_mgmt.Action = cpu_to_le16(1); log(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize)); - if (OK == acx_s_issue_cmd(priv, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) { - priv->wep_key_struct[i].index = i; + if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) { + adev->wep_key_struct[i].index = i; } } } */ /* now retrieve the updated WEPCacheEnd pointer... */ - if (OK != acx_s_interrogate(priv, &pt, ACX1xx_IE_MEMORY_MAP)) { + if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) { printk("%s: ACX1xx_IE_MEMORY_MAP read #2 FAILED\n", - priv->netdev->name); + adev->ndev->name); goto fail; } /* ...and tell it to start allocating templates at that location */ /* (no endianness conversion needed) */ pt.PacketTemplateStart = pt.WEPCacheEnd; - if (OK != acx_s_configure(priv, &pt, ACX1xx_IE_MEMORY_MAP)) { + if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) { printk("%s: ACX1xx_IE_MEMORY_MAP write #2 FAILED\n", - priv->netdev->name); + adev->ndev->name); goto fail; } res = OK; @@ -5405,92 +5326,68 @@ fail: } -/*********************************************************************** -*/ static int -acx_s_init_max_null_data_template(wlandevice_t *priv) +acx_s_init_max_template_generic(acx_device_t *adev, unsigned int len, unsigned int cmd) { - struct acx_template_nullframe b; - int result; - - FN_ENTER; - memset(&b, 0, sizeof(b)); - b.size = cpu_to_le16(sizeof(b) - 2); - result = acx_s_issue_cmd(priv, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b)); - FN_EXIT1(result); - return result; + int res; + union { + acx_template_nullframe_t null; + acx_template_beacon_t b; + acx_template_tim_t tim; + acx_template_probereq_t preq; + acx_template_proberesp_t presp; + } templ; + + memset(&templ, 0, len); + templ.null.size = cpu_to_le16(len - 2); + res = acx_s_issue_cmd(adev, cmd, &templ, len); + return res; } - -/*********************************************************************** -** acx_s_init_max_beacon_template -*/ -static int -acx_s_init_max_beacon_template(wlandevice_t *priv) +static inline int +acx_s_init_max_null_data_template(acx_device_t *adev) { - struct acx_template_beacon b; - int result; - - FN_ENTER; - memset(&b, 0, sizeof(b)); - b.size = cpu_to_le16(sizeof(b) - 2); - result = acx_s_issue_cmd(priv, ACX1xx_CMD_CONFIG_BEACON, &b, sizeof(b)); - - FN_EXIT1(result); - return result; + return acx_s_init_max_template_generic( + adev, sizeof(acx_template_nullframe_t), ACX1xx_CMD_CONFIG_NULL_DATA + ); } -/*********************************************************************** -** acx_s_init_max_tim_template -*/ -static int -acx_s_init_max_tim_template(wlandevice_t *priv) +static inline int +acx_s_init_max_beacon_template(acx_device_t *adev) { - acx_template_tim_t t; - - memset(&t, 0, sizeof(t)); - t.size = cpu_to_le16(sizeof(t) - 2); - return acx_s_issue_cmd(priv, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t)); + return acx_s_init_max_template_generic( + adev, sizeof(acx_template_beacon_t), ACX1xx_CMD_CONFIG_BEACON + ); } - -/*********************************************************************** -** acx_s_init_max_probe_response_template -*/ -static int -acx_s_init_max_probe_response_template(wlandevice_t *priv) +static inline int +acx_s_init_max_tim_template(acx_device_t *adev) { - struct acx_template_proberesp pr; - - memset(&pr, 0, sizeof(pr)); - pr.size = cpu_to_le16(sizeof(pr) - 2); - - return acx_s_issue_cmd(priv, ACX1xx_CMD_CONFIG_PROBE_RESPONSE, &pr, sizeof(pr)); + return acx_s_init_max_template_generic( + adev, sizeof(acx_template_tim_t), ACX1xx_CMD_CONFIG_TIM + ); } - -/*********************************************************************** -** acx_s_init_max_probe_request_template -*/ -static int -acx_s_init_max_probe_request_template(wlandevice_t *priv) +static inline int +acx_s_init_max_probe_response_template(acx_device_t *adev) { - int res; - acx_template_probereq_t pr; - - FN_ENTER; - memset(&pr, 0, sizeof(pr)); - pr.size = cpu_to_le16(sizeof(pr) - 2); - res = acx_s_issue_cmd(priv, ACX1xx_CMD_CONFIG_PROBE_REQUEST, &pr, sizeof(pr)); - FN_EXIT1(res); - return res; + return acx_s_init_max_template_generic( + adev, sizeof(acx_template_proberesp_t), ACX1xx_CMD_CONFIG_PROBE_RESPONSE + ); } +static inline int +acx_s_init_max_probe_request_template(acx_device_t *adev) +{ + return acx_s_init_max_template_generic( + adev, sizeof(acx_template_probereq_t), ACX1xx_CMD_CONFIG_PROBE_REQUEST + ); +} /*********************************************************************** ** acx_s_set_tim_template ** -** In full blown driver we will regularly update partial virtual bitmap +** FIXME: In full blown driver we will regularly update partial virtual bitmap ** by calling this function ** (it can be done by irq handler on each DTIM irq or by timer...) @@ -5525,7 +5422,7 @@ acx_s_init_max_probe_request_template(wl (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?) */ static int -acx_s_set_tim_template(wlandevice_t *priv) +acx_s_set_tim_template(acx_device_t *adev) { /* For now, configure smallish test bitmap, all zero ("no pending data") */ enum { bitmap_size = 5 }; @@ -5539,7 +5436,7 @@ acx_s_set_tim_template(wlandevice_t *pri t.size = 5 + bitmap_size; /* eid+len+count+period+bmap_ctrl + bmap */ t.tim_eid = WLAN_EID_TIM; t.len = 3 + bitmap_size; /* count+period+bmap_ctrl + bmap */ - result = acx_s_issue_cmd(priv, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t)); + result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t)); FN_EXIT1(result); return result; } @@ -5584,7 +5481,7 @@ acx_s_set_tim_template(wlandevice_t *pri ** 19 Extended Supported Rates (if more than 8 rates) */ static int -acx_fill_beacon_or_proberesp_template(wlandevice_t *priv, +acx_fill_beacon_or_proberesp_template(acx_device_t *adev, struct acx_template_beacon *templ, u16 fc /* in host order! */) { @@ -5595,21 +5492,21 @@ acx_fill_beacon_or_proberesp_template(wl memset(templ, 0, sizeof(*templ)); MAC_BCAST(templ->da); - MAC_COPY(templ->sa, priv->dev_addr); - MAC_COPY(templ->bssid, priv->bssid); + MAC_COPY(templ->sa, adev->dev_addr); + MAC_COPY(templ->bssid, adev->bssid); - templ->beacon_interval = cpu_to_le16(priv->beacon_interval); - acx_update_capabilities(priv); - templ->cap = cpu_to_le16(priv->capabilities); + templ->beacon_interval = cpu_to_le16(adev->beacon_interval); + acx_update_capabilities(adev); + templ->cap = cpu_to_le16(adev->capabilities); p = templ->variable; - p = wlan_fill_ie_ssid(p, priv->essid_len, priv->essid); - p = wlan_fill_ie_rates(p, priv->rate_supported_len, priv->rate_supported); - p = wlan_fill_ie_ds_parms(p, priv->channel); + p = wlan_fill_ie_ssid(p, adev->essid_len, adev->essid); + p = wlan_fill_ie_rates(p, adev->rate_supported_len, adev->rate_supported); + p = wlan_fill_ie_ds_parms(p, adev->channel); /* NB: should go AFTER tim, but acx seem to keep tim last always */ - p = wlan_fill_ie_rates_ext(p, priv->rate_supported_len, priv->rate_supported); + p = wlan_fill_ie_rates_ext(p, adev->rate_supported_len, adev->rate_supported); - switch (priv->mode) { + switch (adev->mode) { case ACX_MODE_0_ADHOC: /* ATIM window */ p = wlan_fill_ie_ibss_parms(p, 0); break; @@ -5628,19 +5525,49 @@ acx_fill_beacon_or_proberesp_template(wl } +#if POWER_SAVE_80211 +/*********************************************************************** +** acx_s_set_null_data_template +*/ +static int +acx_s_set_null_data_template(acx_device_t *adev) +{ + struct acx_template_nullframe b; + int result; + + FN_ENTER; + + /* memset(&b, 0, sizeof(b)); not needed, setting all members */ + + b.size = cpu_to_le16(sizeof(b) - 2); + b.hdr.fc = WF_FTYPE_MGMTi | WF_FSTYPE_NULLi; + b.hdr.dur = 0; + MAC_BCAST(b.hdr.a1); + MAC_COPY(b.hdr.a2, adev->dev_addr); + MAC_COPY(b.hdr.a3, adev->bssid); + b.hdr.seq = 0; + + result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b)); + + FN_EXIT1(result); + return result; +} +#endif + + /*********************************************************************** ** acx_s_set_beacon_template */ static int -acx_s_set_beacon_template(wlandevice_t *priv) +acx_s_set_beacon_template(acx_device_t *adev) { struct acx_template_beacon bcn; int len, result; FN_ENTER; - len = acx_fill_beacon_or_proberesp_template(priv, &bcn, WF_FSTYPE_BEACON); - result = acx_s_issue_cmd(priv, ACX1xx_CMD_CONFIG_BEACON, &bcn, len); + len = acx_fill_beacon_or_proberesp_template(adev, &bcn, WF_FSTYPE_BEACON); + result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_BEACON, &bcn, len); FN_EXIT1(result); return result; @@ -5651,15 +5578,15 @@ acx_s_set_beacon_template(wlandevice_t * ** acx_s_set_probe_response_template */ static int -acx_s_set_probe_response_template(wlandevice_t *priv) +acx_s_set_probe_response_template(acx_device_t *adev) { struct acx_template_proberesp pr; int len, result; FN_ENTER; - len = acx_fill_beacon_or_proberesp_template(priv, &pr, WF_FSTYPE_PROBERESP); - result = acx_s_issue_cmd(priv, ACX1xx_CMD_CONFIG_PROBE_RESPONSE, &pr, len); + len = acx_fill_beacon_or_proberesp_template(adev, &pr, WF_FSTYPE_PROBERESP); + result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_PROBE_RESPONSE, &pr, len); FN_EXIT1(result); return result; @@ -5667,53 +5594,63 @@ acx_s_set_probe_response_template(wlande /*********************************************************************** -** acx100_s_init_packet_templates() +** acx_s_init_packet_templates() ** ** NOTE: order is very important here, to have a correct memory layout! ** init templates: max Probe Request (station mode), max NULL data, ** max Beacon, max TIM, max Probe Response. */ -int -acx100_s_init_packet_templates(wlandevice_t *priv) +static int +acx_s_init_packet_templates(acx_device_t *adev) { - acx_ie_memmap_t mm; + acx_ie_memmap_t mm; /* ACX100 only */ int result = NOT_OK; FN_ENTER; - log(L_DEBUG, "sizeof(memmap)=%d bytes\n", (int)sizeof(mm)); - - if (OK != acx_s_init_max_probe_request_template(priv)) - goto failed; + log(L_DEBUG|L_INIT, "initializing max packet templates\n"); - if (OK != acx_s_init_max_null_data_template(priv)) + if (OK != acx_s_init_max_probe_request_template(adev)) goto failed; - if (OK != acx_s_init_max_beacon_template(priv)) + if (OK != acx_s_init_max_null_data_template(adev)) goto failed; - if (OK != acx_s_init_max_tim_template(priv)) + if (OK != acx_s_init_max_beacon_template(adev)) goto failed; - if (OK != acx_s_init_max_probe_response_template(priv)) + if (OK != acx_s_init_max_tim_template(adev)) goto failed; - if (OK != acx_s_set_tim_template(priv)) + if (OK != acx_s_init_max_probe_response_template(adev)) goto failed; - if (OK != acx_s_interrogate(priv, &mm, ACX1xx_IE_MEMORY_MAP)) { - goto failed; + if (IS_ACX111(adev)) { + /* ACX111 doesn't need the memory map magic below, + * and the other templates will be set later (acx_start) */ + result = OK; + goto success; } + /* ACX100 will have its TIM template set, + * and we also need to update the memory map */ + + if (OK != acx_s_set_tim_template(adev)) + goto failed_acx100; + + log(L_DEBUG, "sizeof(memmap)=%d bytes\n", (int)sizeof(mm)); + + if (OK != acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP)) + goto failed_acx100; + mm.QueueStart = cpu_to_le32(le32_to_cpu(mm.PacketTemplateEnd) + 4); - if (OK != acx_s_configure(priv, &mm, ACX1xx_IE_MEMORY_MAP)) { - goto failed; - } + if (OK != acx_s_configure(adev, &mm, ACX1xx_IE_MEMORY_MAP)) + goto failed_acx100; result = OK; goto success; -failed: +failed_acx100: log(L_DEBUG|L_INIT, /* "cb=0x%X\n" */ "ACXMemoryMap:\n" @@ -5731,45 +5668,8 @@ failed: le32_to_cpu(mm.PacketTemplateStart), le32_to_cpu(mm.PacketTemplateEnd)); -success: - FN_EXIT1(result); - return result; -} - -int -acx111_s_init_packet_templates(wlandevice_t *priv) -{ - int result = NOT_OK; - - FN_ENTER; - - log(L_DEBUG|L_INIT, "initializing max packet templates\n"); - - if (OK != acx_s_init_max_probe_request_template(priv)) - goto failed; - - if (OK != acx_s_init_max_null_data_template(priv)) - goto failed; - - if (OK != acx_s_init_max_beacon_template(priv)) - goto failed; - - if (OK != acx_s_init_max_tim_template(priv)) - goto failed; - - if (OK != acx_s_init_max_probe_response_template(priv)) - goto failed; - - /* the other templates will be set later (acx_start) */ - /* - if (OK != acx_s_set_tim_template(priv)) - goto failed;*/ - - result = OK; - goto success; - failed: - printk("%s: acx111_init_packet_templates() FAILED\n", priv->netdev->name); + printk("%s: %s() FAILED\n", adev->ndev->name, __func__); success: FN_EXIT1(result); @@ -5780,7 +5680,7 @@ success: /*********************************************************************** */ static int -acx_s_set_probe_request_template(wlandevice_t *priv) +acx_s_set_probe_request_template(acx_device_t *adev) { struct acx_template_probereq probereq; char *p; @@ -5793,49 +5693,225 @@ acx_s_set_probe_request_template(wlandev probereq.fc = WF_FTYPE_MGMTi | WF_FSTYPE_PROBEREQi; MAC_BCAST(probereq.da); - MAC_COPY(probereq.sa, priv->dev_addr); + MAC_COPY(probereq.sa, adev->dev_addr); MAC_BCAST(probereq.bssid); p = probereq.variable; - p = wlan_fill_ie_ssid(p, priv->essid_len, priv->essid); - p = wlan_fill_ie_rates(p, priv->rate_supported_len, priv->rate_supported); - p = wlan_fill_ie_rates_ext(p, priv->rate_supported_len, priv->rate_supported); + p = wlan_fill_ie_ssid(p, adev->essid_len, adev->essid); + p = wlan_fill_ie_rates(p, adev->rate_supported_len, adev->rate_supported); + p = wlan_fill_ie_rates_ext(p, adev->rate_supported_len, adev->rate_supported); frame_len = p - (char*)&probereq; - probereq.size = frame_len - 2; + probereq.size = cpu_to_le16(frame_len - 2); - res = acx_s_issue_cmd(priv, ACX1xx_CMD_CONFIG_PROBE_REQUEST, &probereq, frame_len); + res = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_PROBE_REQUEST, &probereq, frame_len); FN_EXIT0; return res; } + +/*********************************************************************** +** acx_s_init_mac +*/ +int +acx_s_init_mac(acx_device_t *adev) +{ + int result = NOT_OK; + + FN_ENTER; + + if (IS_ACX111(adev)) { + adev->ie_len = acx111_ie_len; + adev->ie_len_dot11 = acx111_ie_len_dot11; + } else { + adev->ie_len = acx100_ie_len; + adev->ie_len_dot11 = acx100_ie_len_dot11; + } + + if (IS_PCI(adev)) { + adev->memblocksize = 256; /* 256 is default */ + /* try to load radio for both ACX100 and ACX111, since both + * chips have at least some firmware versions making use of an + * external radio module */ + acxpci_s_upload_radio(adev); + } else { + adev->memblocksize = 128; + } + + if (IS_ACX111(adev)) { + /* for ACX111, the order is different from ACX100 + 1. init packet templates + 2. create station context and create dma regions + 3. init wep default keys + */ + if (OK != acx_s_init_packet_templates(adev)) + goto fail; + if (OK != acx111_s_create_dma_regions(adev)) { + printk("%s: acx111_create_dma_regions FAILED\n", + adev->ndev->name); + goto fail; + } + } else { + if (OK != acx100_s_init_wep(adev)) + goto fail; + if (OK != acx_s_init_packet_templates(adev)) + goto fail; + if (OK != acx100_s_create_dma_regions(adev)) { + printk("%s: acx100_create_dma_regions FAILED\n", + adev->ndev->name); + goto fail; + } + } + + MAC_COPY(adev->ndev->dev_addr, adev->dev_addr); + result = OK; + +fail: + if (result) + printk("acx: init_mac() FAILED\n"); + FN_EXIT1(result); + return result; +} + + +void +acx_s_set_sane_reg_domain(acx_device_t *adev, int do_set) +{ + unsigned mask; + + unsigned int i; + + for (i = 0; i < sizeof(acx_reg_domain_ids); i++) + if (acx_reg_domain_ids[i] == adev->reg_dom_id) + break; + + if (sizeof(acx_reg_domain_ids) == i) { + log(L_INIT, "Invalid or unsupported regulatory domain" + " 0x%02X specified, falling back to FCC (USA)!" + " Please report if this sounds fishy!\n", + adev->reg_dom_id); + i = 0; + adev->reg_dom_id = acx_reg_domain_ids[i]; + + /* since there was a mismatch, we need to force updating */ + do_set = 1; + } + + if (do_set) { + acx_ie_generic_t dom; + dom.m.bytes[0] = adev->reg_dom_id; + acx_s_configure(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN); + } + + adev->reg_dom_chanmask = reg_domain_channel_masks[i]; + + mask = (1 << (adev->channel - 1)); + if (!(adev->reg_dom_chanmask & mask)) { + /* hmm, need to adjust our channel to reside within domain */ + mask = 1; + for (i = 1; i <= 14; i++) { + if (adev->reg_dom_chanmask & mask) { + printk("%s: adjusting selected channel from %d " + "to %d due to new regulatory domain\n", + adev->ndev->name, adev->channel, i); + adev->channel = i; + break; + } + mask <<= 1; + } + } +} + + +#if POWER_SAVE_80211 +static void +acx_s_update_80211_powersave_mode(acx_device_t *adev) +{ + /* merge both structs in a union to be able to have common code */ + union { + acx111_ie_powersave_t acx111; + acx100_ie_powersave_t acx100; + } pm; + + /* change 802.11 power save mode settings */ + log(L_INIT, "updating 802.11 power save mode settings: " + "wakeup_cfg 0x%02X, listen interval %u, " + "options 0x%02X, hangover period %u, " + "enhanced_ps_transition_time %u\n", + adev->ps_wakeup_cfg, adev->ps_listen_interval, + adev->ps_options, adev->ps_hangover_period, + adev->ps_enhanced_transition_time); + acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT); + log(L_INIT, "Previous PS mode settings: wakeup_cfg 0x%02X, " + "listen interval %u, options 0x%02X, " + "hangover period %u, " + "enhanced_ps_transition_time %u, beacon_rx_time %u\n", + pm.acx111.wakeup_cfg, + pm.acx111.listen_interval, + pm.acx111.options, + pm.acx111.hangover_period, + IS_ACX111(adev) ? + pm.acx111.enhanced_ps_transition_time + : pm.acx100.enhanced_ps_transition_time, + IS_ACX111(adev) ? + pm.acx111.beacon_rx_time + : (u32)-1 + ); + pm.acx111.wakeup_cfg = adev->ps_wakeup_cfg; + pm.acx111.listen_interval = adev->ps_listen_interval; + pm.acx111.options = adev->ps_options; + pm.acx111.hangover_period = adev->ps_hangover_period; + if (IS_ACX111(adev)) { + pm.acx111.beacon_rx_time = cpu_to_le32(adev->ps_beacon_rx_time); + pm.acx111.enhanced_ps_transition_time = cpu_to_le32(adev->ps_enhanced_transition_time); + } else { + pm.acx100.enhanced_ps_transition_time = cpu_to_le16(adev->ps_enhanced_transition_time); + } + acx_s_configure(adev, &pm, ACX1xx_IE_POWER_MGMT); + acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT); + log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg); + acx_s_msleep(40); + acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT); + log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg); + log(L_INIT, "power save mode change %s\n", + (pm.acx111.wakeup_cfg & PS_CFG_PENDING) ? "FAILED" : "was successful"); + /* FIXME: maybe verify via PS_CFG_PENDING bit here + * that power save mode change was successful. */ + /* FIXME: we shouldn't trigger a scan immediately after + * fiddling with power save mode (since the firmware is sending + * a NULL frame then). */ +} +#endif + + /*********************************************************************** ** acx_s_update_card_settings ** -** Applies accumulated changes in various priv->xxxx members +** Applies accumulated changes in various adev->xxxx members ** Called by ioctl commit handler, acx_start, acx_set_defaults, ** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG), */ static void -acx111_s_sens_radio_16_17(wlandevice_t *priv) +acx111_s_sens_radio_16_17(acx_device_t *adev) { u32 feature1, feature2; - if ((priv->sensitivity < 1) || (priv->sensitivity > 3)) { + if ((adev->sensitivity < 1) || (adev->sensitivity > 3)) { printk("%s: invalid sensitivity setting (1..3), " - "setting to 1\n", priv->netdev->name); - priv->sensitivity = 1; + "setting to 1\n", adev->ndev->name); + adev->sensitivity = 1; } - acx111_s_get_feature_config(priv, &feature1, &feature2); + acx111_s_get_feature_config(adev, &feature1, &feature2); CLEAR_BIT(feature1, FEATURE1_LOW_RX|FEATURE1_EXTRA_LOW_RX); - if (priv->sensitivity > 1) + if (adev->sensitivity > 1) SET_BIT(feature1, FEATURE1_LOW_RX); - if (priv->sensitivity > 2) + if (adev->sensitivity > 2) SET_BIT(feature1, FEATURE1_EXTRA_LOW_RX); - acx111_s_feature_set(priv, feature1, feature2); + acx111_s_feature_set(adev, feature1, feature2); } + void -acx_s_update_card_settings(wlandevice_t *priv) +acx_s_update_card_settings(acx_device_t *adev) { unsigned long flags; unsigned int start_scan = 0; @@ -5844,25 +5920,25 @@ acx_s_update_card_settings(wlandevice_t FN_ENTER; log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X\n", - priv->get_mask, priv->set_mask); + adev->get_mask, adev->set_mask); /* Track dependencies betweed various settings */ - if (priv->set_mask & (GETSET_MODE|GETSET_RESCAN|GETSET_WEP)) { + if (adev->set_mask & (GETSET_MODE|GETSET_RESCAN|GETSET_WEP)) { log(L_INIT, "important setting has been changed. " "Need to update packet templates, too\n"); - SET_BIT(priv->set_mask, SET_TEMPLATES); + SET_BIT(adev->set_mask, SET_TEMPLATES); } - if (priv->set_mask & GETSET_CHANNEL) { + if (adev->set_mask & GETSET_CHANNEL) { /* This will actually tune RX/TX to the channel */ - SET_BIT(priv->set_mask, GETSET_RX|GETSET_TX); - switch (priv->mode) { + SET_BIT(adev->set_mask, GETSET_RX|GETSET_TX); + switch (adev->mode) { case ACX_MODE_0_ADHOC: case ACX_MODE_3_AP: /* Beacons contain channel# - update them */ - SET_BIT(priv->set_mask, SET_TEMPLATES); + SET_BIT(adev->set_mask, SET_TEMPLATES); } - switch (priv->mode) { + switch (adev->mode) { case ACX_MODE_0_ADHOC: case ACX_MODE_2_STA: start_scan = 1; @@ -5873,107 +5949,107 @@ acx_s_update_card_settings(wlandevice_t #ifdef WHY_SHOULD_WE_BOTHER /* imagine we were just powered off */ /* send a disassoc request in case it's required */ - if (priv->set_mask & (GETSET_MODE|GETSET_RESCAN|GETSET_CHANNEL|GETSET_WEP)) { - if (ACX_MODE_2_STA == priv->mode) { - if (ACX_STATUS_4_ASSOCIATED == priv->status) { + if (adev->set_mask & (GETSET_MODE|GETSET_RESCAN|GETSET_CHANNEL|GETSET_WEP)) { + if (ACX_MODE_2_STA == adev->mode) { + if (ACX_STATUS_4_ASSOCIATED == adev->status) { log(L_ASSOC, "we were ASSOCIATED - " "sending disassoc request\n"); - acx_lock(priv, flags); - acx_l_transmit_disassoc(priv, NULL); + acx_lock(adev, flags); + acx_l_transmit_disassoc(adev, NULL); /* FIXME: deauth? */ - acx_unlock(priv, flags); + acx_unlock(adev, flags); } /* need to reset some other stuff as well */ log(L_DEBUG, "resetting bssid\n"); - MAC_ZERO(priv->bssid); - SET_BIT(priv->set_mask, SET_TEMPLATES|SET_STA_LIST); + MAC_ZERO(adev->bssid); + SET_BIT(adev->set_mask, SET_TEMPLATES|SET_STA_LIST); start_scan = 1; } } #endif - if (priv->get_mask & GETSET_STATION_ID) { + if (adev->get_mask & GETSET_STATION_ID) { u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN]; const u8 *paddr; - acx_s_interrogate(priv, &stationID, ACX1xx_IE_DOT11_STATION_ID); + acx_s_interrogate(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID); paddr = &stationID[4]; for (i = 0; i < ETH_ALEN; i++) { /* we copy the MAC address (reversed in * the card) to the netdevice's MAC * address, and on ifup it will be - * copied into iwpriv->dev_addr */ - priv->netdev->dev_addr[ETH_ALEN - 1 - i] = paddr[i]; + * copied into iwadev->dev_addr */ + adev->ndev->dev_addr[ETH_ALEN - 1 - i] = paddr[i]; } - CLEAR_BIT(priv->get_mask, GETSET_STATION_ID); + CLEAR_BIT(adev->get_mask, GETSET_STATION_ID); } - if (priv->get_mask & GETSET_SENSITIVITY) { - if ((RADIO_RFMD_11 == priv->radio_type) - || (RADIO_MAXIM_0D == priv->radio_type) - || (RADIO_RALINK_15 == priv->radio_type)) { - acx_s_read_phy_reg(priv, 0x30, &priv->sensitivity); + if (adev->get_mask & GETSET_SENSITIVITY) { + if ((RADIO_RFMD_11 == adev->radio_type) + || (RADIO_MAXIM_0D == adev->radio_type) + || (RADIO_RALINK_15 == adev->radio_type)) { + acx_s_read_phy_reg(adev, 0x30, &adev->sensitivity); } else { log(L_INIT, "don't know how to get sensitivity " - "for radio type 0x%02X\n", priv->radio_type); - priv->sensitivity = 0; + "for radio type 0x%02X\n", adev->radio_type); + adev->sensitivity = 0; } - log(L_INIT, "got sensitivity value %u\n", priv->sensitivity); + log(L_INIT, "got sensitivity value %u\n", adev->sensitivity); - CLEAR_BIT(priv->get_mask, GETSET_SENSITIVITY); + CLEAR_BIT(adev->get_mask, GETSET_SENSITIVITY); } - if (priv->get_mask & GETSET_ANTENNA) { + if (adev->get_mask & GETSET_ANTENNA) { u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN]; memset(antenna, 0, sizeof(antenna)); - acx_s_interrogate(priv, antenna, ACX1xx_IE_DOT11_CURRENT_ANTENNA); - priv->antenna = antenna[4]; - log(L_INIT, "got antenna value 0x%02X\n", priv->antenna); - CLEAR_BIT(priv->get_mask, GETSET_ANTENNA); + acx_s_interrogate(adev, antenna, ACX1xx_IE_DOT11_CURRENT_ANTENNA); + adev->antenna = antenna[4]; + log(L_INIT, "got antenna value 0x%02X\n", adev->antenna); + CLEAR_BIT(adev->get_mask, GETSET_ANTENNA); } - if (priv->get_mask & GETSET_ED_THRESH) { - if (IS_ACX100(priv)) { + if (adev->get_mask & GETSET_ED_THRESH) { + if (IS_ACX100(adev)) { u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN]; memset(ed_threshold, 0, sizeof(ed_threshold)); - acx_s_interrogate(priv, ed_threshold, ACX100_IE_DOT11_ED_THRESHOLD); - priv->ed_threshold = ed_threshold[4]; + acx_s_interrogate(adev, ed_threshold, ACX100_IE_DOT11_ED_THRESHOLD); + adev->ed_threshold = ed_threshold[4]; } else { log(L_INIT, "acx111 doesn't support ED\n"); - priv->ed_threshold = 0; + adev->ed_threshold = 0; } - log(L_INIT, "got Energy Detect (ED) threshold %u\n", priv->ed_threshold); - CLEAR_BIT(priv->get_mask, GETSET_ED_THRESH); + log(L_INIT, "got Energy Detect (ED) threshold %u\n", adev->ed_threshold); + CLEAR_BIT(adev->get_mask, GETSET_ED_THRESH); } - if (priv->get_mask & GETSET_CCA) { - if (IS_ACX100(priv)) { + if (adev->get_mask & GETSET_CCA) { + if (IS_ACX100(adev)) { u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN]; - memset(cca, 0, sizeof(priv->cca)); - acx_s_interrogate(priv, cca, ACX1xx_IE_DOT11_CURRENT_CCA_MODE); - priv->cca = cca[4]; + memset(cca, 0, sizeof(adev->cca)); + acx_s_interrogate(adev, cca, ACX1xx_IE_DOT11_CURRENT_CCA_MODE); + adev->cca = cca[4]; } else { log(L_INIT, "acx111 doesn't support CCA\n"); - priv->cca = 0; + adev->cca = 0; } - log(L_INIT, "got Channel Clear Assessment (CCA) value %u\n", priv->cca); - CLEAR_BIT(priv->get_mask, GETSET_CCA); + log(L_INIT, "got Channel Clear Assessment (CCA) value %u\n", adev->cca); + CLEAR_BIT(adev->get_mask, GETSET_CCA); } - if (priv->get_mask & GETSET_REG_DOMAIN) { + if (adev->get_mask & GETSET_REG_DOMAIN) { acx_ie_generic_t dom; - acx_s_interrogate(priv, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN); - priv->reg_dom_id = dom.m.bytes[0]; - /* FIXME: should also set chanmask somehow */ - log(L_INIT, "got regulatory domain 0x%02X\n", priv->reg_dom_id); - CLEAR_BIT(priv->get_mask, GETSET_REG_DOMAIN); + acx_s_interrogate(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN); + adev->reg_dom_id = dom.m.bytes[0]; + acx_s_set_sane_reg_domain(adev, 0); + log(L_INIT, "got regulatory domain 0x%02X\n", adev->reg_dom_id); + CLEAR_BIT(adev->get_mask, GETSET_REG_DOMAIN); } - if (priv->set_mask & GETSET_STATION_ID) { + if (adev->set_mask & GETSET_STATION_ID) { u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN]; u8 *paddr; @@ -5983,340 +6059,273 @@ acx_s_update_card_settings(wlandevice_t * that the ethernet iface's MAC changed * to the card (reversed in * the card!) */ - paddr[i] = priv->dev_addr[ETH_ALEN - 1 - i]; + paddr[i] = adev->dev_addr[ETH_ALEN - 1 - i]; } - acx_s_configure(priv, &stationID, ACX1xx_IE_DOT11_STATION_ID); - CLEAR_BIT(priv->set_mask, GETSET_STATION_ID); + acx_s_configure(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID); + CLEAR_BIT(adev->set_mask, GETSET_STATION_ID); } - if (priv->set_mask & SET_TEMPLATES) { + if (adev->set_mask & SET_TEMPLATES) { log(L_INIT, "updating packet templates\n"); - switch (priv->mode) { + switch (adev->mode) { case ACX_MODE_2_STA: - acx_s_set_probe_request_template(priv); + acx_s_set_probe_request_template(adev); +#if POWER_SAVE_80211 + acx_s_set_null_data_template(adev); +#endif break; case ACX_MODE_0_ADHOC: - acx_s_set_probe_request_template(priv); + acx_s_set_probe_request_template(adev); +#if POWER_SAVE_80211 + /* maybe power save functionality is somehow possible + * for Ad-Hoc mode, too... FIXME: verify it somehow? firmware debug fields? */ + acx_s_set_null_data_template(adev); +#endif /* fall through */ case ACX_MODE_3_AP: - acx_s_set_beacon_template(priv); - acx_s_set_tim_template(priv); + acx_s_set_beacon_template(adev); + acx_s_set_tim_template(adev); /* BTW acx111 firmware would not send probe responses ** if probe request does not have all basic rates flagged ** by 0x80! Thus firmware does not conform to 802.11, ** it should ignore 0x80 bit in ratevector from STA. ** We can 'fix' it by not using this template and ** sending probe responses by hand. TODO --vda */ - acx_s_set_probe_response_template(priv); + acx_s_set_probe_response_template(adev); } /* Needed if generated frames are to be emitted at different tx rate now */ log(L_IRQ, "redoing cmd_join_bssid() after template cfg\n"); - acx_s_cmd_join_bssid(priv, priv->bssid); - CLEAR_BIT(priv->set_mask, SET_TEMPLATES); + acx_s_cmd_join_bssid(adev, adev->bssid); + CLEAR_BIT(adev->set_mask, SET_TEMPLATES); } - if (priv->set_mask & SET_STA_LIST) { - acx_lock(priv, flags); - acx_l_sta_list_init(priv); - CLEAR_BIT(priv->set_mask, SET_STA_LIST); - acx_unlock(priv, flags); + if (adev->set_mask & SET_STA_LIST) { + acx_lock(adev, flags); + acx_l_sta_list_init(adev); + CLEAR_BIT(adev->set_mask, SET_STA_LIST); + acx_unlock(adev, flags); } - if (priv->set_mask & SET_RATE_FALLBACK) { + if (adev->set_mask & SET_RATE_FALLBACK) { u8 rate[4 + ACX1xx_IE_RATE_FALLBACK_LEN]; /* configure to not do fallbacks when not in auto rate mode */ - rate[4] = (priv->rate_auto) ? /* priv->txrate_fallback_retries */ 1 : 0; + rate[4] = (adev->rate_auto) ? /* adev->txrate_fallback_retries */ 1 : 0; log(L_INIT, "updating Tx fallback to %u retries\n", rate[4]); - acx_s_configure(priv, &rate, ACX1xx_IE_RATE_FALLBACK); - CLEAR_BIT(priv->set_mask, SET_RATE_FALLBACK); + acx_s_configure(adev, &rate, ACX1xx_IE_RATE_FALLBACK); + CLEAR_BIT(adev->set_mask, SET_RATE_FALLBACK); } - if (priv->set_mask & GETSET_TXPOWER) { + if (adev->set_mask & GETSET_TXPOWER) { log(L_INIT, "updating transmit power: %u dBm\n", - priv->tx_level_dbm); - acx_s_set_tx_level(priv, priv->tx_level_dbm); - CLEAR_BIT(priv->set_mask, GETSET_TXPOWER); + adev->tx_level_dbm); + acx_s_set_tx_level(adev, adev->tx_level_dbm); + CLEAR_BIT(adev->set_mask, GETSET_TXPOWER); } - if (priv->set_mask & GETSET_SENSITIVITY) { + if (adev->set_mask & GETSET_SENSITIVITY) { log(L_INIT, "updating sensitivity value: %u\n", - priv->sensitivity); - switch (priv->radio_type) { + adev->sensitivity); + switch (adev->radio_type) { case RADIO_RFMD_11: case RADIO_MAXIM_0D: case RADIO_RALINK_15: - acx_s_write_phy_reg(priv, 0x30, priv->sensitivity); + acx_s_write_phy_reg(adev, 0x30, adev->sensitivity); break; case RADIO_RADIA_16: case RADIO_UNKNOWN_17: - acx111_s_sens_radio_16_17(priv); + acx111_s_sens_radio_16_17(adev); break; default: log(L_INIT, "don't know how to modify sensitivity " - "for radio type 0x%02X\n", priv->radio_type); + "for radio type 0x%02X\n", adev->radio_type); } - CLEAR_BIT(priv->set_mask, GETSET_SENSITIVITY); + CLEAR_BIT(adev->set_mask, GETSET_SENSITIVITY); } - if (priv->set_mask & GETSET_ANTENNA) { + if (adev->set_mask & GETSET_ANTENNA) { /* antenna */ u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN]; memset(antenna, 0, sizeof(antenna)); - antenna[4] = priv->antenna; + antenna[4] = adev->antenna; log(L_INIT, "updating antenna value: 0x%02X\n", - priv->antenna); - acx_s_configure(priv, &antenna, ACX1xx_IE_DOT11_CURRENT_ANTENNA); - CLEAR_BIT(priv->set_mask, GETSET_ANTENNA); + adev->antenna); + acx_s_configure(adev, &antenna, ACX1xx_IE_DOT11_CURRENT_ANTENNA); + CLEAR_BIT(adev->set_mask, GETSET_ANTENNA); } - if (priv->set_mask & GETSET_ED_THRESH) { + if (adev->set_mask & GETSET_ED_THRESH) { /* ed_threshold */ log(L_INIT, "updating Energy Detect (ED) threshold: %u\n", - priv->ed_threshold); - if (IS_ACX100(priv)) { + adev->ed_threshold); + if (IS_ACX100(adev)) { u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN]; memset(ed_threshold, 0, sizeof(ed_threshold)); - ed_threshold[4] = priv->ed_threshold; - acx_s_configure(priv, &ed_threshold, ACX100_IE_DOT11_ED_THRESHOLD); + ed_threshold[4] = adev->ed_threshold; + acx_s_configure(adev, &ed_threshold, ACX100_IE_DOT11_ED_THRESHOLD); } else log(L_INIT, "acx111 doesn't support ED!\n"); - CLEAR_BIT(priv->set_mask, GETSET_ED_THRESH); + CLEAR_BIT(adev->set_mask, GETSET_ED_THRESH); } - if (priv->set_mask & GETSET_CCA) { + if (adev->set_mask & GETSET_CCA) { /* CCA value */ log(L_INIT, "updating Channel Clear Assessment " - "(CCA) value: 0x%02X\n", priv->cca); - if (IS_ACX100(priv)) { + "(CCA) value: 0x%02X\n", adev->cca); + if (IS_ACX100(adev)) { u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN]; memset(cca, 0, sizeof(cca)); - cca[4] = priv->cca; - acx_s_configure(priv, &cca, ACX1xx_IE_DOT11_CURRENT_CCA_MODE); + cca[4] = adev->cca; + acx_s_configure(adev, &cca, ACX1xx_IE_DOT11_CURRENT_CCA_MODE); } else log(L_INIT, "acx111 doesn't support CCA!\n"); - CLEAR_BIT(priv->set_mask, GETSET_CCA); + CLEAR_BIT(adev->set_mask, GETSET_CCA); } - if (priv->set_mask & GETSET_LED_POWER) { + if (adev->set_mask & GETSET_LED_POWER) { /* Enable Tx */ - log(L_INIT, "updating power LED status: %u\n", priv->led_power); + log(L_INIT, "updating power LED status: %u\n", adev->led_power); - acx_lock(priv, flags); - if (IS_PCI(priv)) - acxpci_l_power_led(priv, priv->led_power); - CLEAR_BIT(priv->set_mask, GETSET_LED_POWER); - acx_unlock(priv, flags); - } - - if (priv->set_mask & GETSET_POWER_80211) { -/* this seems to cause Tx lockup after some random time (Tx error 0x20), - * so let's disable it for now until further investigation */ -/* Maybe fixed now after locking is fixed. Need to retest */ -#ifdef POWER_SAVE_80211 - acx100_ie_powermgmt_t pm; - - /* change 802.11 power save mode settings */ - log(L_INIT, "updating 802.11 power save mode settings: " - "wakeup_cfg 0x%02X, listen interval %u, " - "options 0x%02X, hangover period %u, " - "enhanced_ps_transition_time %d\n", - priv->ps_wakeup_cfg, priv->ps_listen_interval, - priv->ps_options, priv->ps_hangover_period, - priv->ps_enhanced_transition_time); - acx_s_interrogate(priv, &pm, ACX100_IE_POWER_MGMT); - log(L_INIT, "Previous PS mode settings: wakeup_cfg 0x%02X, " - "listen interval %u, options 0x%02X, " - "hangover period %u, " - "enhanced_ps_transition_time %d\n", - pm.wakeup_cfg, pm.listen_interval, pm.options, - pm.hangover_period, pm.enhanced_ps_transition_time); - pm.wakeup_cfg = priv->ps_wakeup_cfg; - pm.listen_interval = priv->ps_listen_interval; - pm.options = priv->ps_options; - pm.hangover_period = priv->ps_hangover_period; - pm.enhanced_ps_transition_time = cpu_to_le16(priv->ps_enhanced_transition_time); - acx_s_configure(priv, &pm, ACX100_IE_POWER_MGMT); - acx_s_interrogate(priv, &pm, ACX100_IE_POWER_MGMT); - log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.wakeup_cfg); - acx_s_msleep(40); - acx_s_interrogate(priv, &pm, ACX100_IE_POWER_MGMT); - log(L_INIT, "power save mode change %s\n", - (pm.wakeup_cfg & PS_CFG_PENDING) ? "FAILED" : "was successful"); - /* FIXME: maybe verify via PS_CFG_PENDING bit here - * that power save mode change was successful. */ - /* FIXME: we shouldn't trigger a scan immediately after - * fiddling with power save mode (since the firmware is sending - * a NULL frame then). Does this need locking?? */ + acx_lock(adev, flags); + if (IS_PCI(adev)) + acxpci_l_power_led(adev, adev->led_power); + CLEAR_BIT(adev->set_mask, GETSET_LED_POWER); + acx_unlock(adev, flags); + } + + if (adev->set_mask & GETSET_POWER_80211) { +#if POWER_SAVE_80211 + acx_s_update_80211_powersave_mode(adev); #endif - CLEAR_BIT(priv->set_mask, GETSET_POWER_80211); + CLEAR_BIT(adev->set_mask, GETSET_POWER_80211); } - if (priv->set_mask & GETSET_CHANNEL) { + if (adev->set_mask & GETSET_CHANNEL) { /* channel */ - log(L_INIT, "updating channel to: %u\n", priv->channel); - CLEAR_BIT(priv->set_mask, GETSET_CHANNEL); + log(L_INIT, "updating channel to: %u\n", adev->channel); + CLEAR_BIT(adev->set_mask, GETSET_CHANNEL); } - if (priv->set_mask & GETSET_TX) { + if (adev->set_mask & GETSET_TX) { /* set Tx */ log(L_INIT, "updating: %s Tx\n", - priv->tx_disabled ? "disable" : "enable"); - if (priv->tx_disabled) - acx_s_issue_cmd(priv, ACX1xx_CMD_DISABLE_TX, NULL, 0); + adev->tx_disabled ? "disable" : "enable"); + if (adev->tx_disabled) + acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0); else - acx_s_issue_cmd(priv, ACX1xx_CMD_ENABLE_TX, &(priv->channel), 1); - CLEAR_BIT(priv->set_mask, GETSET_TX); + acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX, &adev->channel, 1); + CLEAR_BIT(adev->set_mask, GETSET_TX); } - if (priv->set_mask & GETSET_RX) { + if (adev->set_mask & GETSET_RX) { /* Enable Rx */ log(L_INIT, "updating: enable Rx on channel: %u\n", - priv->channel); - acx_s_issue_cmd(priv, ACX1xx_CMD_ENABLE_RX, &(priv->channel), 1); - CLEAR_BIT(priv->set_mask, GETSET_RX); + adev->channel); + acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1); + CLEAR_BIT(adev->set_mask, GETSET_RX); } - if (priv->set_mask & GETSET_RETRY) { + if (adev->set_mask & GETSET_RETRY) { u8 short_retry[4 + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN]; u8 long_retry[4 + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN]; log(L_INIT, "updating short retry limit: %u, long retry limit: %u\n", - priv->short_retry, priv->long_retry); - short_retry[0x4] = priv->short_retry; - long_retry[0x4] = priv->long_retry; - acx_s_configure(priv, &short_retry, ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT); - acx_s_configure(priv, &long_retry, ACX1xx_IE_DOT11_LONG_RETRY_LIMIT); - CLEAR_BIT(priv->set_mask, GETSET_RETRY); + adev->short_retry, adev->long_retry); + short_retry[0x4] = adev->short_retry; + long_retry[0x4] = adev->long_retry; + acx_s_configure(adev, &short_retry, ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT); + acx_s_configure(adev, &long_retry, ACX1xx_IE_DOT11_LONG_RETRY_LIMIT); + CLEAR_BIT(adev->set_mask, GETSET_RETRY); } - if (priv->set_mask & SET_MSDU_LIFETIME) { + if (adev->set_mask & SET_MSDU_LIFETIME) { u8 xmt_msdu_lifetime[4 + ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN]; log(L_INIT, "updating tx MSDU lifetime: %u\n", - priv->msdu_lifetime); - *(u32 *)&xmt_msdu_lifetime[4] = cpu_to_le32((u32)priv->msdu_lifetime); - acx_s_configure(priv, &xmt_msdu_lifetime, ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME); - CLEAR_BIT(priv->set_mask, SET_MSDU_LIFETIME); + adev->msdu_lifetime); + *(u32 *)&xmt_msdu_lifetime[4] = cpu_to_le32((u32)adev->msdu_lifetime); + acx_s_configure(adev, &xmt_msdu_lifetime, ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME); + CLEAR_BIT(adev->set_mask, SET_MSDU_LIFETIME); } - if (priv->set_mask & GETSET_REG_DOMAIN) { - /* reg_domain */ - acx_ie_generic_t dom; - unsigned mask; - + if (adev->set_mask & GETSET_REG_DOMAIN) { log(L_INIT, "updating regulatory domain: 0x%02X\n", - priv->reg_dom_id); - for (i = 0; i < sizeof(acx_reg_domain_ids); i++) - if (acx_reg_domain_ids[i] == priv->reg_dom_id) - break; - - if (sizeof(acx_reg_domain_ids) == i) { - log(L_INIT, "Invalid or unsupported regulatory " - "domain 0x%02X specified, falling back to " - "FCC (USA)! Please report if this sounds " - "fishy!\n", priv->reg_dom_id); - i = 0; - priv->reg_dom_id = acx_reg_domain_ids[i]; - } - - priv->reg_dom_chanmask = reg_domain_channel_masks[i]; - dom.m.bytes[0] = priv->reg_dom_id; - acx_s_configure(priv, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN); - - mask = (1 << (priv->channel - 1)); - if (!(priv->reg_dom_chanmask & mask)) { - /* hmm, need to adjust our channel to reside within domain */ - mask = 1; - for (i = 1; i <= 14; i++) { - if (priv->reg_dom_chanmask & mask) { - printk("%s: adjusting " - "selected channel from %d " - "to %d due to new regulatory " - "domain\n", priv->netdev->name, - priv->channel, i); - priv->channel = i; - break; - } - mask <<= 1; - } - } - CLEAR_BIT(priv->set_mask, GETSET_REG_DOMAIN); + adev->reg_dom_id); + acx_s_set_sane_reg_domain(adev, 1); + CLEAR_BIT(adev->set_mask, GETSET_REG_DOMAIN); } - if (priv->set_mask & GETSET_MODE) { - priv->netdev->type = ARPHRD_ETHER; + if (adev->set_mask & GETSET_MODE) { + adev->ndev->type = (adev->mode == ACX_MODE_MONITOR) ? + adev->monitor_type : ARPHRD_ETHER; - switch (priv->mode) { + switch (adev->mode) { case ACX_MODE_3_AP: - acx_lock(priv, flags); - acx_l_sta_list_init(priv); - priv->aid = 0; - priv->ap_client = NULL; - MAC_COPY(priv->bssid, priv->dev_addr); + acx_lock(adev, flags); + acx_l_sta_list_init(adev); + adev->aid = 0; + adev->ap_client = NULL; + MAC_COPY(adev->bssid, adev->dev_addr); /* this basically says "we're connected" */ - acx_set_status(priv, ACX_STATUS_4_ASSOCIATED); - acx_unlock(priv, flags); + acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); + acx_unlock(adev, flags); - acx111_s_feature_off(priv, 0, FEATURE2_NO_TXCRYPT|FEATURE2_SNIFFER); + acx111_s_feature_off(adev, 0, FEATURE2_NO_TXCRYPT|FEATURE2_SNIFFER); /* start sending beacons */ - acx_s_cmd_join_bssid(priv, priv->bssid); + acx_s_cmd_join_bssid(adev, adev->bssid); break; case ACX_MODE_MONITOR: - /* priv->netdev->type = ARPHRD_ETHER; */ - /* priv->netdev->type = ARPHRD_IEEE80211; */ - priv->netdev->type = ARPHRD_IEEE80211_PRISM; - acx111_s_feature_on(priv, 0, FEATURE2_NO_TXCRYPT|FEATURE2_SNIFFER); + acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT|FEATURE2_SNIFFER); /* this stops beacons */ - acx_s_cmd_join_bssid(priv, priv->bssid); + acx_s_cmd_join_bssid(adev, adev->bssid); /* this basically says "we're connected" */ - acx_set_status(priv, ACX_STATUS_4_ASSOCIATED); - SET_BIT(priv->set_mask, SET_RXCONFIG|SET_WEP_OPTIONS); + acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); + SET_BIT(adev->set_mask, SET_RXCONFIG|SET_WEP_OPTIONS); break; case ACX_MODE_0_ADHOC: case ACX_MODE_2_STA: - acx111_s_feature_off(priv, 0, FEATURE2_NO_TXCRYPT|FEATURE2_SNIFFER); + acx111_s_feature_off(adev, 0, FEATURE2_NO_TXCRYPT|FEATURE2_SNIFFER); - acx_lock(priv, flags); - priv->aid = 0; - priv->ap_client = NULL; - acx_unlock(priv, flags); + acx_lock(adev, flags); + adev->aid = 0; + adev->ap_client = NULL; + acx_unlock(adev, flags); /* we want to start looking for peer or AP */ start_scan = 1; break; case ACX_MODE_OFF: /* TODO: disable RX/TX, stop any scanning activity etc: */ - /* priv->tx_disabled = 1; */ - /* SET_BIT(priv->set_mask, GETSET_RX|GETSET_TX); */ + /* adev->tx_disabled = 1; */ + /* SET_BIT(adev->set_mask, GETSET_RX|GETSET_TX); */ /* This stops beacons (invalid macmode...) */ - acx_s_cmd_join_bssid(priv, priv->bssid); - acx_set_status(priv, ACX_STATUS_0_STOPPED); + acx_s_cmd_join_bssid(adev, adev->bssid); + acx_set_status(adev, ACX_STATUS_0_STOPPED); break; } - CLEAR_BIT(priv->set_mask, GETSET_MODE); + CLEAR_BIT(adev->set_mask, GETSET_MODE); } - if (priv->set_mask & SET_RXCONFIG) { - acx_s_initialize_rx_config(priv); - CLEAR_BIT(priv->set_mask, SET_RXCONFIG); + if (adev->set_mask & SET_RXCONFIG) { + acx_s_initialize_rx_config(adev); + CLEAR_BIT(adev->set_mask, SET_RXCONFIG); } - if (priv->set_mask & GETSET_RESCAN) { - switch (priv->mode) { + if (adev->set_mask & GETSET_RESCAN) { + switch (adev->mode) { case ACX_MODE_0_ADHOC: case ACX_MODE_2_STA: start_scan = 1; break; } - CLEAR_BIT(priv->set_mask, GETSET_RESCAN); + CLEAR_BIT(adev->set_mask, GETSET_RESCAN); } - if (priv->set_mask & GETSET_WEP) { + if (adev->set_mask & GETSET_WEP) { /* encode */ ie_dot11WEPDefaultKeyID_t dkey; @@ -6329,23 +6338,23 @@ acx_s_update_card_settings(wlandevice_t #endif log(L_INIT, "updating WEP key settings\n"); - acx_s_set_wepkey(priv); + acx_s_set_wepkey(adev); - dkey.KeyID = priv->wep_current_index; + dkey.KeyID = adev->wep_current_index; log(L_INIT, "setting WEP key %u as default\n", dkey.KeyID); - acx_s_configure(priv, &dkey, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); + acx_s_configure(adev, &dkey, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); #ifdef DEBUG_WEP keyindic.val = 3; - acx_s_configure(priv, &keyindic, ACX111_IE_KEY_CHOOSE); + acx_s_configure(adev, &keyindic, ACX111_IE_KEY_CHOOSE); #endif start_scan = 1; - CLEAR_BIT(priv->set_mask, GETSET_WEP); + CLEAR_BIT(adev->set_mask, GETSET_WEP); } - if (priv->set_mask & SET_WEP_OPTIONS) { + if (adev->set_mask & SET_WEP_OPTIONS) { acx100_ie_wep_options_t options; - if (IS_ACX111(priv)) { + if (IS_ACX111(adev)) { log(L_DEBUG, "setting WEP Options for acx111 is not supported\n"); } else { log(L_INIT, "setting WEP Options\n"); @@ -6356,32 +6365,32 @@ acx_s_update_card_settings(wlandevice_t /* don't decrypt default key only, * don't override decryption: */ options.WEPOption = 0; - if (priv->mode == ACX_MODE_MONITOR) { + if (adev->mode == ACX_MODE_MONITOR) { /* don't decrypt default key only, * override decryption mechanism: */ options.WEPOption = 2; } - acx_s_configure(priv, &options, ACX100_IE_WEP_OPTIONS); + acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS); } - CLEAR_BIT(priv->set_mask, SET_WEP_OPTIONS); + CLEAR_BIT(adev->set_mask, SET_WEP_OPTIONS); } /* Rescan was requested */ if (start_scan) { - switch (priv->mode) { + switch (adev->mode) { case ACX_MODE_0_ADHOC: case ACX_MODE_2_STA: /* We can avoid clearing list if join code ** will be a bit more clever about not picking ** 'bad' AP over and over again */ - acx_lock(priv, flags); - priv->ap_client = NULL; - acx_l_sta_list_init(priv); - acx_set_status(priv, ACX_STATUS_1_SCANNING); - acx_unlock(priv, flags); + acx_lock(adev, flags); + adev->ap_client = NULL; + acx_l_sta_list_init(adev); + acx_set_status(adev, ACX_STATUS_1_SCANNING); + acx_unlock(adev, flags); - acx_s_cmd_start_scan(priv); + acx_s_cmd_start_scan(adev); } } @@ -6389,7 +6398,7 @@ acx_s_update_card_settings(wlandevice_t /* what about sniffing mode?? */ log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X - after update\n", - priv->get_mask, priv->set_mask); + adev->get_mask, adev->set_mask); /* end: */ FN_EXIT0; @@ -6397,145 +6406,36 @@ acx_s_update_card_settings(wlandevice_t /*********************************************************************** -*/ -void -acx_s_initialize_rx_config(wlandevice_t *priv) -{ - struct { - u16 id ACX_PACKED; - u16 len ACX_PACKED; - u16 rx_cfg1 ACX_PACKED; - u16 rx_cfg2 ACX_PACKED; - } cfg; - - switch (priv->mode) { - case ACX_MODE_OFF: - priv->rx_config_1 = (u16) (0 - /* | RX_CFG1_INCLUDE_RXBUF_HDR */ - /* | RX_CFG1_FILTER_SSID */ - /* | RX_CFG1_FILTER_BCAST */ - /* | RX_CFG1_RCV_MC_ADDR1 */ - /* | RX_CFG1_RCV_MC_ADDR0 */ - /* | RX_CFG1_FILTER_ALL_MULTI */ - /* | RX_CFG1_FILTER_BSSID */ - /* | RX_CFG1_FILTER_MAC */ - /* | RX_CFG1_RCV_PROMISCUOUS */ - /* | RX_CFG1_INCLUDE_FCS */ - /* | RX_CFG1_INCLUDE_PHY_HDR */ - ); - priv->rx_config_2 = (u16) (0 - /*| RX_CFG2_RCV_ASSOC_REQ */ - /*| RX_CFG2_RCV_AUTH_FRAMES */ - /*| RX_CFG2_RCV_BEACON_FRAMES */ - /*| RX_CFG2_RCV_CONTENTION_FREE */ - /*| RX_CFG2_RCV_CTRL_FRAMES */ - /*| RX_CFG2_RCV_DATA_FRAMES */ - /*| RX_CFG2_RCV_BROKEN_FRAMES */ - /*| RX_CFG2_RCV_MGMT_FRAMES */ - /*| RX_CFG2_RCV_PROBE_REQ */ - /*| RX_CFG2_RCV_PROBE_RESP */ - /*| RX_CFG2_RCV_ACK_FRAMES */ - /*| RX_CFG2_RCV_OTHER */ - ); - break; - case ACX_MODE_MONITOR: - priv->rx_config_1 = (u16) (0 - /* | RX_CFG1_INCLUDE_RXBUF_HDR */ - /* | RX_CFG1_FILTER_SSID */ - /* | RX_CFG1_FILTER_BCAST */ - /* | RX_CFG1_RCV_MC_ADDR1 */ - /* | RX_CFG1_RCV_MC_ADDR0 */ - /* | RX_CFG1_FILTER_ALL_MULTI */ - /* | RX_CFG1_FILTER_BSSID */ - /* | RX_CFG1_FILTER_MAC */ - | RX_CFG1_RCV_PROMISCUOUS - /* | RX_CFG1_INCLUDE_FCS */ - /* | RX_CFG1_INCLUDE_PHY_HDR */ - ); - priv->rx_config_2 = (u16) (0 - | RX_CFG2_RCV_ASSOC_REQ - | RX_CFG2_RCV_AUTH_FRAMES - | RX_CFG2_RCV_BEACON_FRAMES - | RX_CFG2_RCV_CONTENTION_FREE - | RX_CFG2_RCV_CTRL_FRAMES - | RX_CFG2_RCV_DATA_FRAMES - | RX_CFG2_RCV_BROKEN_FRAMES - | RX_CFG2_RCV_MGMT_FRAMES - | RX_CFG2_RCV_PROBE_REQ - | RX_CFG2_RCV_PROBE_RESP - | RX_CFG2_RCV_ACK_FRAMES - | RX_CFG2_RCV_OTHER - ); - break; - default: - priv->rx_config_1 = (u16) (0 - /* | RX_CFG1_INCLUDE_RXBUF_HDR */ - /* | RX_CFG1_FILTER_SSID */ - /* | RX_CFG1_FILTER_BCAST */ - /* | RX_CFG1_RCV_MC_ADDR1 */ - /* | RX_CFG1_RCV_MC_ADDR0 */ - /* | RX_CFG1_FILTER_ALL_MULTI */ - /* | RX_CFG1_FILTER_BSSID */ - | RX_CFG1_FILTER_MAC - /* | RX_CFG1_RCV_PROMISCUOUS */ - /* | RX_CFG1_INCLUDE_FCS */ - /* | RX_CFG1_INCLUDE_PHY_HDR */ - ); - priv->rx_config_2 = (u16) (0 - | RX_CFG2_RCV_ASSOC_REQ - | RX_CFG2_RCV_AUTH_FRAMES - | RX_CFG2_RCV_BEACON_FRAMES - | RX_CFG2_RCV_CONTENTION_FREE - | RX_CFG2_RCV_CTRL_FRAMES - | RX_CFG2_RCV_DATA_FRAMES - /*| RX_CFG2_RCV_BROKEN_FRAMES */ - | RX_CFG2_RCV_MGMT_FRAMES - | RX_CFG2_RCV_PROBE_REQ - | RX_CFG2_RCV_PROBE_RESP - /*| RX_CFG2_RCV_ACK_FRAMES */ - | RX_CFG2_RCV_OTHER - ); - break; - } - priv->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR; - - log(L_INIT, "setting RXconfig to %04X:%04X\n", - priv->rx_config_1, priv->rx_config_2); - cfg.rx_cfg1 = cpu_to_le16(priv->rx_config_1); - cfg.rx_cfg2 = cpu_to_le16(priv->rx_config_2); - acx_s_configure(priv, &cfg, ACX1xx_IE_RXCONFIG); -} - - -/*********************************************************************** ** acx_e_after_interrupt_task */ static int -acx_s_recalib_radio(wlandevice_t *priv) +acx_s_recalib_radio(acx_device_t *adev) { - if (IS_ACX111(priv)) { + if (IS_ACX111(adev)) { acx111_cmd_radiocalib_t cal; - printk("%s: recalibrating radio\n", priv->netdev->name); + printk("%s: recalibrating radio\n", adev->ndev->name); /* automatic recalibration, choose all methods: */ cal.methods = cpu_to_le32(0x8000000f); /* automatic recalibration every 60 seconds (value in TUs) - * I wonder what is the firmware default here? */ + * I wonder what the firmware default here is? */ cal.interval = cpu_to_le32(58594); - return acx_s_issue_cmd_timeo(priv, ACX111_CMD_RADIOCALIB, + return acx_s_issue_cmd_timeo(adev, ACX111_CMD_RADIOCALIB, &cal, sizeof(cal), CMD_TIMEOUT_MS(100)); } else { - if (/* (OK == acx_s_issue_cmd(priv, ACX1xx_CMD_DISABLE_TX, NULL, 0)) && - (OK == acx_s_issue_cmd(priv, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */ - (OK == acx_s_issue_cmd(priv, ACX1xx_CMD_ENABLE_TX, &(priv->channel), 1)) && - (OK == acx_s_issue_cmd(priv, ACX1xx_CMD_ENABLE_RX, &(priv->channel), 1)) ) + /* On ACX100, we need to recalibrate the radio + * by issuing a GETSET_TX|GETSET_RX */ + if (/* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) && + (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */ + (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX, &adev->channel, 1)) && + (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1)) ) return OK; return NOT_OK; } } static void -acx_s_after_interrupt_recalib(wlandevice_t *priv) +acx_s_after_interrupt_recalib(acx_device_t *adev) { int res; @@ -6545,52 +6445,55 @@ acx_s_after_interrupt_recalib(wlandevice /* clear flag beforehand, since we want to make sure * it's cleared; then only set it again on specific circumstances */ - CLEAR_BIT(priv->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_RADIO_RECALIB); + CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_RADIO_RECALIB); /* better wait a bit between recalibrations to * prevent overheating due to torturing the card * into working too long despite high temperature * (just a safety measure) */ - if (priv->recalib_time_last_success - && time_before(jiffies, priv->recalib_time_last_success + if (adev->recalib_time_last_success + && time_before(jiffies, adev->recalib_time_last_success + RECALIB_PAUSE * 60 * HZ)) { - priv->recalib_msg_ratelimit++; - if (priv->recalib_msg_ratelimit <= 5) + if (adev->recalib_msg_ratelimit <= 4) { printk("%s: less than " STRING(RECALIB_PAUSE) " minutes since last radio recalibration, " "not recalibrating (maybe card is too hot?)\n", - priv->netdev->name); - if (priv->recalib_msg_ratelimit == 5) - printk("disabling above message\n"); + adev->ndev->name); + adev->recalib_msg_ratelimit++; + if (adev->recalib_msg_ratelimit == 5) + printk("disabling above message\n"); + } return; } - priv->recalib_msg_ratelimit = 0; + adev->recalib_msg_ratelimit = 0; /* note that commands sometimes fail (card busy), * so only clear flag if we were fully successful */ - res = acx_s_recalib_radio(priv); + res = acx_s_recalib_radio(adev); if (res == OK) { printk("%s: successfully recalibrated radio\n", - priv->netdev->name); - priv->recalib_time_last_success = jiffies; - priv->recalib_failure_count = 0; + adev->ndev->name); + adev->recalib_time_last_success = jiffies; + adev->recalib_failure_count = 0; } else { /* failed: resubmit, but only limited * amount of times within some time range * to prevent endless loop */ - priv->recalib_time_last_success = 0; /* we failed */ + adev->recalib_time_last_success = 0; /* we failed */ /* if some time passed between last * attempts, then reset failure retry counter * to be able to do next recalib attempt */ - if (time_after(jiffies, priv->recalib_time_last_attempt + HZ)) - priv->recalib_failure_count = 0; + if (time_after(jiffies, adev->recalib_time_last_attempt + 5*HZ)) + adev->recalib_failure_count = 0; - if (++priv->recalib_failure_count <= 5) { - priv->recalib_time_last_attempt = jiffies; - acx_schedule_task(priv, ACX_AFTER_IRQ_CMD_RADIO_RECALIB); + if (adev->recalib_failure_count < 5) { + /* increment inside only, for speedup of outside path */ + adev->recalib_failure_count++; + adev->recalib_time_last_attempt = jiffies; + acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_RADIO_RECALIB); } } } @@ -6598,56 +6501,56 @@ acx_s_after_interrupt_recalib(wlandevice static void acx_e_after_interrupt_task(void *data) { - netdevice_t *dev = (netdevice_t *) data; - wlandevice_t *priv = netdev_priv(dev); + struct net_device *ndev = (struct net_device*)data; + acx_device_t *adev = ndev2adev(ndev); FN_ENTER; - acx_sem_lock(priv); + acx_sem_lock(adev); - if (!priv->after_interrupt_jobs) + if (!adev->after_interrupt_jobs) goto end; /* no jobs to do */ #if TX_CLEANUP_IN_SOFTIRQ /* can happen only on PCI */ - if (priv->after_interrupt_jobs & ACX_AFTER_IRQ_TX_CLEANUP) { - acx_lock(priv, flags); - acxpci_l_clean_txdesc(priv); - CLEAR_BIT(priv->after_interrupt_jobs, ACX_AFTER_IRQ_TX_CLEANUP); - acx_unlock(priv, flags); + if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_TX_CLEANUP) { + acx_lock(adev, flags); + acxpci_l_clean_txdesc(adev); + CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_TX_CLEANUP); + acx_unlock(adev, flags); } #endif /* we see lotsa tx errors */ - if (priv->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_RADIO_RECALIB) { - acx_s_after_interrupt_recalib(priv); + if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_RADIO_RECALIB) { + acx_s_after_interrupt_recalib(adev); } /* a poor interrupt code wanted to do update_card_settings() */ - if (priv->after_interrupt_jobs & ACX_AFTER_IRQ_UPDATE_CARD_CFG) { - if (ACX_STATE_IFACE_UP & priv->dev_state_mask) - acx_s_update_card_settings(priv); - CLEAR_BIT(priv->after_interrupt_jobs, ACX_AFTER_IRQ_UPDATE_CARD_CFG); + if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_UPDATE_CARD_CFG) { + if (ACX_STATE_IFACE_UP & adev->dev_state_mask) + acx_s_update_card_settings(adev); + CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_UPDATE_CARD_CFG); } /* 1) we detected that no Scan_Complete IRQ came from fw, or ** 2) we found too many STAs */ - if (priv->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_STOP_SCAN) { + if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_STOP_SCAN) { log(L_IRQ, "sending a stop scan cmd...\n"); - acx_s_issue_cmd(priv, ACX1xx_CMD_STOP_SCAN, NULL, 0); + acx_s_issue_cmd(adev, ACX1xx_CMD_STOP_SCAN, NULL, 0); /* HACK: set the IRQ bit, since we won't get a * scan complete IRQ any more on ACX111 (works on ACX100!), * since _we_, not a fw, have stopped the scan */ - SET_BIT(priv->irq_status, HOST_INT_SCAN_COMPLETE); - CLEAR_BIT(priv->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_STOP_SCAN); + SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE); + CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_STOP_SCAN); } /* either fw sent Scan_Complete or we detected that ** no Scan_Complete IRQ came from fw. Finish scanning, ** pick join partner if any */ - if (priv->after_interrupt_jobs & ACX_AFTER_IRQ_COMPLETE_SCAN) { - if (priv->status == ACX_STATUS_1_SCANNING) { - if (OK != acx_s_complete_scan(priv)) { - SET_BIT(priv->after_interrupt_jobs, + if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_COMPLETE_SCAN) { + if (adev->status == ACX_STATUS_1_SCANNING) { + if (OK != acx_s_complete_scan(adev)) { + SET_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_RESTART_SCAN); } } else { @@ -6658,38 +6561,38 @@ acx_e_after_interrupt_task(void *data) ** background one? */ /* + was not verified that everything is restored ** (but at least we start to emit beacons again) */ - switch (priv->mode) { + switch (adev->mode) { case ACX_MODE_0_ADHOC: case ACX_MODE_3_AP: log(L_IRQ, "redoing cmd_join_bssid() after scan\n"); - acx_s_cmd_join_bssid(priv, priv->bssid); + acx_s_cmd_join_bssid(adev, adev->bssid); } } - CLEAR_BIT(priv->after_interrupt_jobs, ACX_AFTER_IRQ_COMPLETE_SCAN); + CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_COMPLETE_SCAN); } /* STA auth or assoc timed out, start over again */ - if (priv->after_interrupt_jobs & ACX_AFTER_IRQ_RESTART_SCAN) { + if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_RESTART_SCAN) { log(L_IRQ, "sending a start_scan cmd...\n"); - acx_s_cmd_start_scan(priv); - CLEAR_BIT(priv->after_interrupt_jobs, ACX_AFTER_IRQ_RESTART_SCAN); + acx_s_cmd_start_scan(adev); + CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_RESTART_SCAN); } /* whee, we got positive assoc response! 8) */ - if (priv->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_ASSOCIATE) { + if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_ASSOCIATE) { acx_ie_generic_t pdr; /* tiny race window exists, checking that we still a STA */ - switch (priv->mode) { + switch (adev->mode) { case ACX_MODE_2_STA: - pdr.m.aid = cpu_to_le16(priv->aid); - acx_s_configure(priv, &pdr, ACX1xx_IE_ASSOC_ID); - acx_set_status(priv, ACX_STATUS_4_ASSOCIATED); + pdr.m.aid = cpu_to_le16(adev->aid); + acx_s_configure(adev, &pdr, ACX1xx_IE_ASSOC_ID); + acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); log(L_ASSOC|L_DEBUG, "ASSOCIATED!\n"); - CLEAR_BIT(priv->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_ASSOCIATE); + CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_ASSOCIATE); } } end: - acx_sem_unlock(priv); + acx_sem_unlock(adev); FN_EXIT0; } @@ -6701,21 +6604,21 @@ end: ** the interrupt context. */ void -acx_schedule_task(wlandevice_t *priv, unsigned int set_flag) +acx_schedule_task(acx_device_t *adev, unsigned int set_flag) { - SET_BIT(priv->after_interrupt_jobs, set_flag); - SCHEDULE_WORK(&priv->after_interrupt_task); + SET_BIT(adev->after_interrupt_jobs, set_flag); + SCHEDULE_WORK(&adev->after_interrupt_task); } /*********************************************************************** */ void -acx_init_task_scheduler(wlandevice_t *priv) +acx_init_task_scheduler(acx_device_t *adev) { /* configure task scheduler */ - INIT_WORK(&priv->after_interrupt_task, acx_e_after_interrupt_task, - priv->netdev); + INIT_WORK(&adev->after_interrupt_task, acx_e_after_interrupt_task, + adev->ndev); } @@ -6723,7 +6626,7 @@ acx_init_task_scheduler(wlandevice_t *pr ** acx_s_start */ void -acx_s_start(wlandevice_t *priv) +acx_s_start(acx_device_t *adev) { FN_ENTER; @@ -6733,13 +6636,13 @@ acx_s_start(wlandevice_t *priv) * was up we get the changes asked for */ - SET_BIT(priv->set_mask, SET_TEMPLATES|SET_STA_LIST|GETSET_WEP + SET_BIT(adev->set_mask, SET_TEMPLATES|SET_STA_LIST|GETSET_WEP |GETSET_TXPOWER|GETSET_ANTENNA|GETSET_ED_THRESH|GETSET_CCA |GETSET_REG_DOMAIN|GETSET_MODE|GETSET_CHANNEL |GETSET_TX|GETSET_RX); log(L_INIT, "updating initial settings on iface activation\n"); - acx_s_update_card_settings(priv); + acx_s_update_card_settings(adev); FN_EXIT0; } @@ -6749,11 +6652,11 @@ acx_s_start(wlandevice_t *priv) ** acx_update_capabilities */ void -acx_update_capabilities(wlandevice_t *priv) +acx_update_capabilities(acx_device_t *adev) { u16 cap = 0; - switch (priv->mode) { + switch (adev->mode) { case ACX_MODE_3_AP: SET_BIT(cap, WF_MGMT_CAP_ESS); break; case ACX_MODE_0_ADHOC: @@ -6761,117 +6664,179 @@ acx_update_capabilities(wlandevice_t *pr /* other types of stations do not emit beacons */ } - if (priv->wep_restricted) { + if (adev->wep_restricted) { SET_BIT(cap, WF_MGMT_CAP_PRIVACY); } - if (priv->capab_short) { + if (adev->cfgopt_dot11ShortPreambleOption) { SET_BIT(cap, WF_MGMT_CAP_SHORT); } - if (priv->capab_pbcc) { + if (adev->cfgopt_dot11PBCCOption) { SET_BIT(cap, WF_MGMT_CAP_PBCC); } - if (priv->capab_agility) { + if (adev->cfgopt_dot11ChannelAgility) { SET_BIT(cap, WF_MGMT_CAP_AGILITY); } log(L_DEBUG, "caps updated from 0x%04X to 0x%04X\n", - priv->capabilities, cap); - priv->capabilities = cap; + adev->capabilities, cap); + adev->capabilities = cap; } -#ifdef UNUSED /*********************************************************************** -** FIXME: check whether this function is indeed acx111 only, -** rename ALL relevant definitions to indicate actual card scope! +** Common function to parse ALL configoption struct formats +** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?). +** FIXME: logging should be removed here and added to a /proc file instead */ void -acx111_s_read_configoption(wlandevice_t *priv) +acx_s_parse_configoption(acx_device_t *adev, const acx111_ie_configoption_t *pcfg) { - acx111_ie_configoption_t co, co2; - int i; const u8 *pEle; + int i; + int is_acx111 = IS_ACX111(adev); - if (OK != acx_s_interrogate(priv, &co, ACX111_IE_CONFIG_OPTIONS) ) { - return; - }; - if (!(acx_debug & L_DEBUG)) + if (acx_debug & L_DEBUG) { + printk("configoption struct content:\n"); + acx_dump_bytes(pcfg, sizeof(*pcfg)); + } + + if (( is_acx111 && (adev->eeprom_version == 5)) + || (!is_acx111 && (adev->eeprom_version == 4)) + || (!is_acx111 && (adev->eeprom_version == 5))) { + /* these versions are known to be supported */ + } else { + printk("unknown chip and EEPROM version combination (%s, v%d), " + "don't know how to parse config options yet. " + "Please report\n", is_acx111 ? "ACX111" : "ACX100", + adev->eeprom_version); return; + } - memcpy(&co2.configoption_fixed, &co.configoption_fixed, - sizeof(co.configoption_fixed)); + /* first custom-parse the first part which has chip-specific layout */ - pEle = (u8 *)&co.configoption_fixed + sizeof(co.configoption_fixed) - 4; + pEle = (const u8 *) pcfg; - co2.antennas.type = pEle[0]; - co2.antennas.len = pEle[1]; + pEle += 4; /* skip (type,len) header */ + + memcpy(adev->cfgopt_NVSv, pEle, sizeof(adev->cfgopt_NVSv)); + pEle += sizeof(adev->cfgopt_NVSv); + + if (is_acx111) { + adev->cfgopt_NVS_vendor_offs = le16_to_cpu(*(u16 *)pEle); + pEle += sizeof(adev->cfgopt_NVS_vendor_offs); + + adev->cfgopt_probe_delay = 200; /* good default value? */ + pEle += 2; /* FIXME: unknown, value 0x0001 */ + } else { + memcpy(adev->cfgopt_MAC, pEle, sizeof(adev->cfgopt_MAC)); + pEle += sizeof(adev->cfgopt_MAC); + + adev->cfgopt_probe_delay = le16_to_cpu(*(u16 *)pEle); + pEle += sizeof(adev->cfgopt_probe_delay); + if ((adev->cfgopt_probe_delay < 100) || (adev->cfgopt_probe_delay > 500)) { + printk("strange probe_delay value %d, " + "tweaking to 200\n", adev->cfgopt_probe_delay); + adev->cfgopt_probe_delay = 200; + } + } + + adev->cfgopt_eof_memory = le32_to_cpu(*(u32 *)pEle); + pEle += sizeof(adev->cfgopt_eof_memory); + + printk("NVS_vendor_offs:%04X probe_delay:%d eof_memory:%d\n", + adev->cfgopt_NVS_vendor_offs, + adev->cfgopt_probe_delay, + adev->cfgopt_eof_memory); + + adev->cfgopt_dot11CCAModes = *pEle++; + adev->cfgopt_dot11Diversity = *pEle++; + adev->cfgopt_dot11ShortPreambleOption = *pEle++; + adev->cfgopt_dot11PBCCOption = *pEle++; + adev->cfgopt_dot11ChannelAgility = *pEle++; + adev->cfgopt_dot11PhyType = *pEle++; + adev->cfgopt_dot11TempType = *pEle++; + printk("CCAModes:%02X Diversity:%02X ShortPreOpt:%02X " + "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n", + adev->cfgopt_dot11CCAModes, + adev->cfgopt_dot11Diversity, + adev->cfgopt_dot11ShortPreambleOption, + adev->cfgopt_dot11PBCCOption, + adev->cfgopt_dot11ChannelAgility, + adev->cfgopt_dot11PhyType, + adev->cfgopt_dot11TempType); + + /* then use common parsing for next part which has common layout */ + + pEle++; /* skip table_count (6) */ + + adev->cfgopt_antennas.type = pEle[0]; + adev->cfgopt_antennas.len = pEle[1]; printk("AntennaID:%02X Len:%02X Data:", - co2.antennas.type, co2.antennas.len); + adev->cfgopt_antennas.type, adev->cfgopt_antennas.len); for (i = 0; i < pEle[1]; i++) { - co2.antennas.list[i] = pEle[i+2]; + adev->cfgopt_antennas.list[i] = pEle[i+2]; printk("%02X ", pEle[i+2]); } printk("\n"); pEle += pEle[1] + 2; - co2.power_levels.type = pEle[0]; - co2.power_levels.len = pEle[1]; + adev->cfgopt_power_levels.type = pEle[0]; + adev->cfgopt_power_levels.len = pEle[1]; printk("PowerLevelID:%02X Len:%02X Data:", - co2.power_levels.type, co2.power_levels.len); - for (i = 0; i < pEle[1]*2; i++) { - co2.power_levels.list[i] = pEle[i+2]; - printk("%02X ", pEle[i+2]); + adev->cfgopt_power_levels.type, adev->cfgopt_power_levels.len); + for (i = 0; i < pEle[1]; i++) { + adev->cfgopt_power_levels.list[i] = le16_to_cpu(*(u16 *)&pEle[i*2+2]); + printk("%04X ", adev->cfgopt_power_levels.list[i]); } printk("\n"); pEle += pEle[1]*2 + 2; - co2.data_rates.type = pEle[0]; - co2.data_rates.len = pEle[1]; + adev->cfgopt_data_rates.type = pEle[0]; + adev->cfgopt_data_rates.len = pEle[1]; printk("DataRatesID:%02X Len:%02X Data:", - co2.data_rates.type, co2.data_rates.len); + adev->cfgopt_data_rates.type, adev->cfgopt_data_rates.len); for (i = 0; i < pEle[1]; i++) { - co2.data_rates.list[i] = pEle[i+2]; + adev->cfgopt_data_rates.list[i] = pEle[i+2]; printk("%02X ", pEle[i+2]); } printk("\n"); pEle += pEle[1] + 2; - co2.domains.type = pEle[0]; - co2.domains.len = pEle[1]; + adev->cfgopt_domains.type = pEle[0]; + adev->cfgopt_domains.len = pEle[1]; printk("DomainID:%02X Len:%02X Data:", - co2.domains.type, co2.domains.len); + adev->cfgopt_domains.type, adev->cfgopt_domains.len); for (i = 0; i < pEle[1]; i++) { - co2.domains.list[i] = pEle[i+2]; + adev->cfgopt_domains.list[i] = pEle[i+2]; printk("%02X ", pEle[i+2]); } printk("\n"); pEle += pEle[1] + 2; - co2.product_id.type = pEle[0]; - co2.product_id.len = pEle[1]; + adev->cfgopt_product_id.type = pEle[0]; + adev->cfgopt_product_id.len = pEle[1]; for (i = 0; i < pEle[1]; i++) { - co2.product_id.list[i] = pEle[i+2]; + adev->cfgopt_product_id.list[i] = pEle[i+2]; } printk("ProductID:%02X Len:%02X Data:%.*s\n", - co2.product_id.type, co2.product_id.len, - co2.product_id.len, (char *)co2.product_id.list); + adev->cfgopt_product_id.type, adev->cfgopt_product_id.len, + adev->cfgopt_product_id.len, (char *)adev->cfgopt_product_id.list); pEle += pEle[1] + 2; - co2.manufacturer.type = pEle[0]; - co2.manufacturer.len = pEle[1]; + adev->cfgopt_manufacturer.type = pEle[0]; + adev->cfgopt_manufacturer.len = pEle[1]; for (i = 0; i < pEle[1]; i++) { - co2.manufacturer.list[i] = pEle[i+2]; + adev->cfgopt_manufacturer.list[i] = pEle[i+2]; } printk("ManufacturerID:%02X Len:%02X Data:%.*s\n", - co2.manufacturer.type, co2.manufacturer.len, - co2.manufacturer.len, (char *)co2.manufacturer.list); + adev->cfgopt_manufacturer.type, adev->cfgopt_manufacturer.len, + adev->cfgopt_manufacturer.len, (char *)adev->cfgopt_manufacturer.list); /* printk("EEPROM part:\n"); for (i=0; i<58; i++) { printk("%02X =======> 0x%02X\n", - i, (u8 *)co.configoption_fixed.NVSv[i-2]); + i, (u8 *)adev->cfgopt_NVSv[i-2]); } */ } -#endif /*********************************************************************** diff -puN drivers/net/wireless/tiacx/conv.c~update-mm-acx-driver-to-version-0331 drivers/net/wireless/tiacx/conv.c --- devel/drivers/net/wireless/tiacx/conv.c~update-mm-acx-driver-to-version-0331 2006-01-31 18:11:09.000000000 -0800 +++ devel-akpm/drivers/net/wireless/tiacx/conv.c 2006-01-31 18:11:09.000000000 -0800 @@ -36,9 +36,7 @@ #include #include #include -#if WIRELESS_EXT >= 13 #include -#endif #include "acx.h" @@ -133,15 +131,14 @@ oui_is_8021h(const struct wlan_snap *sna ** Based largely on p80211conv.c of the linux-wlan-ng project */ int -acx_ether_to_txbuf(wlandevice_t *priv, void *txbuf, const struct sk_buff *skb) +acx_ether_to_txbuf(acx_device_t *adev, void *txbuf, const struct sk_buff *skb) { struct wlan_hdr_a3 *w_hdr; struct wlan_ethhdr *e_hdr; struct wlan_llc *e_llc; struct wlan_snap *e_snap; const u8 *a1, *a3; - int header_len, payload_len; - int result = -1; + int header_len, payload_len = -1; /* protocol type or data length, depending on whether * DIX or 802.3 ethernet format */ u16 proto; @@ -156,17 +153,17 @@ acx_ether_to_txbuf(wlandevice_t *priv, v w_hdr = (struct wlan_hdr_a3*)txbuf; - switch (priv->mode) { + switch (adev->mode) { case ACX_MODE_MONITOR: /* NB: one day we might want to play with DESC_CTL2_FCS ** Will need to stop doing "- WLAN_FCS_LEN" here then */ - if (skb->len >= WLAN_A4FR_MAXLEN_WEP_FCS - WLAN_FCS_LEN) { + if (unlikely(skb->len >= WLAN_A4FR_MAXLEN_WEP_FCS - WLAN_FCS_LEN)) { printk("%s: can't tx oversized frame (%d bytes)\n", - priv->netdev->name, skb->len); + adev->ndev->name, skb->len); goto end; } memcpy(w_hdr, skb->data, skb->len); - result = skb->len; + payload_len = skb->len; goto end; } @@ -208,18 +205,17 @@ acx_ether_to_txbuf(wlandevice_t *priv, v /* TODO: can we just let acx DMA payload from skb instead? */ memcpy((u8*)txbuf + header_len, skb->data + sizeof(wlan_ethhdr_t), payload_len); payload_len += header_len; - result = payload_len; /* Set up the 802.11 header */ - switch (priv->mode) { + switch (adev->mode) { case ACX_MODE_0_ADHOC: fc = (WF_FTYPE_DATAi | WF_FSTYPE_DATAONLYi); a1 = e_hdr->daddr; - a3 = priv->bssid; + a3 = adev->bssid; break; case ACX_MODE_2_STA: fc = (WF_FTYPE_DATAi | WF_FSTYPE_DATAONLYi | WF_FC_TODSi); - a1 = priv->bssid; + a1 = adev->bssid; a3 = e_hdr->daddr; break; case ACX_MODE_3_AP: @@ -229,17 +225,17 @@ acx_ether_to_txbuf(wlandevice_t *priv, v break; default: printk("%s: error - converting eth to wlan in unknown mode\n", - priv->netdev->name); - result = -1; + adev->ndev->name); + payload_len = -1; goto end; } - if (priv->wep_enabled) + if (adev->wep_enabled) SET_BIT(fc, WF_FC_ISWEPi); w_hdr->fc = fc; w_hdr->dur = 0; MAC_COPY(w_hdr->a1, a1); - MAC_COPY(w_hdr->a2, priv->dev_addr); + MAC_COPY(w_hdr->a2, adev->dev_addr); MAC_COPY(w_hdr->a3, a3); w_hdr->seq = 0; @@ -253,8 +249,8 @@ acx_ether_to_txbuf(wlandevice_t *priv, v #endif end: - FN_EXIT1(result); - return result; + FN_EXIT1(payload_len); + return payload_len; } @@ -270,7 +266,7 @@ end: ** Based largely on p80211conv.c of the linux-wlan-ng project */ struct sk_buff* -acx_rxbuf_to_ether(wlandevice_t *priv, rxbuffer_t *rxbuf) +acx_rxbuf_to_ether(acx_device_t *adev, rxbuffer_t *rxbuf) { struct wlan_hdr *w_hdr; struct wlan_ethhdr *e_hdr; @@ -288,7 +284,7 @@ acx_rxbuf_to_ether(wlandevice_t *priv, r /* This looks complex because it must handle possible ** phy header in rxbuff */ - w_hdr = acx_get_wlan_hdr(priv, rxbuf); + w_hdr = acx_get_wlan_hdr(adev, rxbuf); payload_offset = WLAN_HDR_A3_LEN; /* it is relative to w_hdr */ payload_length = RXBUF_BYTES_USED(rxbuf) /* entire rxbuff... */ - ((u8*)w_hdr - (u8*)rxbuf) /* minus space before 802.11 frame */ @@ -316,7 +312,7 @@ acx_rxbuf_to_ether(wlandevice_t *priv, r saddr = w_hdr->a4; } - if ((WF_FC_ISWEPi & fc) && IS_ACX100(priv)) { + if ((WF_FC_ISWEPi & fc) && IS_ACX100(adev)) { /* chop off the IV+ICV WEP header and footer */ log(L_DATA|L_DEBUG, "rx: WEP packet, " "chopping off IV and ICV\n"); @@ -325,15 +321,15 @@ acx_rxbuf_to_ether(wlandevice_t *priv, r } if (unlikely(payload_length < 0)) { - printk("%s: rx frame too short, ignored\n", priv->netdev->name); + printk("%s: rx frame too short, ignored\n", adev->ndev->name); goto ret_null; } e_hdr = (wlan_ethhdr_t*) ((u8*) w_hdr + payload_offset); e_llc = (wlan_llc_t*) e_hdr; e_snap = (wlan_snap_t*) (e_llc + 1); + mtu = adev->ndev->mtu; e_payload = (u8*) (e_snap + 1); - mtu = priv->netdev->mtu; log(L_DATA, "rx: payload_offset %d, payload_length %d\n", payload_offset, payload_length); @@ -357,7 +353,7 @@ acx_rxbuf_to_ether(wlandevice_t *priv, r if (unlikely(payload_length > (mtu + ETH_HLEN))) { printk("%s: rx: ENCAP frame too large (%d > %d)\n", - priv->netdev->name, + adev->ndev->name, payload_length, mtu + ETH_HLEN); goto ret_null; } @@ -388,7 +384,7 @@ acx_rxbuf_to_ether(wlandevice_t *priv, r if (unlikely(payload_length > mtu)) { printk("%s: rx: SNAP frame too large (%d > %d)\n", - priv->netdev->name, + adev->ndev->name, payload_length, mtu); goto ret_null; } @@ -424,7 +420,7 @@ acx_rxbuf_to_ether(wlandevice_t *priv, r payload_length -= sizeof(wlan_llc_t) + sizeof(wlan_snap_t); if (unlikely(payload_length > mtu)) { printk("%s: rx: DIXII frame too large (%d > %d)\n", - priv->netdev->name, + adev->ndev->name, payload_length, mtu); goto ret_null; } @@ -459,7 +455,7 @@ acx_rxbuf_to_ether(wlandevice_t *priv, r if (unlikely(payload_length > mtu)) { printk("%s: rx: OTHER frame too large (%d > %d)\n", - priv->netdev->name, payload_length, mtu); + adev->ndev->name, payload_length, mtu); goto ret_null; } @@ -481,13 +477,14 @@ acx_rxbuf_to_ether(wlandevice_t *priv, r memcpy(skb->data + ETH_HLEN, e_llc, payload_length); } - skb->dev = priv->netdev; - skb->protocol = eth_type_trans(skb, priv->netdev); + skb->dev = adev->ndev; + skb->protocol = eth_type_trans(skb, adev->ndev); #ifdef DEBUG_CONVERT if (acx_debug & L_DATA) { - printk("p802.11 frame [%d]: ", RXBUF_BYTES_RCVD(rxbuf)); - acx_dump_bytes(w_hdr, RXBUF_BYTES_RCVD(rxbuf)); + int len = RXBUF_BYTES_RCVD(adev, rxbuf); + printk("p802.11 frame [%d]: ", len); + acx_dump_bytes(w_hdr, len); printk("eth frame [%d]: ", skb->len); acx_dump_bytes(skb->data, skb->len); } @@ -498,7 +495,7 @@ acx_rxbuf_to_ether(wlandevice_t *priv, r no_skb: printk("%s: rx: no memory for skb (%d bytes)\n", - priv->netdev->name, buflen + 2); + adev->ndev->name, buflen + 2); ret_null: FN_EXIT1((int)NULL); return NULL; diff -puN drivers/net/wireless/tiacx/ioctl.c~update-mm-acx-driver-to-version-0331 drivers/net/wireless/tiacx/ioctl.c --- devel/drivers/net/wireless/tiacx/ioctl.c~update-mm-acx-driver-to-version-0331 2006-01-31 18:11:09.000000000 -0800 +++ devel-akpm/drivers/net/wireless/tiacx/ioctl.c 2006-01-31 18:11:09.000000000 -0800 @@ -35,13 +35,10 @@ #include #include #include -#include /* required for 2.4.x kernels; verify_write() */ - +//#include /* required for 2.4.x kernels; verify_write() */ #include #include -#if WIRELESS_EXT >= 13 #include -#endif /* WE >= 13 */ #include "acx.h" @@ -49,41 +46,6 @@ /*********************************************************************** */ -/* if you plan to reorder something, make sure to reorder all other places - * accordingly! */ -/* SET/GET convention: SETs must have even position, GETs odd */ -#define ACX100_IOCTL SIOCIWFIRSTPRIV -enum { - ACX100_IOCTL_DEBUG = ACX100_IOCTL, - ACX100_IOCTL_GET__________UNUSED1, - ACX100_IOCTL_SET_PLED, - ACX100_IOCTL_GET_PLED, - ACX100_IOCTL_SET_RATES, - ACX100_IOCTL_LIST_DOM, - ACX100_IOCTL_SET_DOM, - ACX100_IOCTL_GET_DOM, - ACX100_IOCTL_SET_SCAN_PARAMS, - ACX100_IOCTL_GET_SCAN_PARAMS, - ACX100_IOCTL_SET_PREAMB, - ACX100_IOCTL_GET_PREAMB, - ACX100_IOCTL_SET_ANT, - ACX100_IOCTL_GET_ANT, - ACX100_IOCTL_RX_ANT, - ACX100_IOCTL_TX_ANT, - ACX100_IOCTL_SET_PHY_AMP_BIAS, - ACX100_IOCTL_GET_PHY_CHAN_BUSY, - ACX100_IOCTL_SET_ED, - ACX100_IOCTL_GET__________UNUSED3, - ACX100_IOCTL_SET_CCA, - ACX100_IOCTL_GET__________UNUSED4, - ACX100_IOCTL_MONITOR, - ACX100_IOCTL_TEST, - ACX100_IOCTL_DBG_SET_MASKS, - ACX111_IOCTL_INFO, - ACX100_IOCTL_DBG_SET_IO, - ACX100_IOCTL_DBG_GET_IO -}; - /* channel frequencies * TODO: Currently, every other 802.11 driver keeps its own copy of this. In * the long run this should be integrated into ieee802_11.h or wireless.h or @@ -93,128 +55,24 @@ static const u16 acx_channel_freq[] = { 2447, 2452, 2457, 2462, 2467, 2472, 2484, }; -static const struct iw_priv_args acx_ioctl_private_args[] = { -#if ACX_DEBUG -{ cmd : ACX100_IOCTL_DEBUG, - set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - get_args : 0, - name : "SetDebug" }, -#endif -{ cmd : ACX100_IOCTL_SET_PLED, - set_args : IW_PRIV_TYPE_BYTE | 2, - get_args : 0, - name : "SetLEDPower" }, -{ cmd : ACX100_IOCTL_GET_PLED, - set_args : 0, - get_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 2, - name : "GetLEDPower" }, -{ cmd : ACX100_IOCTL_SET_RATES, - set_args : IW_PRIV_TYPE_CHAR | 256, - get_args : 0, - name : "SetRates" }, -{ cmd : ACX100_IOCTL_LIST_DOM, - set_args : 0, - get_args : 0, - name : "ListRegDomain" }, -{ cmd : ACX100_IOCTL_SET_DOM, - set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, - get_args : 0, - name : "SetRegDomain" }, -{ cmd : ACX100_IOCTL_GET_DOM, - set_args : 0, - get_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, - name : "GetRegDomain" }, -{ cmd : ACX100_IOCTL_SET_SCAN_PARAMS, - set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 4, - get_args : 0, - name : "SetScanParams" }, -{ cmd : ACX100_IOCTL_GET_SCAN_PARAMS, - set_args : 0, - get_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 4, - name : "GetScanParams" }, -{ cmd : ACX100_IOCTL_SET_PREAMB, - set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, - get_args : 0, - name : "SetSPreamble" }, -{ cmd : ACX100_IOCTL_GET_PREAMB, - set_args : 0, - get_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, - name : "GetSPreamble" }, -{ cmd : ACX100_IOCTL_SET_ANT, - set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, - get_args : 0, - name : "SetAntenna" }, -{ cmd : ACX100_IOCTL_GET_ANT, - set_args : 0, - get_args : 0, - name : "GetAntenna" }, -{ cmd : ACX100_IOCTL_RX_ANT, - set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, - get_args : 0, - name : "SetRxAnt" }, -{ cmd : ACX100_IOCTL_TX_ANT, - set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, - get_args : 0, - name : "SetTxAnt" }, -{ cmd : ACX100_IOCTL_SET_PHY_AMP_BIAS, - set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, - get_args : 0, - name : "SetPhyAmpBias"}, -{ cmd : ACX100_IOCTL_GET_PHY_CHAN_BUSY, - set_args : 0, - get_args : 0, - name : "GetPhyChanBusy" }, -{ cmd : ACX100_IOCTL_SET_ED, - set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - get_args : 0, - name : "SetED" }, -{ cmd : ACX100_IOCTL_SET_CCA, - set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, - get_args : 0, - name : "SetCCA" }, -{ cmd : ACX100_IOCTL_MONITOR, - set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, - get_args : 0, - name : "monitor" }, -{ cmd : ACX100_IOCTL_TEST, - set_args : 0, - get_args : 0, - name : "Test" }, -{ cmd : ACX100_IOCTL_DBG_SET_MASKS, - set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, - get_args : 0, - name : "DbgSetMasks" }, -{ cmd : ACX111_IOCTL_INFO, - set_args : 0, - get_args : 0, - name : "GetAcx111Info" }, -{ cmd : ACX100_IOCTL_DBG_SET_IO, - set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 4, - get_args : 0, - name : "DbgSetIO" }, -{ cmd : ACX100_IOCTL_DBG_GET_IO, - set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, - get_args : 0, - name : "DbgGetIO" }, -}; - /*********************************************************************** ** acx_ioctl_commit */ static int -acx_ioctl_commit(struct net_device *dev, - struct iw_request_info *info, - void *zwrq, char *extra) +acx_ioctl_commit(struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); FN_ENTER; - acx_sem_lock(priv); - if (ACX_STATE_IFACE_UP & priv->dev_state_mask) - acx_s_update_card_settings(priv); - acx_sem_unlock(priv); + acx_sem_lock(adev); + if (ACX_STATE_IFACE_UP & adev->dev_state_mask) + acx_s_update_card_settings(adev); + acx_sem_unlock(adev); FN_EXIT0; return OK; @@ -225,15 +83,15 @@ acx_ioctl_commit(struct net_device *dev, */ static int acx_ioctl_get_name( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - char *cwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); static const char * const names[] = { "IEEE 802.11b+/g+", "IEEE 802.11b+" }; - strcpy(cwrq, names[IS_ACX111(priv) ? 0 : 1]); + strcpy(wrqu->name, names[IS_ACX111(adev) ? 0 : 1]); return OK; } @@ -244,30 +102,30 @@ acx_ioctl_get_name( */ static int acx_ioctl_set_freq( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_freq *fwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); int channel = -1; unsigned int mult = 1; int result; FN_ENTER; - if (fwrq->e == 0 && fwrq->m <= 1000) { + if (wrqu->freq.e == 0 && wrqu->freq.m <= 1000) { /* Setting by channel number */ - channel = fwrq->m; + channel = wrqu->freq.m; } else { /* If setting by frequency, convert to a channel */ int i; - for (i = 0; i < (6 - fwrq->e); i++) + for (i = 0; i < (6 - wrqu->freq.e); i++) mult *= 10; for (i = 1; i <= 14; i++) - if (fwrq->m == acx_channel_freq[i - 1] * mult) + if (wrqu->freq.m == acx_channel_freq[i - 1] * mult) channel = i; } @@ -276,17 +134,17 @@ acx_ioctl_set_freq( goto end; } - acx_sem_lock(priv); + acx_sem_lock(adev); - priv->channel = channel; + adev->channel = channel; /* hmm, the following code part is strange, but this is how * it was being done before... */ log(L_IOCTL, "Changing to channel %d\n", channel); - SET_BIT(priv->set_mask, GETSET_CHANNEL); + SET_BIT(adev->set_mask, GETSET_CHANNEL); result = -EINPROGRESS; /* need to call commit handler */ - acx_sem_unlock(priv); + acx_sem_unlock(adev); end: FN_EXIT1(result); return result; @@ -297,14 +155,14 @@ end: */ static inline int acx_ioctl_get_freq( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_freq *fwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); - fwrq->e = 0; - fwrq->m = priv->channel; + acx_device_t *adev = ndev2adev(ndev); + wrqu->freq.e = 0; + wrqu->freq.m = adev->channel; return OK; } @@ -314,39 +172,37 @@ acx_ioctl_get_freq( */ static int acx_ioctl_set_mode( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - u32 *uwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); int result; FN_ENTER; - acx_sem_lock(priv); + acx_sem_lock(adev); - switch (*uwrq) { + switch (wrqu->mode) { case IW_MODE_AUTO: - priv->mode = ACX_MODE_OFF; + adev->mode = ACX_MODE_OFF; break; -#if WIRELESS_EXT > 14 case IW_MODE_MONITOR: - priv->mode = ACX_MODE_MONITOR; + adev->mode = ACX_MODE_MONITOR; break; -#endif /* WIRELESS_EXT > 14 */ case IW_MODE_ADHOC: - priv->mode = ACX_MODE_0_ADHOC; + adev->mode = ACX_MODE_0_ADHOC; break; case IW_MODE_INFRA: - priv->mode = ACX_MODE_2_STA; + adev->mode = ACX_MODE_2_STA; break; case IW_MODE_MASTER: printk("acx: master mode (HostAP) is very, very " "experimental! It might work partially, but " "better get prepared for nasty surprises " "at any time\n"); - priv->mode = ACX_MODE_3_AP; + adev->mode = ACX_MODE_3_AP; break; case IW_MODE_REPEAT: case IW_MODE_SECOND: @@ -355,12 +211,12 @@ acx_ioctl_set_mode( goto end_unlock; } - log(L_ASSOC, "new priv->mode=%d\n", priv->mode); - SET_BIT(priv->set_mask, GETSET_MODE); + log(L_ASSOC, "new adev->mode=%d\n", adev->mode); + SET_BIT(adev->set_mask, GETSET_MODE); result = -EINPROGRESS; end_unlock: - acx_sem_unlock(priv); + acx_sem_unlock(adev); FN_EXIT1(result); return result; @@ -371,27 +227,25 @@ end_unlock: */ static int acx_ioctl_get_mode( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - u32 *uwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); int result = 0; - switch (priv->mode) { + switch (adev->mode) { case ACX_MODE_OFF: - *uwrq = IW_MODE_AUTO; break; -#if WIRELESS_EXT > 14 + wrqu->mode = IW_MODE_AUTO; break; case ACX_MODE_MONITOR: - *uwrq = IW_MODE_MONITOR; break; -#endif /* WIRELESS_EXT > 14 */ + wrqu->mode = IW_MODE_MONITOR; break; case ACX_MODE_0_ADHOC: - *uwrq = IW_MODE_ADHOC; break; + wrqu->mode = IW_MODE_ADHOC; break; case ACX_MODE_2_STA: - *uwrq = IW_MODE_INFRA; break; + wrqu->mode = IW_MODE_INFRA; break; case ACX_MODE_3_AP: - *uwrq = IW_MODE_MASTER; break; + wrqu->mode = IW_MODE_MASTER; break; default: result = -EOPNOTSUPP; } @@ -403,19 +257,20 @@ acx_ioctl_get_mode( */ static int acx_ioctl_set_sens( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct iw_param *vwrq = &wrqu->sens; + acx_device_t *adev = ndev2adev(ndev); - acx_sem_lock(priv); + acx_sem_lock(adev); - priv->sensitivity = (1 == vwrq->disabled) ? 0 : vwrq->value; - SET_BIT(priv->set_mask, GETSET_SENSITIVITY); + adev->sensitivity = (1 == vwrq->disabled) ? 0 : vwrq->value; + SET_BIT(adev->set_mask, GETSET_SENSITIVITY); - acx_sem_unlock(priv); + acx_sem_unlock(adev); return -EINPROGRESS; } @@ -425,20 +280,25 @@ acx_ioctl_set_sens( */ static int acx_ioctl_get_sens( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct iw_param *vwrq = &wrqu->sens; + acx_device_t *adev = ndev2adev(ndev); + + if (IS_USB(adev)) + /* setting the PHY reg via fw cmd doesn't work yet */ + return -EOPNOTSUPP; - /* acx_sem_lock(priv); */ + /* acx_sem_lock(adev); */ - vwrq->value = priv->sensitivity; + vwrq->value = adev->sensitivity; vwrq->disabled = (vwrq->value == 0); vwrq->fixed = 1; - /* acx_sem_unlock(priv); */ + /* acx_sem_unlock(adev); */ return OK; } @@ -451,12 +311,13 @@ acx_ioctl_get_sens( */ static int acx_ioctl_set_ap( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct sockaddr *awrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct sockaddr *awrq = &wrqu->ap_addr; + acx_device_t *adev = ndev2adev(ndev); int result = 0; const u8 *ap; @@ -473,24 +334,24 @@ acx_ioctl_set_ap( ap = awrq->sa_data; acxlog_mac(L_IOCTL, "set AP=", ap, "\n"); - MAC_COPY(priv->ap, ap); + MAC_COPY(adev->ap, ap); /* We want to start rescan in managed or ad-hoc mode, - ** otherwise just set priv->ap. + ** otherwise just set adev->ap. ** "iwconfig ap mode managed": we must be able ** to set ap _first_ and _then_ set mode */ - switch (priv->mode) { + switch (adev->mode) { case ACX_MODE_0_ADHOC: case ACX_MODE_2_STA: /* FIXME: if there is a convention on what zero AP means, ** please add a comment about that. I don't know of any --vda */ if (mac_is_zero(ap)) { /* "off" == 00:00:00:00:00:00 */ - MAC_BCAST(priv->ap); + MAC_BCAST(adev->ap); log(L_IOCTL, "Not reassociating\n"); } else { log(L_IOCTL, "Forcing reassociation\n"); - SET_BIT(priv->set_mask, GETSET_RESCAN); + SET_BIT(adev->set_mask, GETSET_RESCAN); } break; } @@ -505,16 +366,17 @@ end: */ static int acx_ioctl_get_ap( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct sockaddr *awrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct sockaddr *awrq = &wrqu->ap_addr; + acx_device_t *adev = ndev2adev(ndev); - if (ACX_STATUS_4_ASSOCIATED == priv->status) { + if (ACX_STATUS_4_ASSOCIATED == adev->status) { /* as seen in Aironet driver, airo.c */ - MAC_COPY(awrq->sa_data, priv->bssid); + MAC_COPY(awrq->sa_data, adev->bssid); } else { MAC_ZERO(awrq->sa_data); } @@ -532,12 +394,13 @@ acx_ioctl_get_ap( */ static int acx_ioctl_get_aplist( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_point *dwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct iw_point *dwrq = &wrqu->data; + acx_device_t *adev = ndev2adev(ndev); struct sockaddr *address = (struct sockaddr *) extra; struct iw_quality qual[IW_MAX_AP]; int i, cur; @@ -546,14 +409,14 @@ acx_ioctl_get_aplist( FN_ENTER; /* we have AP list only in STA mode */ - if (ACX_MODE_2_STA != priv->mode) { + if (ACX_MODE_2_STA != adev->mode) { result = -EOPNOTSUPP; goto end; } cur = 0; - for (i = 0; i < VEC_SIZE(priv->sta_list); i++) { - struct client *bss = &priv->sta_list[i]; + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + struct client *bss = &adev->sta_list[i]; if (!bss->used) continue; MAC_COPY(address[cur].sa_data, bss->bssid); address[cur].sa_family = ARPHRD_ETHER; @@ -586,45 +449,44 @@ end: */ static int acx_ioctl_set_scan( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); int result; FN_ENTER; - acx_sem_lock(priv); + acx_sem_lock(adev); /* don't start scan if device is not up yet */ - if (!(priv->dev_state_mask & ACX_STATE_IFACE_UP)) { + if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) { result = -EAGAIN; goto end_unlock; } /* This is NOT a rescan for new AP! ** Do not use SET_BIT(GETSET_RESCAN); */ - acx_s_cmd_start_scan(priv); + acx_s_cmd_start_scan(adev); result = OK; end_unlock: - acx_sem_unlock(priv); + acx_sem_unlock(adev); /* end: */ FN_EXIT1(result); return result; } -#if WIRELESS_EXT > 13 /*********************************************************************** ** acx_s_scan_add_station */ -/* helper. not sure wheter it's really a _s_leeping fn */ +/* helper. not sure whether it's really a _s_leeping fn */ static char* acx_s_scan_add_station( - wlandevice_t *priv, + acx_device_t *adev, char *ptr, char *end_buf, struct client *bss) @@ -728,64 +590,65 @@ acx_s_scan_add_station( */ static int acx_ioctl_get_scan( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_point *dwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct iw_point *dwrq = &wrqu->data; + acx_device_t *adev = ndev2adev(ndev); char *ptr = extra; int i; int result = OK; FN_ENTER; - acx_sem_lock(priv); + acx_sem_lock(adev); /* no scan available if device is not up yet */ - if (!(priv->dev_state_mask & ACX_STATE_IFACE_UP)) { + if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) { log(L_IOCTL, "iface not up yet\n"); result = -EAGAIN; goto end_unlock; } #ifdef ENODATA_TO_BE_USED_AFTER_SCAN_ERROR_ONLY - if (priv->bss_table_count == 0) { + if (adev->bss_table_count == 0) { /* no stations found */ result = -ENODATA; goto end_unlock; } #endif - for (i = 0; i < VEC_SIZE(priv->sta_list); i++) { - struct client *bss = &priv->sta_list[i]; + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + struct client *bss = &adev->sta_list[i]; if (!bss->used) continue; - ptr = acx_s_scan_add_station(priv, ptr, + ptr = acx_s_scan_add_station(adev, ptr, extra + IW_SCAN_MAX_DATA, bss); } dwrq->length = ptr - extra; dwrq->flags = 0; end_unlock: - acx_sem_unlock(priv); + acx_sem_unlock(adev); /* end: */ FN_EXIT1(result); return result; } -#endif /* WIRELESS_EXT > 13 */ -/*---------------------------------------------------------------- -* acx_ioctl_set_essid -*----------------------------------------------------------------*/ +/*********************************************************************** +** acx_ioctl_set_essid +*/ static int acx_ioctl_set_essid( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_point *dwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct iw_point *dwrq = &wrqu->essid; + acx_device_t *adev = ndev2adev(ndev); int len = dwrq->length; int result; @@ -799,11 +662,11 @@ acx_ioctl_set_essid( log(L_IOCTL, "set ESSID '%*s', length %d, flags 0x%04X\n", len, extra, len, dwrq->flags); - acx_sem_lock(priv); + acx_sem_lock(adev); /* ESSID disabled? */ if (0 == dwrq->flags) { - priv->essid_active = 0; + adev->essid_active = 0; } else { if (dwrq->length > IW_ESSID_MAX_SIZE+1) { @@ -811,21 +674,21 @@ acx_ioctl_set_essid( goto end_unlock; } - if (len > sizeof(priv->essid)) - len = sizeof(priv->essid); - memcpy(priv->essid, extra, len-1); - priv->essid[len-1] = '\0'; + if (len > sizeof(adev->essid)) + len = sizeof(adev->essid); + memcpy(adev->essid, extra, len-1); + adev->essid[len-1] = '\0'; /* Paranoia: just in case there is a '\0'... */ - priv->essid_len = strlen(priv->essid); - priv->essid_active = 1; + adev->essid_len = strlen(adev->essid); + adev->essid_active = 1; } - SET_BIT(priv->set_mask, GETSET_RESCAN); + SET_BIT(adev->set_mask, GETSET_RESCAN); result = -EINPROGRESS; end_unlock: - acx_sem_unlock(priv); + acx_sem_unlock(adev); end: FN_EXIT1(result); return result; @@ -836,18 +699,19 @@ end: */ static int acx_ioctl_get_essid( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_point *dwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct iw_point *dwrq = &wrqu->essid; + acx_device_t *adev = ndev2adev(ndev); - dwrq->flags = priv->essid_active; - if (priv->essid_active) { - memcpy(extra, priv->essid, priv->essid_len); - extra[priv->essid_len] = '\0'; - dwrq->length = priv->essid_len + 1; + dwrq->flags = adev->essid_active; + if (adev->essid_active) { + memcpy(extra, adev->essid, adev->essid_len); + extra[adev->essid_len] = '\0'; + dwrq->length = adev->essid_len + 1; dwrq->flags = 1; } return OK; @@ -858,18 +722,18 @@ acx_ioctl_get_essid( ** acx_l_update_client_rates */ static void -acx_l_update_client_rates(wlandevice_t *priv, u16 rate) +acx_l_update_client_rates(acx_device_t *adev, u16 rate) { int i; - for (i = 0; i < VEC_SIZE(priv->sta_list); i++) { - client_t *clt = &priv->sta_list[i]; + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + client_t *clt = &adev->sta_list[i]; if (!clt->used) continue; clt->rate_cfg = (clt->rate_cap & rate); if (!clt->rate_cfg) { /* no compatible rates left: kick client */ acxlog_mac(L_ASSOC, "client ",clt->address," kicked: " "rates are not compatible anymore\n"); - acx_l_sta_list_del(priv, clt); + acx_l_sta_list_del(adev, clt); continue; } clt->rate_cur &= clt->rate_cfg; @@ -877,16 +741,16 @@ acx_l_update_client_rates(wlandevice_t * /* current rate become invalid, choose a valid one */ clt->rate_cur = 1 << lowest_bit(clt->rate_cfg); } - if (IS_ACX100(priv)) + if (IS_ACX100(adev)) clt->rate_100 = acx_bitpos2rate100[highest_bit(clt->rate_cur)]; clt->fallback_count = clt->stepup_count = 0; clt->ignore_count = 16; } - switch (priv->mode) { + switch (adev->mode) { case ACX_MODE_2_STA: - if (priv->ap_client && !priv->ap_client->used) { + if (adev->ap_client && !adev->ap_client->used) { /* Owwww... we kicked our AP!! :) */ - SET_BIT(priv->set_mask, GETSET_RESCAN); + SET_BIT(adev->set_mask, GETSET_RESCAN); } } } @@ -920,12 +784,13 @@ acx111_rate_tbl[] = { */ static int acx_ioctl_set_rate( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct iw_param *vwrq = &wrqu->param; + acx_device_t *adev = ndev2adev(ndev); u16 txrate_cfg = 1; unsigned long flags; int autorate; @@ -939,7 +804,7 @@ acx_ioctl_set_rate( int i = VEC_SIZE(acx111_rate_tbl)-1; if (vwrq->value == -1) /* "iwconfig rate auto" --> choose highest */ - vwrq->value = IS_ACX100(priv) ? 22000000 : 54000000; + vwrq->value = IS_ACX100(adev) ? 22000000 : 54000000; while (i >= 0) { if (vwrq->value == acx111_rate_tbl[i]) { txrate_cfg <<= i; @@ -965,7 +830,7 @@ acx_ioctl_set_rate( txrate_cfg = (txrate_cfg<<1)-1; } - if (IS_ACX100(priv)) { + if (IS_ACX100(adev)) { txrate_cfg &= RATE111_ACX100_COMPAT; if (!txrate_cfg) { result = -ENOTSUPP; /* rate is not supported by acx100 */ @@ -973,31 +838,31 @@ acx_ioctl_set_rate( } } - acx_sem_lock(priv); - acx_lock(priv, flags); + acx_sem_lock(adev); + acx_lock(adev, flags); - priv->rate_auto = autorate; - priv->rate_oper = txrate_cfg; - priv->rate_basic = txrate_cfg; + adev->rate_auto = autorate; + adev->rate_oper = txrate_cfg; + adev->rate_basic = txrate_cfg; /* only do that in auto mode, non-auto will be able to use * one specific Tx rate only anyway */ if (autorate) { /* only use 802.11b base rates, for standard 802.11b H/W * compatibility */ - priv->rate_basic &= RATE111_80211B_COMPAT; + adev->rate_basic &= RATE111_80211B_COMPAT; } - priv->rate_bcast = 1 << lowest_bit(txrate_cfg); - if (IS_ACX100(priv)) - priv->rate_bcast100 = acx_rate111to100(priv->rate_bcast); - acx_l_update_ratevector(priv); - acx_l_update_client_rates(priv, txrate_cfg); + adev->rate_bcast = 1 << lowest_bit(txrate_cfg); + if (IS_ACX100(adev)) + adev->rate_bcast100 = acx_rate111to100(adev->rate_bcast); + acx_l_update_ratevector(adev); + acx_l_update_client_rates(adev, txrate_cfg); /* Do/don't do tx rate fallback; beacon contents and rate */ - SET_BIT(priv->set_mask, SET_RATE_FALLBACK|SET_TEMPLATES); + SET_BIT(adev->set_mask, SET_RATE_FALLBACK|SET_TEMPLATES); result = -EINPROGRESS; - acx_unlock(priv, flags); - acx_sem_unlock(priv); + acx_unlock(adev, flags); + acx_sem_unlock(adev); end: FN_EXIT1(result); return result; @@ -1009,35 +874,37 @@ end: */ static int acx_ioctl_get_rate( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct iw_param *vwrq = &wrqu->param; + acx_device_t *adev = ndev2adev(ndev); unsigned long flags; u16 rate; - acx_lock(priv, flags); - rate = priv->rate_oper; - if (priv->ap_client) - rate = priv->ap_client->rate_cur; + acx_lock(adev, flags); + rate = adev->rate_oper; + if (adev->ap_client) + rate = adev->ap_client->rate_cur; vwrq->value = acx111_rate_tbl[highest_bit(rate)]; - vwrq->fixed = !priv->rate_auto; + vwrq->fixed = !adev->rate_auto; vwrq->disabled = 0; - acx_unlock(priv, flags); + acx_unlock(adev, flags); return OK; } static int acx_ioctl_set_rts( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct iw_param *vwrq = &wrqu->rts; + acx_device_t *adev = ndev2adev(ndev); int val = vwrq->value; if (vwrq->disabled) @@ -1045,37 +912,78 @@ acx_ioctl_set_rts( if ((val < 0) || (val > 2312)) return -EINVAL; - priv->rts_threshold = val; + adev->rts_threshold = val; return OK; } static inline int acx_ioctl_get_rts( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct iw_param *vwrq = &wrqu->rts; + acx_device_t *adev = ndev2adev(ndev); - vwrq->value = priv->rts_threshold; + vwrq->value = adev->rts_threshold; vwrq->disabled = (vwrq->value >= 2312); vwrq->fixed = 1; return OK; } +#if ACX_FRAGMENTATION +static int +acx_ioctl_set_frag( + struct net_device *ndev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int val = vwrq->value; + + if (vwrq->disabled) + val = 32767; + else + if ((val < 256) || (val > 2347)) + return -EINVAL; + + adev->frag_threshold = val; + return OK; +} + +static inline int +acx_ioctl_get_frag( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->frag; + acx_device_t *adev = ndev2adev(ndev); + + vwrq->value = adev->frag_threshold; + vwrq->disabled = (vwrq->value >= 2347); + vwrq->fixed = 1; + return OK; +} +#endif + + /*********************************************************************** ** acx_ioctl_set_encode */ static int acx_ioctl_set_encode( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_point *dwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct iw_point *dwrq = &wrqu->encoding; + acx_device_t *adev = ndev2adev(ndev); int index; int result; @@ -1084,14 +992,14 @@ acx_ioctl_set_encode( log(L_IOCTL, "set encoding flags=0x%04X, size=%d, key: %s\n", dwrq->flags, dwrq->length, extra ? "set" : "No key"); - acx_sem_lock(priv); + acx_sem_lock(adev); index = (dwrq->flags & IW_ENCODE_INDEX) - 1; if (dwrq->length > 0) { /* if index is 0 or invalid, use default key */ if ((index < 0) || (index > 3)) - index = (int)priv->wep_current_index; + index = (int)adev->wep_current_index; if (0 == (dwrq->flags & IW_ENCODE_NOKEY)) { if (dwrq->length > 29) @@ -1099,26 +1007,26 @@ acx_ioctl_set_encode( if (dwrq->length > 13) { /* 29*8 == 232, WEP256 */ - priv->wep_keys[index].size = 29; + adev->wep_keys[index].size = 29; } else if (dwrq->length > 5) { /* 13*8 == 104bit, WEP128 */ - priv->wep_keys[index].size = 13; + adev->wep_keys[index].size = 13; } else if (dwrq->length > 0) { /* 5*8 == 40bit, WEP64 */ - priv->wep_keys[index].size = 5; + adev->wep_keys[index].size = 5; } else { /* disable key */ - priv->wep_keys[index].size = 0; + adev->wep_keys[index].size = 0; } - memset(priv->wep_keys[index].key, 0, - sizeof(priv->wep_keys[index].key)); - memcpy(priv->wep_keys[index].key, extra, dwrq->length); + memset(adev->wep_keys[index].key, 0, + sizeof(adev->wep_keys[index].key)); + memcpy(adev->wep_keys[index].key, extra, dwrq->length); } } else { /* set transmit key */ if ((index >= 0) && (index <= 3)) - priv->wep_current_index = index; + adev->wep_current_index = index; else if (0 == (dwrq->flags & IW_ENCODE_MODE)) { /* complain if we were not just setting * the key mode */ @@ -1127,35 +1035,35 @@ acx_ioctl_set_encode( } } - priv->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED); + adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED); if (dwrq->flags & IW_ENCODE_OPEN) { - priv->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM; - priv->wep_restricted = 0; + adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM; + adev->wep_restricted = 0; } else if (dwrq->flags & IW_ENCODE_RESTRICTED) { - priv->auth_alg = WLAN_AUTH_ALG_SHAREDKEY; - priv->wep_restricted = 1; + adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY; + adev->wep_restricted = 1; } /* set flag to make sure the card WEP settings get updated */ - SET_BIT(priv->set_mask, GETSET_WEP); + SET_BIT(adev->set_mask, GETSET_WEP); log(L_IOCTL, "len=%d, key at 0x%p, flags=0x%X\n", dwrq->length, extra, dwrq->flags); for (index = 0; index <= 3; index++) { - if (priv->wep_keys[index].size) { + if (adev->wep_keys[index].size) { log(L_IOCTL, "index=%d, size=%d, key at 0x%p\n", - priv->wep_keys[index].index, - (int) priv->wep_keys[index].size, - priv->wep_keys[index].key); + adev->wep_keys[index].index, + (int) adev->wep_keys[index].size, + adev->wep_keys[index].key); } } result = -EINPROGRESS; end_unlock: - acx_sem_unlock(priv); + acx_sem_unlock(adev); FN_EXIT1(result); return result; @@ -1167,28 +1075,29 @@ end_unlock: */ static int acx_ioctl_get_encode( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_point *dwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct iw_point *dwrq = &wrqu->encoding; + acx_device_t *adev = ndev2adev(ndev); int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; FN_ENTER; - if (priv->wep_enabled == 0) { + if (adev->wep_enabled == 0) { dwrq->flags = IW_ENCODE_DISABLED; } else { if ((index < 0) || (index > 3)) - index = (int)priv->wep_current_index; + index = (int)adev->wep_current_index; - dwrq->flags = (priv->wep_restricted == 1) ? + dwrq->flags = (adev->wep_restricted == 1) ? IW_ENCODE_RESTRICTED : IW_ENCODE_OPEN; - dwrq->length = priv->wep_keys[index].size; + dwrq->length = adev->wep_keys[index].size; - memcpy(extra, priv->wep_keys[index].key, - priv->wep_keys[index].size); + memcpy(extra, adev->wep_keys[index].key, + adev->wep_keys[index].size); } /* set the current index */ @@ -1207,23 +1116,24 @@ acx_ioctl_get_encode( */ static int acx_ioctl_set_power( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct iw_param *vwrq = &wrqu->power; + acx_device_t *adev = ndev2adev(ndev); int result = -EINPROGRESS; FN_ENTER; log(L_IOCTL, "set 802.11 powersave flags=0x%04X\n", vwrq->flags); - acx_sem_lock(priv); + acx_sem_lock(adev); if (vwrq->disabled) { - CLEAR_BIT(priv->ps_wakeup_cfg, PS_CFG_ENABLE); - SET_BIT(priv->set_mask, GETSET_POWER_80211); + CLEAR_BIT(adev->ps_wakeup_cfg, PS_CFG_ENABLE); + SET_BIT(adev->set_mask, GETSET_POWER_80211); goto end; } if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { @@ -1233,7 +1143,7 @@ acx_ioctl_set_power( ps_timeout = 255; log(L_IOCTL, "setting PS timeout value to %d time units " "due to %dus\n", ps_timeout, vwrq->value); - priv->ps_hangover_period = ps_timeout; + adev->ps_hangover_period = ps_timeout; } else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) { u16 ps_periods = vwrq->value / 1000000; @@ -1241,21 +1151,21 @@ acx_ioctl_set_power( ps_periods = 255; log(L_IOCTL, "setting PS period value to %d periods " "due to %dus\n", ps_periods, vwrq->value); - priv->ps_listen_interval = ps_periods; - CLEAR_BIT(priv->ps_wakeup_cfg, PS_CFG_WAKEUP_MODE_MASK); - SET_BIT(priv->ps_wakeup_cfg, PS_CFG_WAKEUP_EACH_ITVL); + adev->ps_listen_interval = ps_periods; + CLEAR_BIT(adev->ps_wakeup_cfg, PS_CFG_WAKEUP_MODE_MASK); + SET_BIT(adev->ps_wakeup_cfg, PS_CFG_WAKEUP_EACH_ITVL); } switch (vwrq->flags & IW_POWER_MODE) { /* FIXME: are we doing the right thing here? */ case IW_POWER_UNICAST_R: - CLEAR_BIT(priv->ps_options, PS_OPT_STILL_RCV_BCASTS); + CLEAR_BIT(adev->ps_options, PS_OPT_STILL_RCV_BCASTS); break; case IW_POWER_MULTICAST_R: - SET_BIT(priv->ps_options, PS_OPT_STILL_RCV_BCASTS); + SET_BIT(adev->ps_options, PS_OPT_STILL_RCV_BCASTS); break; case IW_POWER_ALL_R: - SET_BIT(priv->ps_options, PS_OPT_STILL_RCV_BCASTS); + SET_BIT(adev->ps_options, PS_OPT_STILL_RCV_BCASTS); break; case IW_POWER_ON: break; @@ -1265,10 +1175,10 @@ acx_ioctl_set_power( goto end; } - SET_BIT(priv->ps_wakeup_cfg, PS_CFG_ENABLE); - SET_BIT(priv->set_mask, GETSET_POWER_80211); + SET_BIT(adev->ps_wakeup_cfg, PS_CFG_ENABLE); + SET_BIT(adev->set_mask, GETSET_POWER_80211); end: - acx_sem_unlock(priv); + acx_sem_unlock(adev); FN_EXIT1(result); return result; @@ -1279,28 +1189,29 @@ end: */ static int acx_ioctl_get_power( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct iw_param *vwrq = &wrqu->power; + acx_device_t *adev = ndev2adev(ndev); FN_ENTER; log(L_IOCTL, "Get 802.11 Power Save flags = 0x%04X\n", vwrq->flags); - vwrq->disabled = ((priv->ps_wakeup_cfg & PS_CFG_ENABLE) == 0); + vwrq->disabled = ((adev->ps_wakeup_cfg & PS_CFG_ENABLE) == 0); if (vwrq->disabled) goto end; if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { - vwrq->value = priv->ps_hangover_period * 1000 / 1024; + vwrq->value = adev->ps_hangover_period * 1000 / 1024; vwrq->flags = IW_POWER_TIMEOUT; } else { - vwrq->value = priv->ps_listen_interval * 1000000; + vwrq->value = adev->ps_listen_interval * 1000000; vwrq->flags = IW_POWER_PERIOD|IW_POWER_RELATIVE; } - if (priv->ps_options & PS_OPT_STILL_RCV_BCASTS) + if (adev->ps_options & PS_OPT_STILL_RCV_BCASTS) SET_BIT(vwrq->flags, IW_POWER_ALL_R); else SET_BIT(vwrq->flags, IW_POWER_UNICAST_R); @@ -1315,21 +1226,22 @@ end: */ static inline int acx_ioctl_get_txpow( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct iw_param *vwrq = &wrqu->power; + acx_device_t *adev = ndev2adev(ndev); FN_ENTER; vwrq->flags = IW_TXPOW_DBM; vwrq->disabled = 0; vwrq->fixed = 1; - vwrq->value = priv->tx_level_dbm; + vwrq->value = adev->tx_level_dbm; - log(L_IOCTL, "get txpower:%d dBm\n", priv->tx_level_dbm); + log(L_IOCTL, "get txpower:%d dBm\n", adev->tx_level_dbm); FN_EXIT1(OK); return OK; @@ -1341,12 +1253,13 @@ acx_ioctl_get_txpow( */ static int acx_ioctl_set_txpow( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct iw_param *vwrq = &wrqu->power; + acx_device_t *adev = ndev2adev(ndev); int result; FN_ENTER; @@ -1354,31 +1267,31 @@ acx_ioctl_set_txpow( log(L_IOCTL, "set txpower:%d, disabled:%d, flags:0x%04X\n", vwrq->value, vwrq->disabled, vwrq->flags); - acx_sem_lock(priv); + acx_sem_lock(adev); - if (vwrq->disabled != priv->tx_disabled) { - SET_BIT(priv->set_mask, GETSET_TX); + if (vwrq->disabled != adev->tx_disabled) { + SET_BIT(adev->set_mask, GETSET_TX); } - priv->tx_disabled = vwrq->disabled; + adev->tx_disabled = vwrq->disabled; if (vwrq->value == -1) { if (vwrq->disabled) { - priv->tx_level_dbm = 0; + adev->tx_level_dbm = 0; log(L_IOCTL, "disable radio tx\n"); } else { - /* priv->tx_level_auto = 1; */ + /* adev->tx_level_auto = 1; */ log(L_IOCTL, "set tx power auto (NIY)\n"); } } else { - priv->tx_level_dbm = vwrq->value <= 20 ? vwrq->value : 20; - /* priv->tx_level_auto = 0; */ - log(L_IOCTL, "set txpower=%d dBm\n", priv->tx_level_dbm); + adev->tx_level_dbm = vwrq->value <= 20 ? vwrq->value : 20; + /* adev->tx_level_auto = 0; */ + log(L_IOCTL, "set txpower=%d dBm\n", adev->tx_level_dbm); } - SET_BIT(priv->set_mask, GETSET_TXPOWER); + SET_BIT(adev->set_mask, GETSET_TXPOWER); result = -EINPROGRESS; - acx_sem_unlock(priv); + acx_sem_unlock(adev); FN_EXIT1(result); return result; @@ -1390,13 +1303,14 @@ acx_ioctl_set_txpow( */ static int acx_ioctl_get_range( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_point *dwrq, + union iwreq_data *wrqu, char *extra) { + struct iw_point *dwrq = &wrqu->data; struct iw_range *range = (struct iw_range *)extra; - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); int i,n; FN_ENTER; @@ -1408,7 +1322,7 @@ acx_ioctl_get_range( memset(range, 0, sizeof(struct iw_range)); n = 0; for (i = 1; i <= 14; i++) { - if (priv->reg_dom_chanmask & (1 << (i - 1))) { + if (adev->reg_dom_chanmask & (1 << (i - 1))) { range->freq[n].i = i; range->freq[n].m = acx_channel_freq[i - 1] * 100000; range->freq[n].e = 1; /* units are MHz */ @@ -1420,9 +1334,11 @@ acx_ioctl_get_range( range->min_rts = 0; range->max_rts = 2312; - /* range->min_frag = 256; - * range->max_frag = 2312; - */ + +#if ACX_FRAGMENTATION + range->min_frag = 256; + range->max_frag = 2312; +#endif range->encoding_size[0] = 5; range->encoding_size[1] = 13; @@ -1438,10 +1354,20 @@ acx_ioctl_get_range( range->pmt_flags = IW_POWER_TIMEOUT; range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R; - for (i = 0; i <= IW_MAX_TXPOWER - 1; i++) - range->txpower[i] = 20 * i / (IW_MAX_TXPOWER - 1); - range->num_txpower = IW_MAX_TXPOWER; - range->txpower_capa = IW_TXPOW_DBM; + if (IS_ACX100(adev)) { /* ACX100 has direct radio programming - arbitrary levels, so offer a lot */ + for (i = 0; i <= IW_MAX_TXPOWER - 1; i++) + range->txpower[i] = 20 * i / (IW_MAX_TXPOWER - 1); + range->num_txpower = IW_MAX_TXPOWER; + range->txpower_capa = IW_TXPOW_DBM; + } + else { + int count = min(IW_MAX_TXPOWER, (int)adev->cfgopt_power_levels.len); + for (i = 0; i <= count; i++) + range->txpower[i] = adev->cfgopt_power_levels.list[i]; + range->num_txpower = count; + /* this list is given in mW */ + range->txpower_capa = IW_TXPOW_MWATT; + } range->we_version_compiled = WIRELESS_EXT; range->we_version_source = 0x9; @@ -1456,15 +1382,15 @@ acx_ioctl_get_range( /* FIXME: lifetime ranges and orders of magnitude are strange?? */ range->max_r_time = 65535; - if (IS_USB(priv)) + if (IS_USB(adev)) range->sensitivity = 0; - else if (IS_ACX111(priv)) + else if (IS_ACX111(adev)) range->sensitivity = 3; else range->sensitivity = 255; - for (i=0; i < priv->rate_supported_len; i++) { - range->bitrate[i] = (priv->rate_supported[i] & ~0x80) * 500000; + for (i=0; i < adev->rate_supported_len; i++) { + range->bitrate[i] = (adev->rate_supported[i] & ~0x80) * 500000; /* never happens, but keep it, to be safe: */ if (range->bitrate[i] == 0) break; @@ -1489,48 +1415,20 @@ end: ** Private functions */ -#if WIRELESS_EXT < 13 -/*********************************************************************** -** acx_ioctl_get_iw_priv -** -** I added the monitor mode and changed the stuff below -** to look more like the orinoco driver -*/ -static int -acx_ioctl_get_iw_priv(struct iwreq *iwr) -{ - int result = -EINVAL; - - if (!iwr->u.data.pointer) - return -EINVAL; - result = verify_area(VERIFY_WRITE, iwr->u.data.pointer, - sizeof(acx_ioctl_private_args)); - if (result) - return result; - - iwr->u.data.length = VEC_SIZE(acx_ioctl_private_args); - if (copy_to_user(iwr->u.data.pointer, - acx_ioctl_private_args, sizeof(acx_ioctl_private_args)) != 0) - result = -EFAULT; - - return result; -} -#endif - - /*********************************************************************** ** acx_ioctl_get_nick */ static inline int acx_ioctl_get_nick( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_point *dwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct iw_point *dwrq = &wrqu->data; + acx_device_t *adev = ndev2adev(ndev); - strcpy(extra, priv->nick); + strcpy(extra, adev->nick); dwrq->length = strlen(extra) + 1; return OK; @@ -1542,17 +1440,18 @@ acx_ioctl_get_nick( */ static int acx_ioctl_set_nick( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_point *dwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct iw_point *dwrq = &wrqu->data; + acx_device_t *adev = ndev2adev(ndev); int result; FN_ENTER; - acx_sem_lock(priv); + acx_sem_lock(adev); if (dwrq->length > IW_ESSID_MAX_SIZE + 1) { result = -E2BIG; @@ -1560,11 +1459,11 @@ acx_ioctl_set_nick( } /* extra includes trailing \0, so it's ok */ - strcpy(priv->nick, extra); + strcpy(adev->nick, extra); result = OK; end_unlock: - acx_sem_unlock(priv); + acx_sem_unlock(adev); FN_EXIT1(result); return result; @@ -1576,39 +1475,40 @@ end_unlock: */ static int acx_ioctl_get_retry( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct iw_param *vwrq = &wrqu->retry; + acx_device_t *adev = ndev2adev(ndev); unsigned int type = vwrq->flags & IW_RETRY_TYPE; unsigned int modifier = vwrq->flags & IW_RETRY_MODIFIER; int result; FN_ENTER; - acx_sem_lock(priv); + acx_sem_lock(adev); /* return the short retry number by default */ if (type == IW_RETRY_LIFETIME) { vwrq->flags = IW_RETRY_LIFETIME; - vwrq->value = priv->msdu_lifetime; + vwrq->value = adev->msdu_lifetime; } else if (modifier == IW_RETRY_MAX) { vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; - vwrq->value = priv->long_retry; + vwrq->value = adev->long_retry; } else { vwrq->flags = IW_RETRY_LIMIT; - if (priv->long_retry != priv->short_retry) + if (adev->long_retry != adev->short_retry) SET_BIT(vwrq->flags, IW_RETRY_MIN); - vwrq->value = priv->short_retry; + vwrq->value = adev->short_retry; } /* can't be disabled */ vwrq->disabled = (u8)0; result = OK; - acx_sem_unlock(priv); + acx_sem_unlock(adev); FN_EXIT1(result); return result; @@ -1620,12 +1520,13 @@ acx_ioctl_get_retry( */ static int acx_ioctl_set_retry( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + struct iw_param *vwrq = &wrqu->retry; + acx_device_t *adev = ndev2adev(ndev); int result; FN_ENTER; @@ -1639,34 +1540,34 @@ acx_ioctl_set_retry( goto end; } - acx_sem_lock(priv); + acx_sem_lock(adev); result = -EINVAL; if (IW_RETRY_LIMIT == (vwrq->flags & IW_RETRY_TYPE)) { printk("old retry limits: short %d long %d\n", - priv->short_retry, priv->long_retry); + adev->short_retry, adev->long_retry); if (vwrq->flags & IW_RETRY_MAX) { - priv->long_retry = vwrq->value; + adev->long_retry = vwrq->value; } else if (vwrq->flags & IW_RETRY_MIN) { - priv->short_retry = vwrq->value; + adev->short_retry = vwrq->value; } else { /* no modifier: set both */ - priv->long_retry = vwrq->value; - priv->short_retry = vwrq->value; + adev->long_retry = vwrq->value; + adev->short_retry = vwrq->value; } printk("new retry limits: short %d long %d\n", - priv->short_retry, priv->long_retry); - SET_BIT(priv->set_mask, GETSET_RETRY); + adev->short_retry, adev->long_retry); + SET_BIT(adev->set_mask, GETSET_RETRY); result = -EINPROGRESS; } else if (vwrq->flags & IW_RETRY_LIFETIME) { - priv->msdu_lifetime = vwrq->value; - printk("new MSDU lifetime: %d\n", priv->msdu_lifetime); - SET_BIT(priv->set_mask, SET_MSDU_LIFETIME); + adev->msdu_lifetime = vwrq->value; + printk("new MSDU lifetime: %d\n", adev->msdu_lifetime); + SET_BIT(adev->set_mask, SET_MSDU_LIFETIME); result = -EINPROGRESS; } - acx_sem_unlock(priv); + acx_sem_unlock(adev); end: FN_EXIT1(result); return result; @@ -1682,9 +1583,9 @@ end: #if ACX_DEBUG static int acx_ioctl_set_debug( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { unsigned int debug_new = *((unsigned int *)extra); @@ -1703,31 +1604,15 @@ acx_ioctl_set_debug( /*********************************************************************** ** acx_ioctl_list_reg_domain */ -static const char * const -reg_domain_strings[] = { - " 1-11 FCC (USA)", - " 1-11 DOC/IC (Canada)", - /* BTW: WLAN use in ETSI is regulated by - * ETSI standard EN 300 328-2 V1.1.2 */ - " 1-13 ETSI (Europe)", - "10-11 Spain", - "10-13 France", - " 14 MKK (Japan)", - " 1-14 MKK1", - " 3-9 Israel (not all firmware versions)", - NULL /* needs to remain as last entry */ -}; - static int acx_ioctl_list_reg_domain( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - int i = 1; - const char * const *entry = reg_domain_strings; + const char * const *entry = acx_reg_domain_strings; printk("dom# chan# domain/country\n"); while (*entry) @@ -1741,12 +1626,12 @@ acx_ioctl_list_reg_domain( */ static int acx_ioctl_set_reg_domain( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); int result; FN_ENTER; @@ -1756,14 +1641,14 @@ acx_ioctl_set_reg_domain( goto end; } - acx_sem_lock(priv); + acx_sem_lock(adev); - priv->reg_dom_id = acx_reg_domain_ids[*extra - 1]; - SET_BIT(priv->set_mask, GETSET_REG_DOMAIN); + adev->reg_dom_id = acx_reg_domain_ids[*extra - 1]; + SET_BIT(adev->set_mask, GETSET_REG_DOMAIN); result = -EINPROGRESS; - acx_sem_unlock(priv); + acx_sem_unlock(adev); end: FN_EXIT1(result); return result; @@ -1775,22 +1660,22 @@ end: */ static int acx_ioctl_get_reg_domain( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); int dom,i; /* no locking */ - dom = priv->reg_dom_id; + dom = adev->reg_dom_id; - for (i=1; i <= 7; i++) { + for (i = 1; i <= acx_reg_domain_ids_len; i++) { if (acx_reg_domain_ids[i-1] == dom) { log(L_IOCTL, "regulatory domain is currently set " "to %d (0x%X): %s\n", i, dom, - reg_domain_strings[i-1]); + acx_reg_domain_strings[i-1]); *extra = i; break; } @@ -1813,12 +1698,12 @@ preamble_modes[] = { static int acx_ioctl_set_short_preamble( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); int i; int result; @@ -1829,49 +1714,49 @@ acx_ioctl_set_short_preamble( goto end; } - acx_sem_lock(priv); + acx_sem_lock(adev); - priv->preamble_mode = (u8)*extra; - switch (priv->preamble_mode) { + adev->preamble_mode = (u8)*extra; + switch (adev->preamble_mode) { case 0: /* long */ - priv->preamble_cur = 0; + adev->preamble_cur = 0; break; case 1: /* short, kick incapable peers */ - priv->preamble_cur = 1; - for (i = 0; i < VEC_SIZE(priv->sta_list); i++) { - client_t *clt = &priv->sta_list[i]; + adev->preamble_cur = 1; + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + client_t *clt = &adev->sta_list[i]; if (!clt->used) continue; if (!(clt->cap_info & WF_MGMT_CAP_SHORT)) { clt->used = CLIENT_EMPTY_SLOT_0; } } - switch (priv->mode) { + switch (adev->mode) { case ACX_MODE_2_STA: - if (priv->ap_client && !priv->ap_client->used) { + if (adev->ap_client && !adev->ap_client->used) { /* We kicked our AP :) */ - SET_BIT(priv->set_mask, GETSET_RESCAN); + SET_BIT(adev->set_mask, GETSET_RESCAN); } } break; case 2: /* auto. short only if all peers are short-capable */ - priv->preamble_cur = 1; - for (i = 0; i < VEC_SIZE(priv->sta_list); i++) { - client_t *clt = &priv->sta_list[i]; + adev->preamble_cur = 1; + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + client_t *clt = &adev->sta_list[i]; if (!clt->used) continue; if (!(clt->cap_info & WF_MGMT_CAP_SHORT)) { - priv->preamble_cur = 0; + adev->preamble_cur = 0; break; } } break; } printk("new short preamble setting: configured %s, active %s\n", - preamble_modes[priv->preamble_mode], - preamble_modes[priv->preamble_cur]); + preamble_modes[adev->preamble_mode], + preamble_modes[adev->preamble_cur]); result = OK; - acx_sem_unlock(priv); + acx_sem_unlock(adev); end: FN_EXIT1(result); return result; @@ -1883,22 +1768,22 @@ end: */ static int acx_ioctl_get_short_preamble( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); - acx_sem_lock(priv); + acx_sem_lock(adev); printk("current short preamble setting: configured %s, active %s\n", - preamble_modes[priv->preamble_mode], - preamble_modes[priv->preamble_cur]); + preamble_modes[adev->preamble_mode], + preamble_modes[adev->preamble_cur]); - *extra = (char)priv->preamble_mode; + *extra = (char)adev->preamble_mode; - acx_sem_unlock(priv); + acx_sem_unlock(adev); return OK; } @@ -1912,14 +1797,14 @@ acx_ioctl_get_short_preamble( */ static int acx_ioctl_set_antenna( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); - acx_sem_lock(priv); + acx_sem_lock(adev); printk("old antenna value: 0x%02X (COMBINED bit mask)\n" "Rx antenna selection:\n" @@ -1932,12 +1817,12 @@ acx_ioctl_set_antenna( "0x00 ant. 2\n" /* yep, those ARE reversed! */ "0x20 ant. 1\n" "new antenna value: 0x%02X\n", - priv->antenna, (u8)*extra); + adev->antenna, (u8)*extra); - priv->antenna = (u8)*extra; - SET_BIT(priv->set_mask, GETSET_ANTENNA); + adev->antenna = (u8)*extra; + SET_BIT(adev->set_mask, GETSET_ANTENNA); - acx_sem_unlock(priv); + acx_sem_unlock(adev); return -EINPROGRESS; } @@ -1948,12 +1833,12 @@ acx_ioctl_set_antenna( */ static int acx_ioctl_get_antenna( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); /* no locking. it's pointless to lock a single load */ printk("current antenna value: 0x%02X (COMBINED bit mask)\n" @@ -1964,7 +1849,7 @@ acx_ioctl_get_antenna( "0xc0 partial diversity\n" "Tx antenna selection:\n" "0x00 ant. 2\n" /* yep, those ARE reversed! */ - "0x20 ant. 1\n", priv->antenna); + "0x20 ant. 1\n", adev->antenna); return 0; } @@ -1978,12 +1863,12 @@ acx_ioctl_get_antenna( */ static int acx_ioctl_set_rx_antenna( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); int result; FN_ENTER; @@ -1993,17 +1878,17 @@ acx_ioctl_set_rx_antenna( goto end; } - printk("old antenna value: 0x%02X\n", priv->antenna); + printk("old antenna value: 0x%02X\n", adev->antenna); - acx_sem_lock(priv); + acx_sem_lock(adev); - priv->antenna &= 0x3f; - SET_BIT(priv->antenna, (*extra << 6)); - SET_BIT(priv->set_mask, GETSET_ANTENNA); - printk("new antenna value: 0x%02X\n", priv->antenna); + adev->antenna &= 0x3f; + SET_BIT(adev->antenna, (*extra << 6)); + SET_BIT(adev->set_mask, GETSET_ANTENNA); + printk("new antenna value: 0x%02X\n", adev->antenna); result = -EINPROGRESS; - acx_sem_unlock(priv); + acx_sem_unlock(adev); end: FN_EXIT1(result); return result; @@ -2018,12 +1903,12 @@ end: */ static int acx_ioctl_set_tx_antenna( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); int result; FN_ENTER; @@ -2033,17 +1918,17 @@ acx_ioctl_set_tx_antenna( goto end; } - printk("old antenna value: 0x%02X\n", priv->antenna); + printk("old antenna value: 0x%02X\n", adev->antenna); - acx_sem_lock(priv); + acx_sem_lock(adev); - priv->antenna &= ~0x30; - SET_BIT(priv->antenna, ((*extra & 0x01) << 5)); - SET_BIT(priv->set_mask, GETSET_ANTENNA); - printk("new antenna value: 0x%02X\n", priv->antenna); + adev->antenna &= ~0x30; + SET_BIT(adev->antenna, ((*extra & 0x01) << 5)); + SET_BIT(adev->set_mask, GETSET_ANTENNA); + printk("new antenna value: 0x%02X\n", adev->antenna); result = -EINPROGRESS; - acx_sem_unlock(priv); + acx_sem_unlock(adev); end: FN_EXIT1(result); return result; @@ -2057,19 +1942,19 @@ end: */ static int acx_ioctl_wlansniff( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); unsigned int *params = (unsigned int*)extra; unsigned int enable = (unsigned int)(params[0] > 0); int result; FN_ENTER; - acx_sem_lock(priv); + acx_sem_lock(adev); /* not using printk() here, since it distorts kismet display * when printk messages activated */ @@ -2077,28 +1962,29 @@ acx_ioctl_wlansniff( switch (params[0]) { case 0: - priv->netdev->type = ARPHRD_ETHER; + /* no monitor mode. hmm, should we simply ignore it + * or go back to enabling adev->netdev->type ARPHRD_ETHER? */ break; case 1: - priv->netdev->type = ARPHRD_IEEE80211_PRISM; + adev->monitor_type = ARPHRD_IEEE80211_PRISM; break; case 2: - priv->netdev->type = ARPHRD_IEEE80211; + adev->monitor_type = ARPHRD_IEEE80211; break; } if (params[0]) { - priv->mode = ACX_MODE_MONITOR; - SET_BIT(priv->set_mask, GETSET_MODE); + adev->mode = ACX_MODE_MONITOR; + SET_BIT(adev->set_mask, GETSET_MODE); } if (enable) { - priv->channel = params[1]; - SET_BIT(priv->set_mask, GETSET_RX); + adev->channel = params[1]; + SET_BIT(adev->set_mask, GETSET_RX); } result = -EINPROGRESS; - acx_sem_unlock(priv); + acx_sem_unlock(adev); FN_EXIT1(result); return result; @@ -2111,25 +1997,26 @@ acx_ioctl_wlansniff( */ static int acx_ioctl_unknown11( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { #ifdef BROKEN - wlandevice_t *priv = netdev_priv(dev); + struct iw_param *vwrq = &wrqu->param; + acx_device_t *adev = ndev2adev(ndev); unsigned long flags; client_t client; int result; - acx_sem_lock(priv); - acx_lock(priv, flags); + acx_sem_lock(adev); + acx_lock(adev, flags); - acx_l_transmit_disassoc(priv, &client); + acx_l_transmit_disassoc(adev, &client); result = OK; - acx_unlock(priv, flags); - acx_sem_unlock(priv); + acx_unlock(adev, flags); + acx_sem_unlock(adev); return result; #endif @@ -2142,29 +2029,29 @@ acx_ioctl_unknown11( */ static int acx_ioctl_dbg_set_masks( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); const unsigned int *params = (unsigned int*)extra; int result; - acx_sem_lock(priv); + acx_sem_lock(adev); log(L_IOCTL, "setting flags in settings mask: " "get_mask %08X set_mask %08X\n" "before: get_mask %08X set_mask %08X\n", params[0], params[1], - priv->get_mask, priv->set_mask); - SET_BIT(priv->get_mask, params[0]); - SET_BIT(priv->set_mask, params[1]); + adev->get_mask, adev->set_mask); + SET_BIT(adev->get_mask, params[0]); + SET_BIT(adev->set_mask, params[1]); log(L_IOCTL, "after: get_mask %08X set_mask %08X\n", - priv->get_mask, priv->set_mask); + adev->get_mask, adev->set_mask); result = -EINPROGRESS; /* immediately call commit handler */ - acx_sem_unlock(priv); + acx_sem_unlock(adev); return result; } @@ -2262,10 +2149,12 @@ verify_rate(u32 rate, int chip_type) } static int -acx_ioctl_set_rates(struct net_device *dev, struct iw_request_info *info, - struct iw_param *vwrq, char *extra) +acx_ioctl_set_rates(struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); unsigned long flags; int result; u32 brate = 0, orate = 0; /* basic, operational rate set */ @@ -2279,36 +2168,36 @@ acx_ioctl_set_rates(struct net_device *d SET_BIT(orate, brate); log(L_IOCTL, "brate %08X orate %08X\n", brate, orate); - result = verify_rate(brate, priv->chip_type); + result = verify_rate(brate, adev->chip_type); if (result) goto end; - result = verify_rate(orate, priv->chip_type); + result = verify_rate(orate, adev->chip_type); if (result) goto end; - acx_sem_lock(priv); - acx_lock(priv, flags); + acx_sem_lock(adev); + acx_lock(adev, flags); - priv->rate_basic = brate; - priv->rate_oper = orate; + adev->rate_basic = brate; + adev->rate_oper = orate; /* TODO: ideally, we shall monitor highest basic rate ** which was successfully sent to every peer ** (say, last we checked, everybody could hear 5.5 Mbits) ** and use that for bcasts when we want to reach all peers. ** For beacons, we probably shall use lowest basic rate ** because we want to reach all *potential* new peers too */ - priv->rate_bcast = 1 << lowest_bit(brate); - if (IS_ACX100(priv)) - priv->rate_bcast100 = acx_rate111to100(priv->rate_bcast); - priv->rate_auto = !has_only_one_bit(orate); - acx_l_update_client_rates(priv, orate); + adev->rate_bcast = 1 << lowest_bit(brate); + if (IS_ACX100(adev)) + adev->rate_bcast100 = acx_rate111to100(adev->rate_bcast); + adev->rate_auto = !has_only_one_bit(orate); + acx_l_update_client_rates(adev, orate); /* TODO: get rid of ratevector, build it only when needed */ - acx_l_update_ratevector(priv); + acx_l_update_ratevector(adev); /* Do/don't do tx rate fallback; beacon contents and rate */ - SET_BIT(priv->set_mask, SET_RATE_FALLBACK|SET_TEMPLATES); + SET_BIT(adev->set_mask, SET_RATE_FALLBACK|SET_TEMPLATES); result = -EINPROGRESS; - acx_unlock(priv, flags); - acx_sem_unlock(priv); + acx_unlock(adev, flags); + acx_sem_unlock(adev); end: FN_EXIT1(result); return result; @@ -2320,12 +2209,12 @@ end: */ static int acx_ioctl_get_phy_chan_busy_percentage( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); struct { /* added ACX_PACKED, not tested --vda */ u16 type ACX_PACKED; u16 len ACX_PACKED; @@ -2334,9 +2223,9 @@ acx_ioctl_get_phy_chan_busy_percentage( } usage; int result; - acx_sem_lock(priv); + acx_sem_lock(adev); - if (OK != acx_s_interrogate(priv, &usage, ACX1xx_IE_MEDIUM_USAGE)) { + if (OK != acx_s_interrogate(adev, &usage, ACX1xx_IE_MEDIUM_USAGE)) { result = NOT_OK; goto end_unlock; } @@ -2345,14 +2234,14 @@ acx_ioctl_get_phy_chan_busy_percentage( usage.totaltime = le32_to_cpu(usage.totaltime); printk("%s: average busy percentage since last invocation: %d%% " "(%u of %u microseconds)\n", - dev->name, + ndev->name, usage.busytime / ((usage.totaltime / 100) + 1), usage.busytime, usage.totaltime); result = OK; end_unlock: - acx_sem_unlock(priv); + acx_sem_unlock(adev); return result; } @@ -2363,21 +2252,21 @@ end_unlock: */ static inline int acx_ioctl_set_ed_threshold( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); - acx_sem_lock(priv); + acx_sem_lock(adev); - printk("old ED threshold value: %d\n", priv->ed_threshold); - priv->ed_threshold = (unsigned char)*extra; + printk("old ED threshold value: %d\n", adev->ed_threshold); + adev->ed_threshold = (unsigned char)*extra; printk("new ED threshold value: %d\n", (unsigned char)*extra); - SET_BIT(priv->set_mask, GETSET_ED_THRESH); + SET_BIT(adev->set_mask, GETSET_ED_THRESH); - acx_sem_unlock(priv); + acx_sem_unlock(adev); return -EINPROGRESS; } @@ -2388,23 +2277,23 @@ acx_ioctl_set_ed_threshold( */ static inline int acx_ioctl_set_cca( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); int result; - acx_sem_lock(priv); + acx_sem_lock(adev); - printk("old CCA value: 0x%02X\n", priv->cca); - priv->cca = (unsigned char)*extra; + printk("old CCA value: 0x%02X\n", adev->cca); + adev->cca = (unsigned char)*extra; printk("new CCA value: 0x%02X\n", (unsigned char)*extra); - SET_BIT(priv->set_mask, GETSET_CCA); + SET_BIT(adev->set_mask, GETSET_CCA); result = -EINPROGRESS; - acx_sem_unlock(priv); + acx_sem_unlock(adev); return result; } @@ -2416,67 +2305,67 @@ static const char * const scan_modes[] = { "active", "passive", "background" }; static void -acx_print_scan_params(wlandevice_t *priv, const char* head) +acx_print_scan_params(acx_device_t *adev, const char* head) { printk("%s: %smode %d (%s), min chan time %dTU, " "max chan time %dTU, max scan rate byte: %d\n", - priv->netdev->name, head, - priv->scan_mode, scan_modes[priv->scan_mode], - priv->scan_probe_delay, priv->scan_duration, priv->scan_rate); + adev->ndev->name, head, + adev->scan_mode, scan_modes[adev->scan_mode], + adev->scan_probe_delay, adev->scan_duration, adev->scan_rate); } static int acx_ioctl_set_scan_params( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); int result; const int *params = (int *)extra; - acx_sem_lock(priv); + acx_sem_lock(adev); - acx_print_scan_params(priv, "old scan parameters: "); + acx_print_scan_params(adev, "old scan parameters: "); if ((params[0] != -1) && (params[0] >= 0) && (params[0] <= 2)) - priv->scan_mode = params[0]; + adev->scan_mode = params[0]; if (params[1] != -1) - priv->scan_probe_delay = params[1]; + adev->scan_probe_delay = params[1]; if (params[2] != -1) - priv->scan_duration = params[2]; + adev->scan_duration = params[2]; if ((params[3] != -1) && (params[3] <= 255)) - priv->scan_rate = params[3]; - acx_print_scan_params(priv, "new scan parameters: "); - SET_BIT(priv->set_mask, GETSET_RESCAN); + adev->scan_rate = params[3]; + acx_print_scan_params(adev, "new scan parameters: "); + SET_BIT(adev->set_mask, GETSET_RESCAN); result = -EINPROGRESS; - acx_sem_unlock(priv); + acx_sem_unlock(adev); return result; } static int acx_ioctl_get_scan_params( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); int result; int *params = (int *)extra; - acx_sem_lock(priv); + acx_sem_lock(adev); - acx_print_scan_params(priv, "current scan parameters: "); - params[0] = priv->scan_mode; - params[1] = priv->scan_probe_delay; - params[2] = priv->scan_duration; - params[3] = priv->scan_rate; + acx_print_scan_params(adev, "current scan parameters: "); + params[0] = adev->scan_mode; + params[1] = adev->scan_probe_delay; + params[2] = adev->scan_duration; + params[3] = adev->scan_rate; result = OK; - acx_sem_unlock(priv); + acx_sem_unlock(adev); return result; } @@ -2486,41 +2375,41 @@ acx_ioctl_get_scan_params( */ static int acx100_ioctl_set_led_power( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { static const char * const led_modes[] = { "off", "on", "LinkQuality" }; - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); int result; - acx_sem_lock(priv); + acx_sem_lock(adev); printk("%s: power LED status: old %d (%s), ", - dev->name, - priv->led_power, - led_modes[priv->led_power]); - priv->led_power = extra[0]; - if (priv->led_power > 2) priv->led_power = 2; + ndev->name, + adev->led_power, + led_modes[adev->led_power]); + adev->led_power = extra[0]; + if (adev->led_power > 2) adev->led_power = 2; printk("new %d (%s)\n", - priv->led_power, - led_modes[priv->led_power]); + adev->led_power, + led_modes[adev->led_power]); - if (priv->led_power == 2) { + if (adev->led_power == 2) { printk("%s: max link quality setting: old %d, ", - dev->name, priv->brange_max_quality); + ndev->name, adev->brange_max_quality); if (extra[1]) - priv->brange_max_quality = extra[1]; - printk("new %d\n", priv->brange_max_quality); + adev->brange_max_quality = extra[1]; + printk("new %d\n", adev->brange_max_quality); } - SET_BIT(priv->set_mask, GETSET_LED_POWER); + SET_BIT(adev->set_mask, GETSET_LED_POWER); result = -EINPROGRESS; - acx_sem_unlock(priv); + acx_sem_unlock(adev); return result; } @@ -2530,22 +2419,22 @@ acx100_ioctl_set_led_power( */ static inline int acx100_ioctl_get_led_power( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); - acx_sem_lock(priv); + acx_sem_lock(adev); - extra[0] = priv->led_power; - if (priv->led_power == 2) - extra[1] = priv->brange_max_quality; + extra[0] = adev->led_power; + if (adev->led_power == 2) + extra[1] = adev->brange_max_quality; else extra[1] = -1; - acx_sem_unlock(priv); + acx_sem_unlock(adev); return OK; } @@ -2555,14 +2444,15 @@ acx100_ioctl_get_led_power( */ static int acx111_ioctl_info( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - if (!IS_PCI((wlandevice_t*)netdev_priv(dev))) + struct iw_param *vwrq = &wrqu->param; + if (!IS_PCI(ndev2adev(ndev))) return OK; - return acx111pci_ioctl_info(dev, info, vwrq, extra); + return acx111pci_ioctl_info(ndev, info, vwrq, extra); } @@ -2570,516 +2460,274 @@ acx111_ioctl_info( */ static int acx100_ioctl_set_phy_amp_bias( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, - struct iw_param *vwrq, + union iwreq_data *wrqu, char *extra) { - if (!IS_PCI((wlandevice_t*)netdev_priv(dev))) { + struct iw_param *vwrq = &wrqu->param; + if (!IS_PCI(ndev2adev(ndev))) { printk("acx: set_phy_amp_bias() is not supported on USB\n"); return OK; } - return acx100pci_ioctl_set_phy_amp_bias(dev, info, vwrq, extra); + return acx100pci_ioctl_set_phy_amp_bias(ndev, info, vwrq, extra); } /*********************************************************************** */ -#if WIRELESS_EXT >= 13 static const iw_handler acx_ioctl_handler[] = { - (iw_handler) acx_ioctl_commit, /* SIOCSIWCOMMIT */ - (iw_handler) acx_ioctl_get_name, /* SIOCGIWNAME */ - (iw_handler) NULL, /* SIOCSIWNWID */ - (iw_handler) NULL, /* SIOCGIWNWID */ - (iw_handler) acx_ioctl_set_freq, /* SIOCSIWFREQ */ - (iw_handler) acx_ioctl_get_freq, /* SIOCGIWFREQ */ - (iw_handler) acx_ioctl_set_mode, /* SIOCSIWMODE */ - (iw_handler) acx_ioctl_get_mode, /* SIOCGIWMODE */ - (iw_handler) acx_ioctl_set_sens, /* SIOCSIWSENS */ - (iw_handler) acx_ioctl_get_sens, /* SIOCGIWSENS */ - (iw_handler) NULL, /* SIOCSIWRANGE */ - (iw_handler) acx_ioctl_get_range, /* SIOCGIWRANGE */ - (iw_handler) NULL, /* SIOCSIWPRIV */ - (iw_handler) NULL, /* SIOCGIWPRIV */ - (iw_handler) NULL, /* SIOCSIWSTATS */ - (iw_handler) NULL, /* SIOCGIWSTATS */ + acx_ioctl_commit, /* SIOCSIWCOMMIT */ + acx_ioctl_get_name, /* SIOCGIWNAME */ + NULL, /* SIOCSIWNWID */ + NULL, /* SIOCGIWNWID */ + acx_ioctl_set_freq, /* SIOCSIWFREQ */ + acx_ioctl_get_freq, /* SIOCGIWFREQ */ + acx_ioctl_set_mode, /* SIOCSIWMODE */ + acx_ioctl_get_mode, /* SIOCGIWMODE */ + acx_ioctl_set_sens, /* SIOCSIWSENS */ + acx_ioctl_get_sens, /* SIOCGIWSENS */ + NULL, /* SIOCSIWRANGE */ + acx_ioctl_get_range, /* SIOCGIWRANGE */ + NULL, /* SIOCSIWPRIV */ + NULL, /* SIOCGIWPRIV */ + NULL, /* SIOCSIWSTATS */ + NULL, /* SIOCGIWSTATS */ #if IW_HANDLER_VERSION > 4 - iw_handler_set_spy, /* SIOCSIWSPY */ - iw_handler_get_spy, /* SIOCGIWSPY */ - iw_handler_set_thrspy, /* SIOCSIWTHRSPY */ - iw_handler_get_thrspy, /* SIOCGIWTHRSPY */ + iw_handler_set_spy, /* SIOCSIWSPY */ + iw_handler_get_spy, /* SIOCGIWSPY */ + iw_handler_set_thrspy, /* SIOCSIWTHRSPY */ + iw_handler_get_thrspy, /* SIOCGIWTHRSPY */ #else /* IW_HANDLER_VERSION > 4 */ #ifdef WIRELESS_SPY - (iw_handler) NULL /* acx_ioctl_set_spy FIXME */, /* SIOCSIWSPY */ - (iw_handler) NULL /* acx_ioctl_get_spy */, /* SIOCGIWSPY */ + NULL /* acx_ioctl_set_spy FIXME */, /* SIOCSIWSPY */ + NULL /* acx_ioctl_get_spy */, /* SIOCGIWSPY */ #else /* WSPY */ - (iw_handler) NULL, /* SIOCSIWSPY */ - (iw_handler) NULL, /* SIOCGIWSPY */ + NULL, /* SIOCSIWSPY */ + NULL, /* SIOCGIWSPY */ #endif /* WSPY */ - (iw_handler) NULL, /* [nothing] */ - (iw_handler) NULL, /* [nothing] */ + NULL, /* [nothing] */ + NULL, /* [nothing] */ #endif /* IW_HANDLER_VERSION > 4 */ - (iw_handler) acx_ioctl_set_ap, /* SIOCSIWAP */ - (iw_handler) acx_ioctl_get_ap, /* SIOCGIWAP */ - (iw_handler) NULL, /* [nothing] */ - (iw_handler) acx_ioctl_get_aplist, /* SIOCGIWAPLIST */ -#if WIRELESS_EXT > 13 - (iw_handler) acx_ioctl_set_scan, /* SIOCSIWSCAN */ - (iw_handler) acx_ioctl_get_scan, /* SIOCGIWSCAN */ -#else /* WE > 13 */ - (iw_handler) NULL, /* SIOCSIWSCAN */ - (iw_handler) NULL, /* SIOCGIWSCAN */ -#endif /* WE > 13 */ - (iw_handler) acx_ioctl_set_essid, /* SIOCSIWESSID */ - (iw_handler) acx_ioctl_get_essid, /* SIOCGIWESSID */ - (iw_handler) acx_ioctl_set_nick, /* SIOCSIWNICKN */ - (iw_handler) acx_ioctl_get_nick, /* SIOCGIWNICKN */ - (iw_handler) NULL, /* [nothing] */ - (iw_handler) NULL, /* [nothing] */ - (iw_handler) acx_ioctl_set_rate, /* SIOCSIWRATE */ - (iw_handler) acx_ioctl_get_rate, /* SIOCGIWRATE */ - (iw_handler) acx_ioctl_set_rts, /* SIOCSIWRTS */ - (iw_handler) acx_ioctl_get_rts, /* SIOCGIWRTS */ - (iw_handler) NULL /* acx_ioctl_set_frag FIXME*/, /* SIOCSIWFRAG */ - (iw_handler) NULL /* acx_ioctl_get_frag */, /* SIOCGIWFRAG */ - (iw_handler) acx_ioctl_set_txpow, /* SIOCSIWTXPOW */ - (iw_handler) acx_ioctl_get_txpow, /* SIOCGIWTXPOW */ - (iw_handler) acx_ioctl_set_retry, /* SIOCSIWRETRY */ - (iw_handler) acx_ioctl_get_retry, /* SIOCGIWRETRY */ - (iw_handler) acx_ioctl_set_encode, /* SIOCSIWENCODE */ - (iw_handler) acx_ioctl_get_encode, /* SIOCGIWENCODE */ - (iw_handler) acx_ioctl_set_power, /* SIOCSIWPOWER */ - (iw_handler) acx_ioctl_get_power, /* SIOCGIWPOWER */ -}; - -static const iw_handler acx_ioctl_private_handler[] = -{ -#if ACX_DEBUG -[ACX100_IOCTL_DEBUG - ACX100_IOCTL] = (iw_handler) acx_ioctl_set_debug, + acx_ioctl_set_ap, /* SIOCSIWAP */ + acx_ioctl_get_ap, /* SIOCGIWAP */ + NULL, /* [nothing] */ + acx_ioctl_get_aplist, /* SIOCGIWAPLIST */ + acx_ioctl_set_scan, /* SIOCSIWSCAN */ + acx_ioctl_get_scan, /* SIOCGIWSCAN */ + acx_ioctl_set_essid, /* SIOCSIWESSID */ + acx_ioctl_get_essid, /* SIOCGIWESSID */ + acx_ioctl_set_nick, /* SIOCSIWNICKN */ + acx_ioctl_get_nick, /* SIOCGIWNICKN */ + NULL, /* [nothing] */ + NULL, /* [nothing] */ + acx_ioctl_set_rate, /* SIOCSIWRATE */ + acx_ioctl_get_rate, /* SIOCGIWRATE */ + acx_ioctl_set_rts, /* SIOCSIWRTS */ + acx_ioctl_get_rts, /* SIOCGIWRTS */ +#if ACX_FRAGMENTATION + acx_ioctl_set_frag, /* SIOCSIWFRAG */ + acx_ioctl_get_frag, /* SIOCGIWFRAG */ #else -[ACX100_IOCTL_DEBUG - ACX100_IOCTL] = (iw_handler) NULL, + NULL, /* SIOCSIWFRAG */ + NULL, /* SIOCGIWFRAG */ #endif -[ACX100_IOCTL_SET_PLED - ACX100_IOCTL] = (iw_handler) acx100_ioctl_set_led_power, -[ACX100_IOCTL_GET_PLED - ACX100_IOCTL] = (iw_handler) acx100_ioctl_get_led_power, -[ACX100_IOCTL_SET_RATES - ACX100_IOCTL] = (iw_handler) acx_ioctl_set_rates, -[ACX100_IOCTL_LIST_DOM - ACX100_IOCTL] = (iw_handler) acx_ioctl_list_reg_domain, -[ACX100_IOCTL_SET_DOM - ACX100_IOCTL] = (iw_handler) acx_ioctl_set_reg_domain, -[ACX100_IOCTL_GET_DOM - ACX100_IOCTL] = (iw_handler) acx_ioctl_get_reg_domain, -[ACX100_IOCTL_SET_SCAN_PARAMS - ACX100_IOCTL] = (iw_handler) acx_ioctl_set_scan_params, -[ACX100_IOCTL_GET_SCAN_PARAMS - ACX100_IOCTL] = (iw_handler) acx_ioctl_get_scan_params, -[ACX100_IOCTL_SET_PREAMB - ACX100_IOCTL] = (iw_handler) acx_ioctl_set_short_preamble, -[ACX100_IOCTL_GET_PREAMB - ACX100_IOCTL] = (iw_handler) acx_ioctl_get_short_preamble, -[ACX100_IOCTL_SET_ANT - ACX100_IOCTL] = (iw_handler) acx_ioctl_set_antenna, -[ACX100_IOCTL_GET_ANT - ACX100_IOCTL] = (iw_handler) acx_ioctl_get_antenna, -[ACX100_IOCTL_RX_ANT - ACX100_IOCTL] = (iw_handler) acx_ioctl_set_rx_antenna, -[ACX100_IOCTL_TX_ANT - ACX100_IOCTL] = (iw_handler) acx_ioctl_set_tx_antenna, -[ACX100_IOCTL_SET_PHY_AMP_BIAS - ACX100_IOCTL] = (iw_handler) acx100_ioctl_set_phy_amp_bias, -[ACX100_IOCTL_GET_PHY_CHAN_BUSY - ACX100_IOCTL] = (iw_handler) acx_ioctl_get_phy_chan_busy_percentage, -[ACX100_IOCTL_SET_ED - ACX100_IOCTL] = (iw_handler) acx_ioctl_set_ed_threshold, -[ACX100_IOCTL_SET_CCA - ACX100_IOCTL] = (iw_handler) acx_ioctl_set_cca, -[ACX100_IOCTL_MONITOR - ACX100_IOCTL] = (iw_handler) acx_ioctl_wlansniff, -[ACX100_IOCTL_TEST - ACX100_IOCTL] = (iw_handler) acx_ioctl_unknown11, -[ACX100_IOCTL_DBG_SET_MASKS - ACX100_IOCTL] = (iw_handler) acx_ioctl_dbg_set_masks, -[ACX111_IOCTL_INFO - ACX100_IOCTL] = (iw_handler) acx111_ioctl_info, -}; - -const struct iw_handler_def acx_ioctl_handler_def = -{ - .num_standard = VEC_SIZE(acx_ioctl_handler), - .num_private = VEC_SIZE(acx_ioctl_private_handler), - .num_private_args = VEC_SIZE(acx_ioctl_private_args), - .standard = (iw_handler *) acx_ioctl_handler, - .private = (iw_handler *) acx_ioctl_private_handler, - .private_args = (struct iw_priv_args *) acx_ioctl_private_args, + acx_ioctl_set_txpow, /* SIOCSIWTXPOW */ + acx_ioctl_get_txpow, /* SIOCGIWTXPOW */ + acx_ioctl_set_retry, /* SIOCSIWRETRY */ + acx_ioctl_get_retry, /* SIOCGIWRETRY */ + acx_ioctl_set_encode, /* SIOCSIWENCODE */ + acx_ioctl_get_encode, /* SIOCGIWENCODE */ + acx_ioctl_set_power, /* SIOCSIWPOWER */ + acx_ioctl_get_power, /* SIOCGIWPOWER */ }; -#endif /* WE >= 13 */ - -#if WIRELESS_EXT < 13 /*********************************************************************** -** Main function -** -** acx_e_ioctl_old -** -** This is the *OLD* ioctl handler. -** Make sure to not only place your additions here, but instead mainly -** in the new one (acx_ioctl_handler[])! */ -int -acx_e_ioctl_old(netdevice_t *dev, struct ifreq *ifr, int cmd) -{ - wlandevice_t *priv = netdev_priv(dev); - int result = 0; - struct iwreq *iwr = (struct iwreq *)ifr; - - log(L_IOCTL, "%s cmd = 0x%04X\n", __func__, cmd); - - /* This is the way it is done in the orinoco driver. - * Check to see if device is present. - */ - if (0 == netif_device_present(dev)) { - return -ENODEV; - } - - switch (cmd) { -/* WE 13 and higher will use acx_ioctl_handler_def */ - case SIOCGIWNAME: - /* get name == wireless protocol */ - result = acx_ioctl_get_name(dev, NULL, - (char *)&(iwr->u.name), NULL); - break; - - case SIOCSIWNWID: /* pre-802.11, */ - case SIOCGIWNWID: /* not supported. */ - result = -EOPNOTSUPP; - break; - case SIOCSIWFREQ: - /* set channel/frequency (Hz) - data can be frequency or channel : - 0-1000 = channel - > 1000 = frequency in Hz */ - result = acx_ioctl_set_freq(dev, NULL, &(iwr->u.freq), NULL); - break; - - case SIOCGIWFREQ: - /* get channel/frequency (Hz) */ - result = acx_ioctl_get_freq(dev, NULL, &(iwr->u.freq), NULL); - break; - - case SIOCSIWMODE: - /* set operation mode */ - result = acx_ioctl_set_mode(dev, NULL, &(iwr->u.mode), NULL); - break; - - case SIOCGIWMODE: - /* get operation mode */ - result = acx_ioctl_get_mode(dev, NULL, &(iwr->u.mode), NULL); - break; - - case SIOCSIWSENS: - /* Set sensitivity */ - result = acx_ioctl_set_sens(dev, NULL, &(iwr->u.sens), NULL); - break; - - case SIOCGIWSENS: - /* Get sensitivity */ - result = acx_ioctl_get_sens(dev, NULL, &(iwr->u.sens), NULL); - break; - -#if WIRELESS_EXT > 10 - case SIOCGIWRANGE: - /* Get range of parameters */ - { - struct iw_range range; - result = acx_ioctl_get_range(dev, NULL, - &(iwr->u.data), (char *)&range); - if (copy_to_user(iwr->u.data.pointer, &range, - sizeof(struct iw_range))) - result = -EFAULT; - } - break; -#endif - - case SIOCGIWPRIV: - result = acx_ioctl_get_iw_priv(iwr); - break; - - /* case SIOCSIWSPY: */ - /* case SIOCGIWSPY: */ - /* case SIOCSIWTHRSPY: */ - /* case SIOCGIWTHRSPY: */ - - case SIOCSIWAP: - /* set access point by MAC address */ - result = acx_ioctl_set_ap(dev, NULL, &(iwr->u.ap_addr), - NULL); - break; - - case SIOCGIWAP: - /* get access point MAC address */ - result = acx_ioctl_get_ap(dev, NULL, &(iwr->u.ap_addr), - NULL); - break; - - case SIOCGIWAPLIST: - /* get list of access points in range */ - result = acx_ioctl_get_aplist(dev, NULL, &(iwr->u.data), - NULL); - break; - -#if NOT_FINISHED_YET - case SIOCSIWSCAN: - /* start a station scan */ - result = acx_ioctl_set_scan(iwr, priv); - break; - - case SIOCGIWSCAN: - /* get list of stations found during scan */ - result = acx_ioctl_get_scan(iwr, priv); - break; -#endif - - case SIOCSIWESSID: - /* set ESSID (network name) */ - { - char essid[IW_ESSID_MAX_SIZE+1]; - - if (iwr->u.essid.length > IW_ESSID_MAX_SIZE) - { - result = -E2BIG; - break; - } - if (copy_from_user(essid, iwr->u.essid.pointer, - iwr->u.essid.length)) - { - result = -EFAULT; - break; - } - result = acx_ioctl_set_essid(dev, NULL, - &(iwr->u.essid), essid); - } - break; - - case SIOCGIWESSID: - /* get ESSID */ - { - char essid[IW_ESSID_MAX_SIZE+1]; - if (iwr->u.essid.pointer) - result = acx_ioctl_get_essid(dev, NULL, - &(iwr->u.essid), essid); - if (copy_to_user(iwr->u.essid.pointer, essid, - iwr->u.essid.length)) - result = -EFAULT; - } - break; - - case SIOCSIWNICKN: - /* set nick */ - { - char nick[IW_ESSID_MAX_SIZE+1]; - - if (iwr->u.data.length > IW_ESSID_MAX_SIZE) - { - result = -E2BIG; - break; - } - if (copy_from_user(nick, iwr->u.data.pointer, - iwr->u.data.length)) - { - result = -EFAULT; - break; - } - result = acx_ioctl_set_nick(dev, NULL, - &(iwr->u.data), nick); - } - break; - - case SIOCGIWNICKN: - /* get nick */ - { - char nick[IW_ESSID_MAX_SIZE+1]; - if (iwr->u.data.pointer) - result = acx_ioctl_get_nick(dev, NULL, - &(iwr->u.data), nick); - if (copy_to_user(iwr->u.data.pointer, nick, - iwr->u.data.length)) - result = -EFAULT; - } - break; - - case SIOCSIWRATE: - /* set default bit rate (bps) */ - result = acx_ioctl_set_rate(dev, NULL, &(iwr->u.bitrate), - NULL); - break; - - case SIOCGIWRATE: - /* get default bit rate (bps) */ - result = acx_ioctl_get_rate(dev, NULL, &(iwr->u.bitrate), - NULL); - break; - - case SIOCSIWRTS: - /* set RTS threshold value */ - result = acx_ioctl_set_rts(dev, NULL, &(iwr->u.rts), NULL); - break; - case SIOCGIWRTS: - /* get RTS threshold value */ - result = acx_ioctl_get_rts(dev, NULL, &(iwr->u.rts), NULL); - break; - - /* case SIOCSIWFRAG: */ - /* case SIOCGIWFRAG: */ +/* if you plan to reorder something, make sure to reorder all other places + * accordingly! */ +/* SET/GET convention: SETs must have even position, GETs odd */ +#define ACX100_IOCTL SIOCIWFIRSTPRIV +enum { + ACX100_IOCTL_DEBUG = ACX100_IOCTL, + ACX100_IOCTL_GET__________UNUSED1, + ACX100_IOCTL_SET_PLED, + ACX100_IOCTL_GET_PLED, + ACX100_IOCTL_SET_RATES, + ACX100_IOCTL_LIST_DOM, + ACX100_IOCTL_SET_DOM, + ACX100_IOCTL_GET_DOM, + ACX100_IOCTL_SET_SCAN_PARAMS, + ACX100_IOCTL_GET_SCAN_PARAMS, + ACX100_IOCTL_SET_PREAMB, + ACX100_IOCTL_GET_PREAMB, + ACX100_IOCTL_SET_ANT, + ACX100_IOCTL_GET_ANT, + ACX100_IOCTL_RX_ANT, + ACX100_IOCTL_TX_ANT, + ACX100_IOCTL_SET_PHY_AMP_BIAS, + ACX100_IOCTL_GET_PHY_CHAN_BUSY, + ACX100_IOCTL_SET_ED, + ACX100_IOCTL_GET__________UNUSED3, + ACX100_IOCTL_SET_CCA, + ACX100_IOCTL_GET__________UNUSED4, + ACX100_IOCTL_MONITOR, + ACX100_IOCTL_TEST, + ACX100_IOCTL_DBG_SET_MASKS, + ACX111_IOCTL_INFO, + ACX100_IOCTL_DBG_SET_IO, + ACX100_IOCTL_DBG_GET_IO +}; -#if WIRELESS_EXT > 9 - case SIOCGIWTXPOW: - /* get tx power */ - result = acx_ioctl_get_txpow(dev, NULL, &(iwr->u.txpower), - NULL); - break; - case SIOCSIWTXPOW: - /* set tx power */ - result = acx_ioctl_set_txpow(dev, NULL, &(iwr->u.txpower), - NULL); - break; +static const iw_handler acx_ioctl_private_handler[] = +{ +#if ACX_DEBUG +[ACX100_IOCTL_DEBUG - ACX100_IOCTL] = acx_ioctl_set_debug, #endif +[ACX100_IOCTL_SET_PLED - ACX100_IOCTL] = acx100_ioctl_set_led_power, +[ACX100_IOCTL_GET_PLED - ACX100_IOCTL] = acx100_ioctl_get_led_power, +[ACX100_IOCTL_SET_RATES - ACX100_IOCTL] = acx_ioctl_set_rates, +[ACX100_IOCTL_LIST_DOM - ACX100_IOCTL] = acx_ioctl_list_reg_domain, +[ACX100_IOCTL_SET_DOM - ACX100_IOCTL] = acx_ioctl_set_reg_domain, +[ACX100_IOCTL_GET_DOM - ACX100_IOCTL] = acx_ioctl_get_reg_domain, +[ACX100_IOCTL_SET_SCAN_PARAMS - ACX100_IOCTL] = acx_ioctl_set_scan_params, +[ACX100_IOCTL_GET_SCAN_PARAMS - ACX100_IOCTL] = acx_ioctl_get_scan_params, +[ACX100_IOCTL_SET_PREAMB - ACX100_IOCTL] = acx_ioctl_set_short_preamble, +[ACX100_IOCTL_GET_PREAMB - ACX100_IOCTL] = acx_ioctl_get_short_preamble, +[ACX100_IOCTL_SET_ANT - ACX100_IOCTL] = acx_ioctl_set_antenna, +[ACX100_IOCTL_GET_ANT - ACX100_IOCTL] = acx_ioctl_get_antenna, +[ACX100_IOCTL_RX_ANT - ACX100_IOCTL] = acx_ioctl_set_rx_antenna, +[ACX100_IOCTL_TX_ANT - ACX100_IOCTL] = acx_ioctl_set_tx_antenna, +[ACX100_IOCTL_SET_PHY_AMP_BIAS - ACX100_IOCTL] = acx100_ioctl_set_phy_amp_bias, +[ACX100_IOCTL_GET_PHY_CHAN_BUSY - ACX100_IOCTL] = acx_ioctl_get_phy_chan_busy_percentage, +[ACX100_IOCTL_SET_ED - ACX100_IOCTL] = acx_ioctl_set_ed_threshold, +[ACX100_IOCTL_SET_CCA - ACX100_IOCTL] = acx_ioctl_set_cca, +[ACX100_IOCTL_MONITOR - ACX100_IOCTL] = acx_ioctl_wlansniff, +[ACX100_IOCTL_TEST - ACX100_IOCTL] = acx_ioctl_unknown11, +[ACX100_IOCTL_DBG_SET_MASKS - ACX100_IOCTL] = acx_ioctl_dbg_set_masks, +[ACX111_IOCTL_INFO - ACX100_IOCTL] = acx111_ioctl_info, +}; - case SIOCSIWRETRY: - result = acx_ioctl_set_retry(dev, NULL, &(iwr->u.retry), NULL); - break; - - case SIOCGIWRETRY: - result = acx_ioctl_get_retry(dev, NULL, &(iwr->u.retry), NULL); - break; - - case SIOCSIWENCODE: - { - /* set encoding token & mode */ - u8 key[29]; - if (iwr->u.encoding.pointer) { - if (iwr->u.encoding.length > 29) { - result = -E2BIG; - break; - } - if (copy_from_user(key, iwr->u.encoding.pointer, - iwr->u.encoding.length)) { - result = -EFAULT; - break; - } - } - else - if (iwr->u.encoding.length) { - result = -EINVAL; - break; - } - result = acx_ioctl_set_encode(dev, NULL, - &(iwr->u.encoding), key); - } - break; - - case SIOCGIWENCODE: - { - /* get encoding token & mode */ - u8 key[29]; - - result = acx_ioctl_get_encode(dev, NULL, - &(iwr->u.encoding), key); - if (iwr->u.encoding.pointer) { - if (copy_to_user(iwr->u.encoding.pointer, - key, iwr->u.encoding.length)) - result = -EFAULT; - } - } - break; - /******************** iwpriv ioctls below ********************/ +static const struct iw_priv_args acx_ioctl_private_args[] = { #if ACX_DEBUG - case ACX100_IOCTL_DEBUG: - acx_ioctl_set_debug(dev, NULL, NULL, iwr->u.name); - break; +{ cmd : ACX100_IOCTL_DEBUG, + set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetDebug" }, #endif +{ cmd : ACX100_IOCTL_SET_PLED, + set_args : IW_PRIV_TYPE_BYTE | 2, + get_args : 0, + name : "SetLEDPower" }, +{ cmd : ACX100_IOCTL_GET_PLED, + set_args : 0, + get_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 2, + name : "GetLEDPower" }, +{ cmd : ACX100_IOCTL_SET_RATES, + set_args : IW_PRIV_TYPE_CHAR | 256, + get_args : 0, + name : "SetRates" }, +{ cmd : ACX100_IOCTL_LIST_DOM, + set_args : 0, + get_args : 0, + name : "ListRegDomain" }, +{ cmd : ACX100_IOCTL_SET_DOM, + set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetRegDomain" }, +{ cmd : ACX100_IOCTL_GET_DOM, + set_args : 0, + get_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + name : "GetRegDomain" }, +{ cmd : ACX100_IOCTL_SET_SCAN_PARAMS, + set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 4, + get_args : 0, + name : "SetScanParams" }, +{ cmd : ACX100_IOCTL_GET_SCAN_PARAMS, + set_args : 0, + get_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 4, + name : "GetScanParams" }, +{ cmd : ACX100_IOCTL_SET_PREAMB, + set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetSPreamble" }, +{ cmd : ACX100_IOCTL_GET_PREAMB, + set_args : 0, + get_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + name : "GetSPreamble" }, +{ cmd : ACX100_IOCTL_SET_ANT, + set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetAntenna" }, +{ cmd : ACX100_IOCTL_GET_ANT, + set_args : 0, + get_args : 0, + name : "GetAntenna" }, +{ cmd : ACX100_IOCTL_RX_ANT, + set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetRxAnt" }, +{ cmd : ACX100_IOCTL_TX_ANT, + set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetTxAnt" }, +{ cmd : ACX100_IOCTL_SET_PHY_AMP_BIAS, + set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetPhyAmpBias"}, +{ cmd : ACX100_IOCTL_GET_PHY_CHAN_BUSY, + set_args : 0, + get_args : 0, + name : "GetPhyChanBusy" }, +{ cmd : ACX100_IOCTL_SET_ED, + set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetED" }, +{ cmd : ACX100_IOCTL_SET_CCA, + set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetCCA" }, +{ cmd : ACX100_IOCTL_MONITOR, + set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, + get_args : 0, + name : "monitor" }, +{ cmd : ACX100_IOCTL_TEST, + set_args : 0, + get_args : 0, + name : "Test" }, +{ cmd : ACX100_IOCTL_DBG_SET_MASKS, + set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, + get_args : 0, + name : "DbgSetMasks" }, +{ cmd : ACX111_IOCTL_INFO, + set_args : 0, + get_args : 0, + name : "GetAcx111Info" }, +{ cmd : ACX100_IOCTL_DBG_SET_IO, + set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 4, + get_args : 0, + name : "DbgSetIO" }, +{ cmd : ACX100_IOCTL_DBG_GET_IO, + set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, + get_args : 0, + name : "DbgGetIO" }, +}; - case ACX100_IOCTL_SET_PLED: - acx100_ioctl_set_led_power(dev, NULL, NULL, iwr->u.name); - break; - - case ACX100_IOCTL_GET_PLED: - acx100_ioctl_get_led_power(dev, NULL, NULL, iwr->u.name); - break; - - case ACX100_IOCTL_LIST_DOM: - acx_ioctl_list_reg_domain(dev, NULL, NULL, NULL); - break; - - case ACX100_IOCTL_SET_DOM: - acx_ioctl_set_reg_domain(dev, NULL, NULL, iwr->u.name); - break; - - case ACX100_IOCTL_GET_DOM: - acx_ioctl_get_reg_domain(dev, NULL, NULL, iwr->u.name); - break; - - case ACX100_IOCTL_SET_SCAN_PARAMS: - acx_ioctl_set_scan_params(dev, NULL, NULL, iwr->u.name); - break; - - case ACX100_IOCTL_GET_SCAN_PARAMS: - acx_ioctl_get_scan_params(dev, NULL, NULL, iwr->u.name); - break; - - case ACX100_IOCTL_SET_PREAMB: - acx_ioctl_set_short_preamble(dev, NULL, NULL, iwr->u.name); - break; - - case ACX100_IOCTL_GET_PREAMB: - acx_ioctl_get_short_preamble(dev, NULL, NULL, iwr->u.name); - break; - - case ACX100_IOCTL_SET_ANT: - acx_ioctl_set_antenna(dev, NULL, NULL, iwr->u.name); - break; - - case ACX100_IOCTL_GET_ANT: - acx_ioctl_get_antenna(dev, NULL, NULL, NULL); - break; - - case ACX100_IOCTL_RX_ANT: - acx_ioctl_set_rx_antenna(dev, NULL, NULL, iwr->u.name); - break; - - case ACX100_IOCTL_TX_ANT: - acx_ioctl_set_tx_antenna(dev, NULL, NULL, iwr->u.name); - break; - - case ACX100_IOCTL_SET_ED: - acx_ioctl_set_ed_threshold(dev, NULL, NULL, iwr->u.name); - break; - - case ACX100_IOCTL_SET_CCA: - acx_ioctl_set_cca(dev, NULL, NULL, iwr->u.name); - break; - - case ACX100_IOCTL_MONITOR: /* set sniff (monitor) mode */ - log(L_IOCTL, "%s: IWPRIV monitor\n", dev->name); - - /* can only be done by admin */ - if (!capable(CAP_NET_ADMIN)) { - result = -EPERM; - break; - } - result = acx_ioctl_wlansniff(dev, NULL, NULL, iwr->u.name); - break; - - case ACX100_IOCTL_TEST: - acx_ioctl_unknown11(dev, NULL, NULL, NULL); - break; - - case ACX111_IOCTL_INFO: - acx111_ioctl_info(dev, NULL, NULL, NULL); - break; - - default: - log(L_IOCTL, "wireless ioctl 0x%04X queried " - "but not implemented yet\n", cmd); - result = -EOPNOTSUPP; - break; - } - - if ((priv->dev_state_mask & ACX_STATE_IFACE_UP) && priv->set_mask) { - acx_sem_lock(priv); - acx_s_update_card_settings(priv); - acx_sem_unlock(priv); - } - - /* older WEs don't have a commit handler, - * so we need to fix return code in this case */ - if (-EINPROGRESS == result) - result = 0; - return result; -} -#endif /* WE < 13 */ +const struct iw_handler_def acx_ioctl_handler_def = +{ + .num_standard = VEC_SIZE(acx_ioctl_handler), + .num_private = VEC_SIZE(acx_ioctl_private_handler), + .num_private_args = VEC_SIZE(acx_ioctl_private_args), + .standard = (iw_handler *) acx_ioctl_handler, + .private = (iw_handler *) acx_ioctl_private_handler, + .private_args = (struct iw_priv_args *) acx_ioctl_private_args, +#if IW_HANDLER_VERSION > 5 + .get_wireless_stats = acx_e_get_wireless_stats +#endif /* IW > 5 */ +}; diff -puN drivers/net/wireless/tiacx/pci.c~update-mm-acx-driver-to-version-0331 drivers/net/wireless/tiacx/pci.c --- devel/drivers/net/wireless/tiacx/pci.c~update-mm-acx-driver-to-version-0331 2006-01-31 18:11:09.000000000 -0800 +++ devel-akpm/drivers/net/wireless/tiacx/pci.c 2006-01-31 18:11:09.000000000 -0800 @@ -33,11 +33,10 @@ #include #include +#include /* required for Lx 2.6.8 ?? */ #include #include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) #include -#endif #include #include #include @@ -45,9 +44,7 @@ #include #include #include -#if WIRELESS_EXT >= 13 #include -#endif #include #include #include @@ -85,17 +82,28 @@ #define CARD_EEPROM_ID_SIZE 6 +#ifndef PCI_D0 +/* From include/linux/pci.h */ +#define PCI_D0 0 +#define PCI_D1 1 +#define PCI_D2 2 +#define PCI_D3hot 3 +#define PCI_D3cold 4 +#define PCI_UNKNOWN 5 +#define PCI_POWER_ERROR -1 +#endif + /*********************************************************************** */ -static void acxpci_i_tx_timeout(netdevice_t *dev); +static void acxpci_i_tx_timeout(struct net_device *ndev); static irqreturn_t acxpci_i_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void acxpci_i_set_multicast_list(netdevice_t *dev); +static void acxpci_i_set_multicast_list(struct net_device *ndev); -static int acxpci_e_open(netdevice_t *dev); -static int acxpci_e_close(netdevice_t *dev); -static void acxpci_s_up(netdevice_t *dev); -static void acxpci_s_down(netdevice_t *dev); +static int acxpci_e_open(struct net_device *ndev); +static int acxpci_e_close(struct net_device *ndev); +static void acxpci_s_up(struct net_device *ndev); +static void acxpci_s_down(struct net_device *ndev); /*********************************************************************** @@ -107,49 +115,49 @@ static void acxpci_s_down(netdevice_t *d #define INLINE_IO static inline INLINE_IO u32 -read_reg32(wlandevice_t *priv, unsigned int offset) +read_reg32(acx_device_t *adev, unsigned int offset) { #if ACX_IO_WIDTH == 32 - return readl((u8 *)priv->iobase + priv->io[offset]); + return readl((u8 *)adev->iobase + adev->io[offset]); #else - return readw((u8 *)priv->iobase + priv->io[offset]) - + (readw((u8 *)priv->iobase + priv->io[offset] + 2) << 16); + return readw((u8 *)adev->iobase + adev->io[offset]) + + (readw((u8 *)adev->iobase + adev->io[offset] + 2) << 16); #endif } INLINE_IO u16 -read_reg16(wlandevice_t *priv, unsigned int offset) +read_reg16(acx_device_t *adev, unsigned int offset) { - return readw((u8 *)priv->iobase + priv->io[offset]); + return readw((u8 *)adev->iobase + adev->io[offset]); } INLINE_IO u8 -read_reg8(wlandevice_t *priv, unsigned int offset) +read_reg8(acx_device_t *adev, unsigned int offset) { - return readb((u8 *)priv->iobase + priv->io[offset]); + return readb((u8 *)adev->iobase + adev->io[offset]); } INLINE_IO void -write_reg32(wlandevice_t *priv, unsigned int offset, u32 val) +write_reg32(acx_device_t *adev, unsigned int offset, u32 val) { #if ACX_IO_WIDTH == 32 - writel(val, (u8 *)priv->iobase + priv->io[offset]); + writel(val, (u8 *)adev->iobase + adev->io[offset]); #else - writew(val & 0xffff, (u8 *)priv->iobase + priv->io[offset]); - writew(val >> 16, (u8 *)priv->iobase + priv->io[offset] + 2); + writew(val & 0xffff, (u8 *)adev->iobase + adev->io[offset]); + writew(val >> 16, (u8 *)adev->iobase + adev->io[offset] + 2); #endif } INLINE_IO void -write_reg16(wlandevice_t *priv, unsigned int offset, u16 val) +write_reg16(acx_device_t *adev, unsigned int offset, u16 val) { - writew(val, (u8 *)priv->iobase + priv->io[offset]); + writew(val, (u8 *)adev->iobase + adev->io[offset]); } INLINE_IO void -write_reg8(wlandevice_t *priv, unsigned int offset, u8 val) +write_reg8(acx_device_t *adev, unsigned int offset, u8 val) { - writeb(val, (u8 *)priv->iobase + priv->io[offset]); + writeb(val, (u8 *)adev->iobase + adev->io[offset]); } /* Handle PCI posting properly: @@ -158,100 +166,90 @@ write_reg8(wlandevice_t *priv, unsigned * This call has to be made if there is no read following (which would flush the data * to the adapter), yet the written data has to reach the adapter immediately. */ INLINE_IO void -write_flush(wlandevice_t *priv) +write_flush(acx_device_t *adev) { - /* readb(priv->iobase + priv->io[IO_ACX_INFO_MAILBOX_OFFS]); */ + /* readb(adev->iobase + adev->io[IO_ACX_INFO_MAILBOX_OFFS]); */ /* faster version (accesses the first register, IO_ACX_SOFT_RESET, * which should also be safe): */ - readb(priv->iobase); + readb(adev->iobase); } /*********************************************************************** */ -typedef struct acx_device { - netdevice_t *newest; -} acx_device_t; - -/* if this driver was only about PCI devices, then we probably wouldn't - * need this linked list. - * But if we want to register ALL kinds of devices in one global list, - * then we need it and need to maintain it properly. */ -static struct acx_device root_acx_dev = { - .newest = NULL, -}; -DECLARE_MUTEX(root_acx_dev_sem); +static struct net_device *root_adev_newest = NULL; +DECLARE_MUTEX(root_adev_sem); /*********************************************************************** */ static inline txdesc_t* -get_txdesc(wlandevice_t* priv, int index) +get_txdesc(acx_device_t *adev, int index) { - return (txdesc_t*) (((u8*)priv->txdesc_start) + index * priv->txdesc_size); + return (txdesc_t*) (((u8*)adev->txdesc_start) + index * adev->txdesc_size); } static inline txdesc_t* -advance_txdesc(wlandevice_t* priv, txdesc_t* txdesc, int inc) +advance_txdesc(acx_device_t *adev, txdesc_t* txdesc, int inc) { - return (txdesc_t*) (((u8*)txdesc) + inc * priv->txdesc_size); + return (txdesc_t*) (((u8*)txdesc) + inc * adev->txdesc_size); } static txhostdesc_t* -get_txhostdesc(wlandevice_t* priv, txdesc_t* txdesc) +get_txhostdesc(acx_device_t *adev, txdesc_t* txdesc) { - int index = (u8*)txdesc - (u8*)priv->txdesc_start; - if (ACX_DEBUG && (index % priv->txdesc_size)) { + int index = (u8*)txdesc - (u8*)adev->txdesc_start; + if (unlikely(ACX_DEBUG && (index % adev->txdesc_size))) { printk("bad txdesc ptr %p\n", txdesc); return NULL; } - index /= priv->txdesc_size; - if (ACX_DEBUG && (index >= TX_CNT)) { + index /= adev->txdesc_size; + if (unlikely(ACX_DEBUG && (index >= TX_CNT))) { printk("bad txdesc ptr %p\n", txdesc); return NULL; } - return &priv->txhostdesc_start[index*2]; + return &adev->txhostdesc_start[index*2]; } static inline client_t* -get_txc(wlandevice_t* priv, txdesc_t* txdesc) +get_txc(acx_device_t *adev, txdesc_t* txdesc) { - int index = (u8*)txdesc - (u8*)priv->txdesc_start; - if (ACX_DEBUG && (index % priv->txdesc_size)) { + int index = (u8*)txdesc - (u8*)adev->txdesc_start; + if (unlikely(ACX_DEBUG && (index % adev->txdesc_size))) { printk("bad txdesc ptr %p\n", txdesc); return NULL; } - index /= priv->txdesc_size; - if (ACX_DEBUG && (index >= TX_CNT)) { + index /= adev->txdesc_size; + if (unlikely(ACX_DEBUG && (index >= TX_CNT))) { printk("bad txdesc ptr %p\n", txdesc); return NULL; } - return priv->txc[index]; + return adev->txc[index]; } static inline u16 -get_txr(wlandevice_t* priv, txdesc_t* txdesc) +get_txr(acx_device_t *adev, txdesc_t* txdesc) { - int index = (u8*)txdesc - (u8*)priv->txdesc_start; - index /= priv->txdesc_size; - return priv->txr[index]; + int index = (u8*)txdesc - (u8*)adev->txdesc_start; + index /= adev->txdesc_size; + return adev->txr[index]; } static inline void -put_txcr(wlandevice_t* priv, txdesc_t* txdesc, client_t* c, u16 r111) +put_txcr(acx_device_t *adev, txdesc_t* txdesc, client_t* c, u16 r111) { - int index = (u8*)txdesc - (u8*)priv->txdesc_start; - if (ACX_DEBUG && (index % priv->txdesc_size)) { + int index = (u8*)txdesc - (u8*)adev->txdesc_start; + if (unlikely(ACX_DEBUG && (index % adev->txdesc_size))) { printk("bad txdesc ptr %p\n", txdesc); return; } - index /= priv->txdesc_size; - if (ACX_DEBUG && (index >= TX_CNT)) { + index /= adev->txdesc_size; + if (unlikely(ACX_DEBUG && (index >= TX_CNT))) { printk("bad txdesc ptr %p\n", txdesc); return; } - priv->txc[index] = c; - priv->txr[index] = r111; + adev->txc[index] = c; + adev->txr[index] = r111; } @@ -267,37 +265,38 @@ put_txcr(wlandevice_t* priv, txdesc_t* t ** connected card is a legal one or not. ** ** Arguments: -** priv ptr to wlandevice structure +** adev ptr to acx_device structure ** addr address to read in the EEPROM ** charbuf ptr to a char. This is where the read octet ** will be stored */ int -acxpci_read_eeprom_byte(wlandevice_t *priv, u32 addr, u8 *charbuf) +acxpci_read_eeprom_byte(acx_device_t *adev, u32 addr, u8 *charbuf) { int result; int count; - write_reg32(priv, IO_ACX_EEPROM_CFG, 0); - write_reg32(priv, IO_ACX_EEPROM_ADDR, addr); - write_flush(priv); - write_reg32(priv, IO_ACX_EEPROM_CTL, 2); + write_reg32(adev, IO_ACX_EEPROM_CFG, 0); + write_reg32(adev, IO_ACX_EEPROM_ADDR, addr); + write_flush(adev); + write_reg32(adev, IO_ACX_EEPROM_CTL, 2); count = 0xffff; - while (read_reg16(priv, IO_ACX_EEPROM_CTL)) { + while (read_reg16(adev, IO_ACX_EEPROM_CTL)) { /* scheduling away instead of CPU burning loop * doesn't seem to work here at all: * awful delay, sometimes also failure. * Doesn't matter anyway (only small delay). */ if (unlikely(!--count)) { printk("%s: timeout waiting for EEPROM read\n", - priv->netdev->name); + adev->ndev->name); result = NOT_OK; goto fail; } + cpu_relax(); } - *charbuf = read_reg8(priv, IO_ACX_EEPROM_DATA); + *charbuf = read_reg8(adev, IO_ACX_EEPROM_DATA); log(L_DEBUG, "EEPROM at 0x%04X = 0x%02X\n", addr, *charbuf); result = OK; @@ -312,7 +311,7 @@ fail: */ #ifdef UNUSED int -acxpci_s_write_eeprom(wlandevice_t *priv, u32 addr, u32 len, const u8 *charbuf) +acxpci_s_write_eeprom(acx_device_t *adev, u32 addr, u32 len, const u8 *charbuf) { u8 *data_verify = NULL; unsigned long flags; @@ -344,47 +343,50 @@ acxpci_s_write_eeprom(wlandevice_t *priv * but you probably have to modify GPIO_OUT, too, * and you probably need to activate a different GPIO * line instead! */ - gpio_orig = read_reg16(priv, IO_ACX_GPIO_OE); - write_reg16(priv, IO_ACX_GPIO_OE, gpio_orig & ~1); - write_flush(priv); + gpio_orig = read_reg16(adev, IO_ACX_GPIO_OE); + write_reg16(adev, IO_ACX_GPIO_OE, gpio_orig & ~1); + write_flush(adev); /* ok, now start writing the data out */ for (i = 0; i < len; i++) { - write_reg32(priv, IO_ACX_EEPROM_CFG, 0); - write_reg32(priv, IO_ACX_EEPROM_ADDR, addr + i); - write_reg32(priv, IO_ACX_EEPROM_DATA, *(charbuf + i)); - write_flush(priv); - write_reg32(priv, IO_ACX_EEPROM_CTL, 1); + write_reg32(adev, IO_ACX_EEPROM_CFG, 0); + write_reg32(adev, IO_ACX_EEPROM_ADDR, addr + i); + write_reg32(adev, IO_ACX_EEPROM_DATA, *(charbuf + i)); + write_flush(adev); + write_reg32(adev, IO_ACX_EEPROM_CTL, 1); - while (read_reg16(priv, IO_ACX_EEPROM_CTL)) { - if (unlikely(++count > 0xffff)) { + count = 0xffff; + while (read_reg16(adev, IO_ACX_EEPROM_CTL)) { + if (unlikely(!--count)) { printk("WARNING, DANGER!!! " "Timeout waiting for EEPROM write\n"); goto end; } + cpu_relax(); } } /* disable EEPROM writing */ - write_reg16(priv, IO_ACX_GPIO_OE, gpio_orig); - write_flush(priv); + write_reg16(adev, IO_ACX_GPIO_OE, gpio_orig); + write_flush(adev); /* now start a verification run */ - count = 0xffff; for (i = 0; i < len; i++) { - write_reg32(priv, IO_ACX_EEPROM_CFG, 0); - write_reg32(priv, IO_ACX_EEPROM_ADDR, addr + i); - write_flush(priv); - write_reg32(priv, IO_ACX_EEPROM_CTL, 2); + write_reg32(adev, IO_ACX_EEPROM_CFG, 0); + write_reg32(adev, IO_ACX_EEPROM_ADDR, addr + i); + write_flush(adev); + write_reg32(adev, IO_ACX_EEPROM_CTL, 2); - while (read_reg16(priv, IO_ACX_EEPROM_CTL)) { + count = 0xffff; + while (read_reg16(adev, IO_ACX_EEPROM_CTL)) { if (unlikely(!--count)) { printk("timeout waiting for EEPROM read\n"); goto end; } + cpu_relax(); } - data_verify[i] = read_reg16(priv, IO_ACX_EEPROM_DATA); + data_verify[i] = read_reg16(adev, IO_ACX_EEPROM_DATA); } if (0 == memcmp(charbuf, data_verify, len)) @@ -402,36 +404,37 @@ end: ** acxpci_s_read_phy_reg ** ** Messing with rx/tx disabling and enabling here -** (write_reg32(priv, IO_ACX_ENABLE, 0b000000xx)) kills traffic +** (write_reg32(adev, IO_ACX_ENABLE, 0b000000xx)) kills traffic */ int -acxpci_s_read_phy_reg(wlandevice_t *priv, u32 reg, u8 *charbuf) +acxpci_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf) { int result = NOT_OK; int count; FN_ENTER; - write_reg32(priv, IO_ACX_PHY_ADDR, reg); - write_flush(priv); - write_reg32(priv, IO_ACX_PHY_CTL, 2); + write_reg32(adev, IO_ACX_PHY_ADDR, reg); + write_flush(adev); + write_reg32(adev, IO_ACX_PHY_CTL, 2); count = 0xffff; - while (read_reg32(priv, IO_ACX_PHY_CTL)) { + while (read_reg32(adev, IO_ACX_PHY_CTL)) { /* scheduling away instead of CPU burning loop * doesn't seem to work here at all: * awful delay, sometimes also failure. * Doesn't matter anyway (only small delay). */ if (unlikely(!--count)) { printk("%s: timeout waiting for phy read\n", - priv->netdev->name); + adev->ndev->name); *charbuf = 0; goto fail; } + cpu_relax(); } log(L_DEBUG, "count was %u\n", count); - *charbuf = read_reg8(priv, IO_ACX_PHY_DATA); + *charbuf = read_reg8(adev, IO_ACX_PHY_DATA); log(L_DEBUG, "radio PHY at 0x%04X = 0x%02X\n", *charbuf, reg); result = OK; @@ -445,17 +448,18 @@ fail: /*********************************************************************** */ int -acxpci_s_write_phy_reg(wlandevice_t *priv, u32 reg, u8 value) +acxpci_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value) { FN_ENTER; /* mprusko said that 32bit accesses result in distorted sensitivity - * on his card. Unconfirmed, looks like it's not true. */ - write_reg32(priv, IO_ACX_PHY_DATA, value); - write_reg32(priv, IO_ACX_PHY_ADDR, reg); - write_flush(priv); - write_reg32(priv, IO_ACX_PHY_CTL, 1); - write_flush(priv); + * on his card. Unconfirmed, looks like it's not true (most likely since we + * now properly flush writes). */ + write_reg32(adev, IO_ACX_PHY_DATA, value); + write_reg32(adev, IO_ACX_PHY_ADDR, reg); + write_flush(adev); + write_reg32(adev, IO_ACX_PHY_CTL, 1); + write_flush(adev); log(L_DEBUG, "radio PHY write 0x%02X at 0x%04X\n", value, reg); FN_EXIT1(OK); @@ -471,7 +475,7 @@ acxpci_s_write_phy_reg(wlandevice_t *pri ** Write the firmware image into the card. ** ** Arguments: -** priv wlan device structure +** adev wlan device structure ** apfw_image firmware image. ** ** Returns: @@ -479,7 +483,7 @@ acxpci_s_write_phy_reg(wlandevice_t *pri ** 0 success */ static int -acxpci_s_write_fw(wlandevice_t *priv, const firmware_image_t *apfw_image, u32 offset) +acxpci_s_write_fw(acx_device_t *adev, const firmware_image_t *apfw_image, u32 offset) { int len, size; u32 sum, v32; @@ -490,14 +494,14 @@ acxpci_s_write_fw(wlandevice_t *priv, co sum = image[0]+image[1]+image[2]+image[3]; image += 4; - write_reg32(priv, IO_ACX_SLV_END_CTL, 0); + write_reg32(adev, IO_ACX_SLV_END_CTL, 0); #if NO_AUTO_INCREMENT - write_reg32(priv, IO_ACX_SLV_MEM_CTL, 0); /* use basic mode */ + write_reg32(adev, IO_ACX_SLV_MEM_CTL, 0); /* use basic mode */ #else - write_reg32(priv, IO_ACX_SLV_MEM_CTL, 1); /* use autoincrement mode */ - write_reg32(priv, IO_ACX_SLV_MEM_ADDR, offset); /* configure start address */ - write_flush(priv); + write_reg32(adev, IO_ACX_SLV_MEM_CTL, 1); /* use autoincrement mode */ + write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset); /* configure start address */ + write_flush(adev); #endif len = 0; @@ -510,10 +514,10 @@ acxpci_s_write_fw(wlandevice_t *priv, co len += 4; #if NO_AUTO_INCREMENT - write_reg32(priv, IO_ACX_SLV_MEM_ADDR, offset + len - 4); - write_flush(priv); + write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset + len - 4); + write_flush(adev); #endif - write_reg32(priv, IO_ACX_SLV_MEM_DATA, v32); + write_reg32(adev, IO_ACX_SLV_MEM_DATA, v32); } log(L_DEBUG, "firmware written, size:%d sum1:%x sum2:%x\n", @@ -531,7 +535,7 @@ acxpci_s_write_fw(wlandevice_t *priv, co ** the firmware image written into the card. ** ** Arguments: -** priv wlan device structure +** adev wlan device structure ** apfw_image firmware image. ** ** Returns: @@ -539,10 +543,10 @@ acxpci_s_write_fw(wlandevice_t *priv, co ** OK success */ static int -acxpci_s_validate_fw(wlandevice_t *priv, const firmware_image_t *apfw_image, +acxpci_s_validate_fw(acx_device_t *adev, const firmware_image_t *apfw_image, u32 offset) { - u32 v32, w32, sum; + u32 sum, v32, w32; int len, size; int result = OK; /* we skip the first four bytes which contain the control sum */ @@ -552,13 +556,13 @@ acxpci_s_validate_fw(wlandevice_t *priv, sum = image[0]+image[1]+image[2]+image[3]; image += 4; - write_reg32(priv, IO_ACX_SLV_END_CTL, 0); + write_reg32(adev, IO_ACX_SLV_END_CTL, 0); #if NO_AUTO_INCREMENT - write_reg32(priv, IO_ACX_SLV_MEM_CTL, 0); /* use basic mode */ + write_reg32(adev, IO_ACX_SLV_MEM_CTL, 0); /* use basic mode */ #else - write_reg32(priv, IO_ACX_SLV_MEM_CTL, 1); /* use autoincrement mode */ - write_reg32(priv, IO_ACX_SLV_MEM_ADDR, offset); /* configure start address */ + write_reg32(adev, IO_ACX_SLV_MEM_CTL, 1); /* use autoincrement mode */ + write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset); /* configure start address */ #endif len = 0; @@ -570,9 +574,9 @@ acxpci_s_validate_fw(wlandevice_t *priv, len += 4; #if NO_AUTO_INCREMENT - write_reg32(priv, IO_ACX_SLV_MEM_ADDR, offset + len - 4); + write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset + len - 4); #endif - w32 = read_reg32(priv, IO_ACX_SLV_MEM_DATA); + w32 = read_reg32(adev, IO_ACX_SLV_MEM_DATA); if (unlikely(w32 != v32)) { printk("acx: FATAL: firmware upload: " @@ -606,7 +610,7 @@ acxpci_s_validate_fw(wlandevice_t *priv, ** Called from acx_reset_dev */ static int -acxpci_s_upload_fw(wlandevice_t *priv) +acxpci_s_upload_fw(acx_device_t *adev) { firmware_image_t *apfw_image = NULL; int res = NOT_OK; @@ -617,15 +621,15 @@ acxpci_s_upload_fw(wlandevice_t *priv) FN_ENTER; /* Try combined, then main image */ - priv->need_radio_fw = 0; - sprintf(filename, "tiacx1%02dc%02X", - IS_ACX111(priv)*11, priv->radio_type); + adev->need_radio_fw = 0; + snprintf(filename, sizeof(filename), "tiacx1%02dc%02X", + IS_ACX111(adev)*11, adev->radio_type); - apfw_image = acx_s_read_fw(&priv->pdev->dev, filename, &size); + apfw_image = acx_s_read_fw(&adev->pdev->dev, filename, &size); if (!apfw_image) { - priv->need_radio_fw = 1; + adev->need_radio_fw = 1; filename[sizeof("tiacx1NN")-1] = '\0'; - apfw_image = acx_s_read_fw(&priv->pdev->dev, filename, &size); + apfw_image = acx_s_read_fw(&adev->pdev->dev, filename, &size); if (!apfw_image) { FN_EXIT1(NOT_OK); return NOT_OK; @@ -633,16 +637,16 @@ acxpci_s_upload_fw(wlandevice_t *priv) } for (try = 1; try <= 5; try++) { - res = acxpci_s_write_fw(priv, apfw_image, 0); + res = acxpci_s_write_fw(adev, apfw_image, 0); log(L_DEBUG|L_INIT, "acx_write_fw (main/combined):%d\n", res); if (OK == res) { - res = acxpci_s_validate_fw(priv, apfw_image, 0); + res = acxpci_s_validate_fw(adev, apfw_image, 0); log(L_DEBUG|L_INIT, "acx_validate_fw " "(main/combined):%d\n", res); } if (OK == res) { - SET_BIT(priv->dev_state_mask, ACX_STATE_FW_LOADED); + SET_BIT(adev->dev_state_mask, ACX_STATE_FW_LOADED); break; } printk("acx: firmware upload attempt #%d FAILED, " @@ -663,7 +667,7 @@ acxpci_s_upload_fw(wlandevice_t *priv) ** Uploads the appropriate radio module firmware into the card. */ int -acxpci_s_upload_radio(wlandevice_t *priv) +acxpci_s_upload_radio(acx_device_t *adev) { acx_ie_memmap_t mm; firmware_image_t *radio_image; @@ -674,29 +678,29 @@ acxpci_s_upload_radio(wlandevice_t *priv u32 size; char filename[sizeof("tiacx1NNrNN")]; - if (!priv->need_radio_fw) return OK; + if (!adev->need_radio_fw) return OK; FN_ENTER; - acx_s_interrogate(priv, &mm, ACX1xx_IE_MEMORY_MAP); + acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP); offset = le32_to_cpu(mm.CodeEnd); - sprintf(filename, "tiacx1%02dr%02X", - IS_ACX111(priv)*11, - priv->radio_type); - radio_image = acx_s_read_fw(&priv->pdev->dev, filename, &size); + snprintf(filename, sizeof(filename), "tiacx1%02dr%02X", + IS_ACX111(adev)*11, + adev->radio_type); + radio_image = acx_s_read_fw(&adev->pdev->dev, filename, &size); if (!radio_image) { printk("acx: can't load radio module '%s'\n", filename); goto fail; } - acx_s_issue_cmd(priv, ACX1xx_CMD_SLEEP, NULL, 0); + acx_s_issue_cmd(adev, ACX1xx_CMD_SLEEP, NULL, 0); for (try = 1; try <= 5; try++) { - res = acxpci_s_write_fw(priv, radio_image, offset); + res = acxpci_s_write_fw(adev, radio_image, offset); log(L_DEBUG|L_INIT, "acx_write_fw (radio): %d\n", res); if (OK == res) { - res = acxpci_s_validate_fw(priv, radio_image, offset); + res = acxpci_s_validate_fw(adev, radio_image, offset); log(L_DEBUG|L_INIT, "acx_validate_fw (radio): %d\n", res); } @@ -707,7 +711,7 @@ acxpci_s_upload_radio(wlandevice_t *priv acx_s_msleep(1000); /* better wait for a while... */ } - acx_s_issue_cmd(priv, ACX1xx_CMD_WAKE, NULL, 0); + acx_s_issue_cmd(adev, ACX1xx_CMD_WAKE, NULL, 0); radioinit.offset = cpu_to_le32(offset); /* no endian conversion needed, remains in card CPU area: */ radioinit.len = radio_image->size; @@ -718,10 +722,10 @@ acxpci_s_upload_radio(wlandevice_t *priv goto fail; /* will take a moment so let's have a big timeout */ - acx_s_issue_cmd_timeo(priv, ACX1xx_CMD_RADIOINIT, + acx_s_issue_cmd_timeo(adev, ACX1xx_CMD_RADIOINIT, &radioinit, sizeof(radioinit), CMD_TIMEOUT_MS(1000)); - res = acx_s_interrogate(priv, &mm, ACX1xx_IE_MEMORY_MAP); + res = acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP); fail: FN_EXIT1(res); return res; @@ -731,41 +735,34 @@ fail: /*********************************************************************** ** acxpci_l_reset_mac ** -** Arguments: -** wlandevice: private device that contains card device -** Side effects: -** MAC will be reset -** Call context: -** acx_reset_dev -** Comment: -** resets onboard acx MAC +** MAC will be reset +** Call context: reset_dev */ static void -acxpci_l_reset_mac(wlandevice_t *priv) +acxpci_l_reset_mac(acx_device_t *adev) { u16 temp; FN_ENTER; /* halt eCPU */ - temp = read_reg16(priv, IO_ACX_ECPU_CTRL) | 0x1; - write_reg16(priv, IO_ACX_ECPU_CTRL, temp); + temp = read_reg16(adev, IO_ACX_ECPU_CTRL) | 0x1; + write_reg16(adev, IO_ACX_ECPU_CTRL, temp); - /* now do soft reset of eCPU */ - temp = read_reg16(priv, IO_ACX_SOFT_RESET) | 0x1; + /* now do soft reset of eCPU, set bit */ + temp = read_reg16(adev, IO_ACX_SOFT_RESET) | 0x1; log(L_DEBUG, "%s: enable soft reset...\n", __func__); - write_reg16(priv, IO_ACX_SOFT_RESET, temp); - write_flush(priv); + write_reg16(adev, IO_ACX_SOFT_RESET, temp); + write_flush(adev); - /* now reset bit again */ + /* now clear bit again: deassert eCPU reset */ log(L_DEBUG, "%s: disable soft reset and go to init mode...\n", __func__); - /* deassert eCPU reset */ - write_reg16(priv, IO_ACX_SOFT_RESET, temp & ~0x1); + write_reg16(adev, IO_ACX_SOFT_RESET, temp & ~0x1); - /* now start a burst read from initial flash EEPROM */ - temp = read_reg16(priv, IO_ACX_EE_START) | 0x1; - write_reg16(priv, IO_ACX_EE_START, temp); - write_flush(priv); + /* now start a burst read from initial EEPROM */ + temp = read_reg16(adev, IO_ACX_EE_START) | 0x1; + write_reg16(adev, IO_ACX_EE_START, temp); + write_flush(adev); FN_EXIT0; } @@ -775,7 +772,7 @@ acxpci_l_reset_mac(wlandevice_t *priv) ** acxpci_s_verify_init */ static int -acxpci_s_verify_init(wlandevice_t *priv) +acxpci_s_verify_init(acx_device_t *adev) { int result = NOT_OK; unsigned long timeout; @@ -784,10 +781,10 @@ acxpci_s_verify_init(wlandevice_t *priv) timeout = jiffies + 2*HZ; for (;;) { - u16 irqstat = read_reg16(priv, IO_ACX_IRQ_STATUS_NON_DES); + u16 irqstat = read_reg16(adev, IO_ACX_IRQ_STATUS_NON_DES); if (irqstat & HOST_INT_FCS_THRESHOLD) { result = OK; - write_reg16(priv, IO_ACX_IRQ_ACK, HOST_INT_FCS_THRESHOLD); + write_reg16(adev, IO_ACX_IRQ_ACK, HOST_INT_FCS_THRESHOLD); break; } if (time_after(jiffies, timeout)) @@ -814,10 +811,10 @@ acxpci_s_verify_init(wlandevice_t *priv) */ static inline void -acxpci_write_cmd_type_status(wlandevice_t *priv, u16 type, u16 status) +acxpci_write_cmd_type_status(acx_device_t *adev, u16 type, u16 status) { - writel(type | (status << 16), priv->cmd_area); - write_flush(priv); + writel(type | (status << 16), adev->cmd_area); + write_flush(adev); } @@ -825,11 +822,11 @@ acxpci_write_cmd_type_status(wlandevice_ ** acxpci_read_cmd_type_status */ static u32 -acxpci_read_cmd_type_status(wlandevice_t *priv) +acxpci_read_cmd_type_status(acx_device_t *adev) { u32 cmd_type, cmd_status; - cmd_type = readl(priv->cmd_area); + cmd_type = readl(adev->cmd_area); cmd_status = (cmd_type >> 16); cmd_type = (u16)cmd_type; @@ -845,7 +842,7 @@ acxpci_read_cmd_type_status(wlandevice_t ** acxpci_s_reset_dev ** ** Arguments: -** netdevice that contains the wlandevice priv variable +** netdevice that contains the adev variable ** Returns: ** NOT_OK on fail ** OK on success @@ -859,118 +856,128 @@ acxpci_read_cmd_type_status(wlandevice_t */ static inline void -init_mboxes(wlandevice_t *priv) +init_mboxes(acx_device_t *adev) { u32 cmd_offs, info_offs; - cmd_offs = read_reg32(priv, IO_ACX_CMD_MAILBOX_OFFS); - info_offs = read_reg32(priv, IO_ACX_INFO_MAILBOX_OFFS); - priv->cmd_area = (u8 *)priv->iobase2 + cmd_offs; - priv->info_area = (u8 *)priv->iobase2 + info_offs; + cmd_offs = read_reg32(adev, IO_ACX_CMD_MAILBOX_OFFS); + info_offs = read_reg32(adev, IO_ACX_INFO_MAILBOX_OFFS); + adev->cmd_area = (u8 *)adev->iobase2 + cmd_offs; + adev->info_area = (u8 *)adev->iobase2 + info_offs; log(L_DEBUG, "iobase2=%p\n" "cmd_mbox_offset=%X cmd_area=%p\n" "info_mbox_offset=%X info_area=%p\n", - priv->iobase2, - cmd_offs, priv->cmd_area, - info_offs, priv->info_area); + adev->iobase2, + cmd_offs, adev->cmd_area, + info_offs, adev->info_area); } static inline void -read_eeprom_area(wlandevice_t *priv) +read_eeprom_area(acx_device_t *adev) { #if ACX_DEBUG > 1 int offs; u8 tmp; for (offs = 0x8c; offs < 0xb9; offs++) - acxpci_read_eeprom_byte(priv, offs, &tmp); + acxpci_read_eeprom_byte(adev, offs, &tmp); #endif } static int -acxpci_s_reset_dev(wlandevice_t *priv) +acxpci_s_reset_dev(acx_device_t *adev) { const char* msg = ""; unsigned long flags; int result = NOT_OK; u16 hardware_info; u16 ecpu_ctrl; + int count; FN_ENTER; - /* we're doing a reset, so hardware is unavailable */ - /* reset the device to make sure the eCPU is stopped * to upload the firmware correctly */ - acx_lock(priv, flags); + acx_lock(adev, flags); - acxpci_l_reset_mac(priv); + acxpci_l_reset_mac(adev); - ecpu_ctrl = read_reg16(priv, IO_ACX_ECPU_CTRL) & 1; + ecpu_ctrl = read_reg16(adev, IO_ACX_ECPU_CTRL) & 1; if (!ecpu_ctrl) { msg = "eCPU is already running. "; goto end_unlock; } #ifdef WE_DONT_NEED_THAT_DO_WE - if (read_reg16(priv, IO_ACX_SOR_CFG) & 2) { + if (read_reg16(adev, IO_ACX_SOR_CFG) & 2) { /* eCPU most likely means "embedded CPU" */ msg = "eCPU did not start after boot from flash. "; goto end_unlock; } /* check sense on reset flags */ - if (read_reg16(priv, IO_ACX_SOR_CFG) & 0x10) { + if (read_reg16(adev, IO_ACX_SOR_CFG) & 0x10) { printk("%s: eCPU did not start after boot (SOR), " - "is this fatal?\n", priv->netdev->name); + "is this fatal?\n", adev->ndev->name); } #endif /* scan, if any, is stopped now, setting corresponding IRQ bit */ - priv->irq_status |= HOST_INT_SCAN_COMPLETE; + adev->irq_status |= HOST_INT_SCAN_COMPLETE; + + acx_unlock(adev, flags); - acx_unlock(priv, flags); + /* need to know radio type before fw load */ + /* Need to wait for arrival of this information in a loop, + * most probably since eCPU runs some init code from EEPROM + * (started burst read in reset_mac()) which also + * sets the radio type ID */ - /* without this delay acx100 may fail to report hardware_info - ** (see below). Most probably eCPU runs some init code */ - acx_s_msleep(10); - - /* Need to know radio type before fw load */ - hardware_info = read_reg16(priv, IO_ACX_EEPROM_INFORMATION); - priv->form_factor = hardware_info & 0xff; - priv->radio_type = hardware_info >> 8; + count = 0xffff; + do { + hardware_info = read_reg16(adev, IO_ACX_EEPROM_INFORMATION); + if (!--count) { + msg = "eCPU didn't indicate radio type"; + goto end_fail; + } + cpu_relax(); + } while (!(hardware_info & 0xff00)); /* radio type still zero? */ + + /* printk("DEBUG: count %d\n", count); */ + adev->form_factor = hardware_info & 0xff; + adev->radio_type = hardware_info >> 8; /* load the firmware */ - if (OK != acxpci_s_upload_fw(priv)) + if (OK != acxpci_s_upload_fw(adev)) goto end_fail; - acx_s_msleep(10); + /* acx_s_msleep(10); this one really shouldn't be required */ /* now start eCPU by clearing bit */ + write_reg16(adev, IO_ACX_ECPU_CTRL, ecpu_ctrl & ~0x1); log(L_DEBUG, "booted eCPU up and waiting for completion...\n"); - write_reg16(priv, IO_ACX_ECPU_CTRL, ecpu_ctrl & ~0x1); /* wait for eCPU bootup */ - if (OK != acxpci_s_verify_init(priv)) { + if (OK != acxpci_s_verify_init(adev)) { msg = "timeout waiting for eCPU. "; goto end_fail; } log(L_DEBUG, "eCPU has woken up, card is ready to be configured\n"); - init_mboxes(priv); - acxpci_write_cmd_type_status(priv, 0, 0); + init_mboxes(adev); + acxpci_write_cmd_type_status(adev, 0, 0); - /* Test that EEPROM is readable */ - read_eeprom_area(priv); + /* test that EEPROM is readable */ + read_eeprom_area(adev); result = OK; goto end; /* Finish error message. Indicate which function failed */ end_unlock: - acx_unlock(priv, flags); + acx_unlock(adev, flags); end_fail: printk("acx: %sreset_dev() FAILED\n", msg); end: @@ -997,7 +1004,7 @@ end: #if !ACX_DEBUG int acxpci_s_issue_cmd_timeo( - wlandevice_t *priv, + acx_device_t *adev, unsigned int cmd, void *buffer, unsigned buflen, @@ -1006,7 +1013,7 @@ acxpci_s_issue_cmd_timeo( #else int acxpci_s_issue_cmd_timeo_debug( - wlandevice_t *priv, + acx_device_t *adev, unsigned cmd, void *buffer, unsigned buflen, @@ -1023,22 +1030,22 @@ acxpci_s_issue_cmd_timeo_debug( FN_ENTER; - devname = priv->netdev->name; - if (!devname || !devname[0]) + devname = adev->ndev->name; + if (!devname || !devname[0] || devname[4]=='%') devname = "acx"; log(L_CTL, FUNC"(cmd:%s,buflen:%u,timeout:%ums,type:0x%04X)\n", cmdstr, buflen, cmd_timeout, buffer ? le16_to_cpu(((acx_ie_generic_t *)buffer)->type) : -1); - if (!(priv->dev_state_mask & ACX_STATE_FW_LOADED)) { + if (!(adev->dev_state_mask & ACX_STATE_FW_LOADED)) { printk("%s: "FUNC"(): firmware is not loaded yet, " "cannot execute commands!\n", devname); goto bad; } if ((acx_debug & L_DEBUG) && (cmd != ACX1xx_CMD_INTERROGATE)) { - printk("input pdr (len=%u):\n", buflen); + printk("input buffer (len=%u):\n", buflen); acx_dump_bytes(buffer, buflen); } @@ -1047,18 +1054,17 @@ acxpci_s_issue_cmd_timeo_debug( counter = (timeout * 1000 / HZ) - 1; /* in ms */ timeout += jiffies; do { - cmd_status = acxpci_read_cmd_type_status(priv); + cmd_status = acxpci_read_cmd_type_status(adev); /* Test for IDLE state */ if (!cmd_status) break; - if (counter % 10 == 0) { - if (time_after(jiffies, timeout)) - { + if (counter % 5 == 0) { + if (time_after(jiffies, timeout)) { counter = 0; break; } - /* we waited 10 iterations, no luck. Sleep 10 ms */ - acx_s_msleep(10); + /* we waited 5 iterations, no luck. Sleep 5 ms */ + acx_s_msleep(5); } } while (likely(--counter)); @@ -1078,17 +1084,17 @@ acxpci_s_issue_cmd_timeo_debug( * of parameters to read, as data */ #if CMD_DISCOVERY if (cmd == ACX1xx_CMD_INTERROGATE) - memset_io(priv->cmd_area + 4, 0xAA, buflen); + memset_io(adev->cmd_area + 4, 0xAA, buflen); #endif - /* priv->cmd_area points to PCI device's memory, not to RAM! */ - memcpy_toio(priv->cmd_area + 4, buffer, + /* adev->cmd_area points to PCI device's memory, not to RAM! */ + memcpy_toio(adev->cmd_area + 4, buffer, (cmd == ACX1xx_CMD_INTERROGATE) ? 4 : buflen); } /* now write the actual command type */ - acxpci_write_cmd_type_status(priv, cmd, 0); + acxpci_write_cmd_type_status(adev, cmd, 0); /* execute command */ - write_reg16(priv, IO_ACX_INT_TRIG, INT_TRIG_CMD); - write_flush(priv); + write_reg16(adev, IO_ACX_INT_TRIG, INT_TRIG_CMD); + write_flush(adev); /* wait for firmware to process command */ @@ -1099,54 +1105,53 @@ acxpci_s_issue_cmd_timeo_debug( if (unlikely(cmd_timeout > 1199)) cmd_timeout = 1199; /* clear CMD_COMPLETE bit. can be set only by IRQ handler: */ - priv->irq_status &= ~HOST_INT_CMD_COMPLETE; + adev->irq_status &= ~HOST_INT_CMD_COMPLETE; /* we schedule away sometimes (timeout can be large) */ counter = cmd_timeout; timeout = jiffies + cmd_timeout * HZ / 1000; do { - if (!priv->irqs_active) { /* IRQ disabled: poll */ - irqtype = read_reg16(priv, IO_ACX_IRQ_STATUS_NON_DES); + if (!adev->irqs_active) { /* IRQ disabled: poll */ + irqtype = read_reg16(adev, IO_ACX_IRQ_STATUS_NON_DES); if (irqtype & HOST_INT_CMD_COMPLETE) { - write_reg16(priv, IO_ACX_IRQ_ACK, + write_reg16(adev, IO_ACX_IRQ_ACK, HOST_INT_CMD_COMPLETE); break; } } else { /* Wait when IRQ will set the bit */ - irqtype = priv->irq_status; + irqtype = adev->irq_status; if (irqtype & HOST_INT_CMD_COMPLETE) break; } - if (counter % 10 == 0) { - if (time_after(jiffies, timeout)) - { + if (counter % 5 == 0) { + if (time_after(jiffies, timeout)) { counter = 0; break; } - /* we waited 10 iterations, no luck. Sleep 10 ms */ - acx_s_msleep(10); + /* we waited 5 iterations, no luck. Sleep 5 ms */ + acx_s_msleep(5); } } while (likely(--counter)); /* save state for debugging */ - cmd_status = acxpci_read_cmd_type_status(priv); + cmd_status = acxpci_read_cmd_type_status(adev); /* put the card in IDLE state */ - acxpci_write_cmd_type_status(priv, 0, 0); + acxpci_write_cmd_type_status(adev, 0, 0); if (!counter) { /* timed out! */ printk("%s: "FUNC"(): timed out %s for CMD_COMPLETE. " "irq bits:0x%04X irq_status:0x%04X timeout:%dms " "cmd_status:%d (%s)\n", - devname, (priv->irqs_active) ? "waiting" : "polling", - irqtype, priv->irq_status, cmd_timeout, + devname, (adev->irqs_active) ? "waiting" : "polling", + irqtype, adev->irq_status, cmd_timeout, cmd_status, acx_cmd_status_str(cmd_status)); goto bad; } else if (cmd_timeout - counter > 30) { /* if waited >30ms... */ log(L_CTL|L_DEBUG, FUNC"(): %s for CMD_COMPLETE %dms. " "count:%d. Please report\n", - (priv->irqs_active) ? "waited" : "polled", + (adev->irqs_active) ? "waited" : "polled", cmd_timeout - counter, counter); } @@ -1155,7 +1160,9 @@ acxpci_s_issue_cmd_timeo_debug( "Took %dms of %d\n", devname, cmd_status, acx_cmd_status_str(cmd_status), cmd_timeout - counter, cmd_timeout); - /* zero out result buffer */ + /* zero out result buffer + * WARNING: this will trash stack in case of illegally large input + * length! */ if (buffer && buflen) memset(buffer, 0, buflen); goto bad; @@ -1163,8 +1170,8 @@ acxpci_s_issue_cmd_timeo_debug( /* read in result parameters if needed */ if (buffer && buflen && (cmd == ACX1xx_CMD_INTERROGATE)) { - /* priv->cmd_area points to PCI device's memory, not to RAM! */ - memcpy_fromio(buffer, priv->cmd_area + 4, buflen); + /* adev->cmd_area points to PCI device's memory, not to RAM! */ + memcpy_fromio(buffer, adev->cmd_area + 4, buflen); if (acx_debug & L_DEBUG) { printk("output buffer (len=%u): ", buflen); acx_dump_bytes(buffer, buflen); @@ -1230,7 +1237,7 @@ device_ids[] = }; static void -acx_show_card_eeprom_id(wlandevice_t *priv) +acx_show_card_eeprom_id(acx_device_t *adev) { unsigned char buffer[CARD_EEPROM_ID_SIZE]; int i; @@ -1238,10 +1245,9 @@ acx_show_card_eeprom_id(wlandevice_t *pr memset(&buffer, 0, CARD_EEPROM_ID_SIZE); /* use direct EEPROM access */ for (i = 0; i < CARD_EEPROM_ID_SIZE; i++) { - if (OK != acxpci_read_eeprom_byte(priv, + if (OK != acxpci_read_eeprom_byte(adev, ACX100_EEPROM_ID_OFFSET + i, - &buffer[i])) - { + &buffer[i])) { printk("acx: reading EEPROM FAILED\n"); break; } @@ -1269,47 +1275,46 @@ acx_show_card_eeprom_id(wlandevice_t *pr /*********************************************************************** */ static void -acxpci_s_device_chain_add(struct net_device *dev) +acxpci_s_device_chain_add(struct net_device *ndev) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); - down(&root_acx_dev_sem); - priv->prev_nd = root_acx_dev.newest; - root_acx_dev.newest = dev; - priv->netdev = dev; - up(&root_acx_dev_sem); + down(&root_adev_sem); + adev->prev_nd = root_adev_newest; + root_adev_newest = ndev; + adev->ndev = ndev; + up(&root_adev_sem); } static void -acxpci_s_device_chain_remove(struct net_device *dev) +acxpci_s_device_chain_remove(struct net_device *ndev) { struct net_device *querydev; struct net_device *olderdev; struct net_device *newerdev; - down(&root_acx_dev_sem); - querydev = root_acx_dev.newest; + down(&root_adev_sem); + querydev = root_adev_newest; newerdev = NULL; while (querydev) { - olderdev = ((wlandevice_t*)netdev_priv(querydev))->prev_nd; - if (0 == strcmp(querydev->name, dev->name)) { + olderdev = ndev2adev(querydev)->prev_nd; + if (0 == strcmp(querydev->name, ndev->name)) { if (!newerdev) { /* if we were at the beginning of the * list, then it's the list head that * we need to update to point at the * next older device */ - root_acx_dev.newest = olderdev; + root_adev_newest = olderdev; } else { /* it's the device that is newer than us * that we need to update to point at * the device older than us */ - ((wlandevice_t*)netdev_priv(newerdev))-> - prev_nd = olderdev; + ndev2adev(newerdev)->prev_nd = olderdev; } break; } /* "newerdev" is actually the device of the old iteration, - * but since the list starts (root_acx_dev.newest) + * but since the list starts (root_adev_newest) * with the newest devices, * it's newer than the ones following. * Oh the joys of iterating from newest to oldest :-\ */ @@ -1319,7 +1324,7 @@ acxpci_s_device_chain_remove(struct net_ * of the list */ querydev = olderdev; } - up(&root_acx_dev_sem); + up(&root_adev_sem); } @@ -1335,16 +1340,12 @@ static inline void free_coherent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 53) dma_free_coherent(hwdev == NULL ? NULL : &hwdev->dev, size, vaddr, dma_handle); -#else - pci_free_consistent(hwdev, size, vaddr, dma_handle); -#endif } void -acxpci_free_desc_queues(wlandevice_t *priv) +acxpci_free_desc_queues(acx_device_t *adev) { #define ACX_FREE_QUEUE(size, ptr, phyaddr) \ if (ptr) { \ @@ -1355,15 +1356,15 @@ acxpci_free_desc_queues(wlandevice_t *pr FN_ENTER; - ACX_FREE_QUEUE(priv->txhostdesc_area_size, priv->txhostdesc_start, priv->txhostdesc_startphy); - ACX_FREE_QUEUE(priv->txbuf_area_size, priv->txbuf_start, priv->txbuf_startphy); + ACX_FREE_QUEUE(adev->txhostdesc_area_size, adev->txhostdesc_start, adev->txhostdesc_startphy); + ACX_FREE_QUEUE(adev->txbuf_area_size, adev->txbuf_start, adev->txbuf_startphy); - priv->txdesc_start = NULL; + adev->txdesc_start = NULL; - ACX_FREE_QUEUE(priv->rxhostdesc_area_size, priv->rxhostdesc_start, priv->rxhostdesc_startphy); - ACX_FREE_QUEUE(priv->rxbuf_area_size, priv->rxbuf_start, priv->rxbuf_startphy); + ACX_FREE_QUEUE(adev->rxhostdesc_area_size, adev->rxhostdesc_start, adev->rxhostdesc_startphy); + ACX_FREE_QUEUE(adev->rxbuf_area_size, adev->rxbuf_start, adev->rxbuf_startphy); - priv->rxdesc_start = NULL; + adev->rxdesc_start = NULL; FN_EXIT0; } @@ -1373,7 +1374,7 @@ acxpci_free_desc_queues(wlandevice_t *pr ** acxpci_s_delete_dma_regions */ static void -acxpci_s_delete_dma_regions(wlandevice_t *priv) +acxpci_s_delete_dma_regions(acx_device_t *adev) { unsigned long flags; @@ -1381,13 +1382,13 @@ acxpci_s_delete_dma_regions(wlandevice_t /* disable radio Tx/Rx. Shouldn't we use the firmware commands * here instead? Or are we that much down the road that it's no * longer possible here? */ - write_reg16(priv, IO_ACX_ENABLE, 0); + write_reg16(adev, IO_ACX_ENABLE, 0); acx_s_msleep(100); - acx_lock(priv, flags); - acxpci_free_desc_queues(priv); - acx_unlock(priv, flags); + acx_lock(adev, flags); + acxpci_free_desc_queues(adev); + acx_unlock(adev, flags); FN_EXIT0; } @@ -1495,11 +1496,12 @@ IO_ACX111[] = }; static void -dummy_netdev_init(struct net_device *dev) {} +dummy_netdev_init(struct net_device *ndev) {} static int __devinit acxpci_e_probe(struct pci_dev *pdev, const struct pci_device_id *id) { + acx111_ie_configoption_t co; unsigned long mem_region1 = 0; unsigned long mem_region2 = 0; unsigned long mem_region1_size; @@ -1508,41 +1510,15 @@ acxpci_e_probe(struct pci_dev *pdev, con unsigned long phymem2; void *mem1 = NULL; void *mem2 = NULL; - wlandevice_t *priv = NULL; - struct net_device *dev = NULL; + acx_device_t *adev = NULL; + struct net_device *ndev = NULL; const char *chip_name; int result = -EIO; int err; u8 chip_type; -#if SEPARATE_DRIVER_INSTANCES - struct pci_dev *tdev; - unsigned int inited; - static int turn = 0; -#endif /* SEPARATE_DRIVER_INSTANCES */ - FN_ENTER; -#if SEPARATE_DRIVER_INSTANCES - if (card) { - turn++; - inited = 0; - pci_for_each_dev(tdev) { - if (tdev->vendor != PCI_VENDOR_ID_TI) - continue; - - if (tdev == pdev) - break; - if (pci_get_drvdata(tdev)) - inited++; - } - if (inited + turn != card) { - result = -ENODEV; - goto done; - } - } -#endif /* SEPARATE_DRIVER_INSTANCES */ - /* Enable the PCI device */ if (pci_enable_device(pdev)) { printk("acx: pci_enable_device() FAILED\n"); @@ -1553,6 +1529,9 @@ acxpci_e_probe(struct pci_dev *pdev, con /* enable busmastering (required for CardBus) */ pci_set_master(pdev); + /* FIXME: prism54 calls pci_set_mwi() here, + * should we do/support the same? */ + /* chiptype is u8 but id->driver_data is ulong ** Works for now (possible values are 1 and 2) */ chip_type = (u8)id->driver_data; @@ -1612,121 +1591,124 @@ acxpci_e_probe(struct pci_dev *pdev, con goto fail_irq; } - dev = alloc_netdev(sizeof(wlandevice_t), "wlan%d", dummy_netdev_init); + ndev = alloc_netdev(sizeof(*adev), "wlan%d", dummy_netdev_init); /* (NB: memsets to 0 entire area) */ - if (!dev) { + if (!ndev) { printk("acx: no memory for netdevice structure\n"); goto fail_alloc_netdev; } - ether_setup(dev); - dev->open = &acxpci_e_open; - dev->stop = &acxpci_e_close; - dev->hard_start_xmit = &acx_i_start_xmit; - dev->get_stats = &acx_e_get_stats; - dev->get_wireless_stats = &acx_e_get_wireless_stats; -#if WIRELESS_EXT >= 13 - dev->wireless_handlers = (struct iw_handler_def *)&acx_ioctl_handler_def; -#else - dev->do_ioctl = &acx_e_ioctl_old; + ether_setup(ndev); + ndev->open = &acxpci_e_open; + ndev->stop = &acxpci_e_close; + ndev->hard_start_xmit = &acx_i_start_xmit; + ndev->get_stats = &acx_e_get_stats; +#if IW_HANDLER_VERSION <= 5 + ndev->get_wireless_stats = &acx_e_get_wireless_stats; #endif - dev->set_multicast_list = &acxpci_i_set_multicast_list; - dev->tx_timeout = &acxpci_i_tx_timeout; - dev->change_mtu = &acx_e_change_mtu; - dev->watchdog_timeo = 4 * HZ; - dev->irq = pdev->irq; - dev->base_addr = pci_resource_start(pdev, 0); + ndev->wireless_handlers = (struct iw_handler_def *)&acx_ioctl_handler_def; + ndev->set_multicast_list = &acxpci_i_set_multicast_list; + ndev->tx_timeout = &acxpci_i_tx_timeout; + ndev->change_mtu = &acx_e_change_mtu; + ndev->watchdog_timeo = 4 * HZ; + ndev->irq = pdev->irq; + ndev->base_addr = pci_resource_start(pdev, 0); - priv = netdev_priv(dev); - spin_lock_init(&priv->lock); /* initial state: unlocked */ + adev = ndev2adev(ndev); + spin_lock_init(&adev->lock); /* initial state: unlocked */ /* We do not start with downed sem: we want PARANOID_LOCKING to work */ - sema_init(&priv->sem, 1); /* initial state: 1 (upped) */ + sema_init(&adev->sem, 1); /* initial state: 1 (upped) */ /* since nobody can see new netdev yet, we can as well ** just _presume_ that we're under sem (instead of actually taking it): */ - /* acx_sem_lock(priv); */ - priv->pdev = pdev; - priv->dev_type = DEVTYPE_PCI; - priv->chip_type = chip_type; - priv->chip_name = chip_name; - priv->io = (CHIPTYPE_ACX100 == chip_type) ? IO_ACX100 : IO_ACX111; - priv->membase = phymem1; - priv->iobase = mem1; - priv->membase2 = phymem2; - priv->iobase2 = mem2; + /* acx_sem_lock(adev); */ + adev->pdev = pdev; + adev->dev_type = DEVTYPE_PCI; + adev->chip_type = chip_type; + adev->chip_name = chip_name; + adev->io = (CHIPTYPE_ACX100 == chip_type) ? IO_ACX100 : IO_ACX111; + adev->membase = phymem1; + adev->iobase = mem1; + adev->membase2 = phymem2; + adev->iobase2 = mem2; /* to find crashes due to weird driver access * to unconfigured interface (ifup) */ - priv->mgmt_timer.function = (void (*)(unsigned long))0x0000dead; + adev->mgmt_timer.function = (void (*)(unsigned long))0x0000dead; #ifdef NONESSENTIAL_FEATURES - acx_show_card_eeprom_id(priv); + acx_show_card_eeprom_id(adev); #endif /* NONESSENTIAL_FEATURES */ #ifdef SET_MODULE_OWNER - SET_MODULE_OWNER(dev); -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 70) - /* this define and its netdev member exist since 2.5.70 */ - SET_NETDEV_DEV(dev, &pdev->dev); + SET_MODULE_OWNER(ndev); #endif + SET_NETDEV_DEV(ndev, &pdev->dev); /* register new dev in linked list */ - acxpci_s_device_chain_add(dev); + acxpci_s_device_chain_add(ndev); log(L_IRQ|L_INIT, "using IRQ %d\n", pdev->irq); /* need to be able to restore PCI state after a suspend */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) - /* 2.6.9-rc3-mm2 (2.6.9-bk4, too) introduced this shorter version, - then it made its way into 2.6.10 */ pci_save_state(pdev); -#else - pci_save_state(pdev, priv->pci_state); -#endif - pci_set_drvdata(pdev, dev); + pci_set_drvdata(pdev, ndev); - /* ok, pci setup is finished, now start initialising the card */ + /* ok, pci setup is finished, now start initializing the card */ - /* NB: read_reg() reads may return bogus data before reset_dev(). - ** acx100 seems to be more affected than acx111 */ - if (OK != acxpci_s_reset_dev(priv)) + /* NB: read_reg() reads may return bogus data before reset_dev(), + * since the firmware which directly controls large parts of the I/O + * registers isn't initialized yet. + * acx100 seems to be more affected than acx111 */ + if (OK != acxpci_s_reset_dev(adev)) goto fail_reset; - if (OK != acxpci_read_eeprom_byte(priv, 0x05, &priv->eeprom_version)) + if (OK != acxpci_read_eeprom_byte(adev, 0x05, &adev->eeprom_version)) goto fail_read_eeprom_version; - if (OK != acx_s_init_mac(priv)) + if (IS_ACX100(adev)) { + /* ACX100: configopt struct in cmd mailbox - directly after reset */ + memcpy_fromio(&co, adev->cmd_area, sizeof(co)); + } + + if (OK != acx_s_init_mac(adev)) goto fail_init_mac; - acx_s_set_defaults(priv); - acx_s_get_firmware_version(priv); /* needs to be after acx_s_init_mac() */ - acx_display_hardware_details(priv); + if (IS_ACX111(adev)) { + /* ACX111: configopt struct needs to be queried after full init */ + acx_s_interrogate(adev, &co, ACX111_IE_CONFIG_OPTIONS); + } + +//TODO: merge them into one function, they are called just once and are the same for pci & usb + acx_s_parse_configoption(adev, &co); + acx_s_set_defaults(adev); + acx_s_get_firmware_version(adev); /* needs to be after acx_s_init_mac() */ + acx_display_hardware_details(adev); /* Register the card, AFTER everything else has been set up, * since otherwise an ioctl could step on our feet due to * firmware operations happening in parallel or uninitialized data */ - err = register_netdev(dev); + err = register_netdev(ndev); if (OK != err) { printk("acx: register_netdev() FAILED: %d\n", err); goto fail_register_netdev; } - acx_proc_register_entries(dev); + acx_proc_register_entries(ndev); /* Now we have our device, so make sure the kernel doesn't try * to send packets even though we're not associated to a network yet */ - acx_stop_queue(dev, "on probe"); - acx_carrier_off(dev, "on probe"); + acx_stop_queue(ndev, "on probe"); + acx_carrier_off(ndev, "on probe"); /* after register_netdev() userspace may start working with dev * (in particular, on other CPUs), we only need to up the sem */ - /* acx_sem_unlock(priv); */ + /* acx_sem_unlock(adev); */ printk("acx "ACX_RELEASE": net device %s, driver compiled " "against wireless extensions %d and Linux %s\n", - dev->name, WIRELESS_EXT, UTS_RELEASE); + ndev->name, WIRELESS_EXT, UTS_RELEASE); #if CMD_DISCOVERY - great_inquisitor(priv); + great_inquisitor(adev); #endif result = OK; @@ -1736,15 +1718,15 @@ acxpci_e_probe(struct pci_dev *pdev, con fail_register_netdev: - acxpci_s_delete_dma_regions(priv); + acxpci_s_delete_dma_regions(adev); pci_set_drvdata(pdev, NULL); fail_init_mac: fail_read_eeprom_version: fail_reset: - acxpci_s_device_chain_remove(dev); - free_netdev(dev); + acxpci_s_device_chain_remove(ndev); + free_netdev(ndev); fail_alloc_netdev: fail_irq: @@ -1766,7 +1748,7 @@ fail_unknown_chiptype: pci_disable_device(pdev); fail_pci_enable_device: - pci_set_power_state(pdev, 3); + pci_set_power_state(pdev, PCI_D3hot); done: FN_EXIT1(result); @@ -1788,33 +1770,33 @@ done: static void __devexit acxpci_e_remove(struct pci_dev *pdev) { - struct net_device *dev; - wlandevice_t *priv; + struct net_device *ndev; + acx_device_t *adev; unsigned long mem_region1, mem_region2; FN_ENTER; - dev = (struct net_device *) pci_get_drvdata(pdev); - if (!dev) { + ndev = (struct net_device*) pci_get_drvdata(pdev); + if (!ndev) { log(L_DEBUG, "%s: card is unused. Skipping any release code\n", __func__); goto end; } - priv = netdev_priv(dev); + adev = ndev2adev(ndev); /* unregister the device to not let the kernel * (e.g. ioctls) access a half-deconfigured device * NB: this will cause acxpci_e_close() to be called, * thus we shouldn't call it under sem! */ - log(L_INIT, "removing device %s\n", dev->name); - unregister_netdev(dev); + log(L_INIT, "removing device %s\n", ndev->name); + unregister_netdev(ndev); /* unregister_netdev ensures that no references to us left. * For paranoid reasons we continue to follow the rules */ - acx_sem_lock(priv); + acx_sem_lock(adev); - if (IS_ACX100(priv)) { + if (IS_ACX100(adev)) { mem_region1 = PCI_ACX100_REGION1; mem_region2 = PCI_ACX100_REGION2; } else { @@ -1822,21 +1804,21 @@ acxpci_e_remove(struct pci_dev *pdev) mem_region2 = PCI_ACX111_REGION2; } - acx_proc_unregister_entries(dev); + acx_proc_unregister_entries(ndev); /* find our PCI device in the global acx list and remove it */ - acxpci_s_device_chain_remove(dev); + acxpci_s_device_chain_remove(ndev); - if (priv->dev_state_mask & ACX_STATE_IFACE_UP) - acxpci_s_down(dev); + if (adev->dev_state_mask & ACX_STATE_IFACE_UP) + acxpci_s_down(ndev); - CLEAR_BIT(priv->dev_state_mask, ACX_STATE_IFACE_UP); + CLEAR_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP); - acxpci_s_delete_dma_regions(priv); + acxpci_s_delete_dma_regions(adev); /* finally, clean up PCI bus state */ - if (priv->iobase) iounmap(priv->iobase); - if (priv->iobase2) iounmap(priv->iobase2); + if (adev->iobase) iounmap(adev->iobase); + if (adev->iobase2) iounmap(adev->iobase2); release_mem_region(pci_resource_start(pdev, mem_region1), pci_resource_len(pdev, mem_region1)); @@ -1853,10 +1835,10 @@ acxpci_e_remove(struct pci_dev *pdev) * since otherwise we might get caught off-guard * by a netdev timeout handler execution * expecting to see a working dev...) */ - free_netdev(dev); + free_netdev(ndev); /* put device into ACPI D3 mode (shutdown) */ - pci_set_power_state(pdev, 3); + pci_set_power_state(pdev, PCI_D3hot); end: FN_EXIT0; @@ -1867,7 +1849,6 @@ end: ** TODO: PM code needs to be fixed / debugged / tested. */ #ifdef CONFIG_PM -static int if_was_up = 0; /* FIXME: HACK, do it correctly sometime instead */ static int #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) acxpci_e_suspend(struct pci_dev *pdev, pm_message_t state) @@ -1875,84 +1856,85 @@ acxpci_e_suspend(struct pci_dev *pdev, p acxpci_e_suspend(struct pci_dev *pdev, u32 state) #endif { - struct net_device *dev = pci_get_drvdata(pdev); - wlandevice_t *priv = netdev_priv(dev); + struct net_device *ndev = pci_get_drvdata(pdev); + acx_device_t *adev; FN_ENTER; + printk("acx: suspend handler is experimental!\n"); + printk("sus: dev %p\n", ndev); - acx_sem_lock(priv); + if (!netif_running(ndev)) + goto end; - printk("acx: experimental suspend handler called for %p\n", priv); - if (netif_device_present(dev)) { - if_was_up = 1; - acxpci_s_down(dev); - } - else - if_was_up = 0; + adev = ndev2adev(ndev); + printk("sus: adev %p\n", adev); - netif_device_detach(dev); /* This one cannot sleep */ - acxpci_s_delete_dma_regions(priv); + acx_sem_lock(adev); - acx_sem_unlock(priv); + netif_device_detach(ndev); /* this one cannot sleep */ + acxpci_s_down(ndev); + /* down() does not set it to 0xffff, but here we really want that */ + write_reg16(adev, IO_ACX_IRQ_MASK, 0xffff); + write_reg16(adev, IO_ACX_FEMR, 0x0); + acxpci_s_delete_dma_regions(adev); + pci_save_state(pdev); + pci_set_power_state(pdev, PCI_D3hot); + acx_sem_unlock(adev); +end: FN_EXIT0; return OK; } + static int acxpci_e_resume(struct pci_dev *pdev) { - struct net_device *dev; - wlandevice_t *priv; + struct net_device *ndev = pci_get_drvdata(pdev); + acx_device_t *adev; + + FN_ENTER; - printk(KERN_WARNING "rsm: resume\n"); - dev = pci_get_drvdata(pdev); - printk(KERN_WARNING "rsm: got dev\n"); + printk("acx: resume handler is experimental!\n"); + printk("rsm: got dev %p\n", ndev); - if (!netif_running(dev)) - return 0; + if (!netif_running(ndev)) + goto end; - priv = netdev_priv(dev); + adev = ndev2adev(ndev); + printk("rsm: got adev %p\n", adev); - acx_sem_lock(priv); + acx_sem_lock(adev); - printk(KERN_WARNING "rsm: got priv\n"); - FN_ENTER; - printk("acx: experimental resume handler called for %p!\n", priv); - pci_set_power_state(pdev, 0); - log(L_DEBUG, "rsm: power state set\n"); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) - /* 2.6.9-rc3-mm2 (2.6.9-bk4, too) introduced this shorter version, - then it made its way into 2.6.10 */ + pci_set_power_state(pdev, PCI_D0); + printk("rsm: power state PCI_D0 set\n"); pci_restore_state(pdev); -#else - pci_restore_state(pdev, priv->pci_state); -#endif - log(L_DEBUG, "rsm: PCI state restored\n"); - acxpci_s_reset_dev(priv); - log(L_DEBUG, "rsm: device reset done\n"); + printk("rsm: PCI state restored\n"); - if (OK != acx_s_init_mac(priv)) - goto fail; - log(L_DEBUG, "rsm: init MAC done\n"); + if (OK != acxpci_s_reset_dev(adev)) + goto end_unlock; + printk("rsm: device reset done\n"); + if (OK != acx_s_init_mac(adev)) + goto end_unlock; + printk("rsm: init MAC done\n"); - if (1 == if_was_up) - acxpci_s_up(dev); - log(L_DEBUG, "rsm: acx up\n"); + acxpci_s_up(ndev); + printk("rsm: acx up done\n"); /* now even reload all card parameters as they were before suspend, * and possibly be back in the network again already :-) */ - if (ACX_STATE_IFACE_UP & priv->dev_state_mask) { - priv->set_mask = GETSET_ALL; - acx_s_update_card_settings(priv); - } - log(L_DEBUG, "rsm: settings updated\n"); - netif_device_attach(dev); - log(L_DEBUG, "rsm: device attached\n"); - -fail: /* we need to return OK here anyway, right? */ - acx_sem_unlock(priv); + if (ACX_STATE_IFACE_UP & adev->dev_state_mask) { + adev->set_mask = GETSET_ALL; + acx_s_update_card_settings(adev); + printk("rsm: settings updated\n"); + } + netif_device_attach(ndev); + printk("rsm: device attached\n"); +end_unlock: + acx_sem_unlock(adev); +end: + /* we need to return OK here anyway, right? */ FN_EXIT0; return OK; } @@ -1970,48 +1952,48 @@ fail: /* we need to return OK here anywa */ static void -enable_acx_irq(wlandevice_t *priv) +enable_acx_irq(acx_device_t *adev) { FN_ENTER; - write_reg16(priv, IO_ACX_IRQ_MASK, priv->irq_mask); - write_reg16(priv, IO_ACX_FEMR, 0x8000); - priv->irqs_active = 1; + write_reg16(adev, IO_ACX_IRQ_MASK, adev->irq_mask); + write_reg16(adev, IO_ACX_FEMR, 0x8000); + adev->irqs_active = 1; FN_EXIT0; } static void -acxpci_s_up(netdevice_t *dev) +acxpci_s_up(struct net_device *ndev) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); unsigned long flags; FN_ENTER; - acx_lock(priv, flags); - enable_acx_irq(priv); - acx_unlock(priv, flags); + acx_lock(adev, flags); + enable_acx_irq(adev); + acx_unlock(adev, flags); /* acx fw < 1.9.3.e has a hardware timer, and older drivers ** used to use it. But we don't do that anymore, our OS ** has reliable software timers */ - init_timer(&priv->mgmt_timer); - priv->mgmt_timer.function = acx_i_timer; - priv->mgmt_timer.data = (unsigned long)priv; + init_timer(&adev->mgmt_timer); + adev->mgmt_timer.function = acx_i_timer; + adev->mgmt_timer.data = (unsigned long)adev; /* Need to set ACX_STATE_IFACE_UP first, or else ** timer won't be started by acx_set_status() */ - SET_BIT(priv->dev_state_mask, ACX_STATE_IFACE_UP); - switch (priv->mode) { + SET_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP); + switch (adev->mode) { case ACX_MODE_0_ADHOC: case ACX_MODE_2_STA: /* actual scan cmd will happen in start() */ - acx_set_status(priv, ACX_STATUS_1_SCANNING); break; + acx_set_status(adev, ACX_STATUS_1_SCANNING); break; case ACX_MODE_3_AP: case ACX_MODE_MONITOR: - acx_set_status(priv, ACX_STATUS_4_ASSOCIATED); break; + acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); break; } - acx_s_start(priv); + acx_s_start(adev); FN_EXIT0; } @@ -2027,27 +2009,33 @@ acxpci_s_up(netdevice_t *dev) */ static void -disable_acx_irq(wlandevice_t *priv) +disable_acx_irq(acx_device_t *adev) { FN_ENTER; - write_reg16(priv, IO_ACX_IRQ_MASK, priv->irq_mask_off); - write_reg16(priv, IO_ACX_FEMR, 0x0); - priv->irqs_active = 0; + + /* I guess mask is not 0xffff because acx100 won't signal + ** cmd completion then (needed for ifup). + ** Someone with acx100 please confirm */ + write_reg16(adev, IO_ACX_IRQ_MASK, adev->irq_mask_off); + write_reg16(adev, IO_ACX_FEMR, 0x0); + adev->irqs_active = 0; FN_EXIT0; } static void -acxpci_s_down(netdevice_t *dev) +acxpci_s_down(struct net_device *ndev) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); unsigned long flags; FN_ENTER; /* Disable IRQs first, so that IRQs cannot race with us */ - acx_lock(priv, flags); - disable_acx_irq(priv); - acx_unlock(priv, flags); + /* then wait until interrupts have finished executing on other CPUs */ + acx_lock(adev, flags); + disable_acx_irq(adev); + synchronize_irq(adev->pdev->irq); + acx_unlock(adev, flags); /* we really don't want to have an asynchronous tasklet disturb us ** after something vital for its job has been shut down, so @@ -2064,25 +2052,25 @@ acxpci_s_down(netdevice_t *dev) ** Work around that by temporary sem unlock. ** This will fail miserably if we'll be hit by concurrent ** iwconfig or something in between. TODO! */ - acx_sem_unlock(priv); + acx_sem_unlock(adev); FLUSH_SCHEDULED_WORK(); - acx_sem_lock(priv); + acx_sem_lock(adev); /* This is possible: ** FLUSH_SCHEDULED_WORK -> acx_e_after_interrupt_task -> ** -> set_status(ASSOCIATED) -> wake_queue() ** That's why we stop queue _after_ FLUSH_SCHEDULED_WORK ** lock/unlock is just paranoia, maybe not needed */ - acx_lock(priv, flags); - acx_stop_queue(dev, "on ifdown"); - acx_set_status(priv, ACX_STATUS_0_STOPPED); - acx_unlock(priv, flags); + acx_lock(adev, flags); + acx_stop_queue(ndev, "on ifdown"); + acx_set_status(adev, ACX_STATUS_0_STOPPED); + acx_unlock(adev, flags); /* kernel/timer.c says it's illegal to del_timer_sync() ** a timer which restarts itself. We guarantee this cannot ** ever happen because acx_i_timer() never does this if ** status is ACX_STATUS_0_STOPPED */ - del_timer_sync(&priv->mgmt_timer); + del_timer_sync(&adev->mgmt_timer); FN_EXIT0; } @@ -2100,30 +2088,29 @@ acxpci_s_down(netdevice_t *dev) ** <0 driver reported error */ static int -acxpci_e_open(netdevice_t *dev) +acxpci_e_open(struct net_device *ndev) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); int result = OK; FN_ENTER; - log(L_INIT, "module count++\n"); - WLAN_MOD_INC_USE_COUNT; + acx_sem_lock(adev); - acx_sem_lock(priv); + acx_init_task_scheduler(adev); - acx_init_task_scheduler(priv); +//TODO: pci_set_power_state(pdev, PCI_D0); ? /* request shared IRQ handler */ - if (request_irq(dev->irq, acxpci_i_interrupt, SA_SHIRQ, dev->name, dev)) { - printk("%s: request_irq FAILED\n", dev->name); + if (request_irq(ndev->irq, acxpci_i_interrupt, SA_SHIRQ, ndev->name, ndev)) { + printk("%s: request_irq FAILED\n", ndev->name); result = -EAGAIN; goto done; } - log(L_DEBUG|L_IRQ, "request_irq %d successful\n", dev->irq); + log(L_DEBUG|L_IRQ, "request_irq %d successful\n", ndev->irq); /* ifup device */ - acxpci_s_up(dev); + acxpci_s_up(ndev); /* We don't currently have to do anything else. * The setup of the MAC should be subsequently completed via @@ -2133,7 +2120,7 @@ acxpci_e_open(netdevice_t *dev) * frames because of dev->flags&IFF_UP is true. */ done: - acx_sem_unlock(priv); + acx_sem_unlock(adev); FN_EXIT1(result); return result; @@ -2152,34 +2139,33 @@ done: ** <0 driver reported error */ static int -acxpci_e_close(netdevice_t *dev) +acxpci_e_close(struct net_device *ndev) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); FN_ENTER; - acx_sem_lock(priv); + acx_sem_lock(adev); /* ifdown device */ - CLEAR_BIT(priv->dev_state_mask, ACX_STATE_IFACE_UP); - if (netif_device_present(dev)) { - acxpci_s_down(dev); + CLEAR_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP); + if (netif_device_present(ndev)) { + acxpci_s_down(ndev); } /* disable all IRQs, release shared IRQ handler */ - write_reg16(priv, IO_ACX_IRQ_MASK, 0xffff); - write_reg16(priv, IO_ACX_FEMR, 0x0); - free_irq(dev->irq, dev); + write_reg16(adev, IO_ACX_IRQ_MASK, 0xffff); + write_reg16(adev, IO_ACX_FEMR, 0x0); + free_irq(ndev->irq, ndev); + +//TODO: pci_set_power_state(pdev, PCI_D3hot); ? /* We currently don't have to do anything else. * Higher layers know we're not ready from dev->start==0 and * dev->tbusy==1. Our rx path knows to not pass up received * frames because of dev->flags&IFF_UP is false. */ - log(L_INIT, "module count--\n"); - WLAN_MOD_DEC_USE_COUNT; - - acx_sem_unlock(priv); + acx_sem_unlock(adev); log(L_INIT, "closed device\n"); FN_EXIT0; @@ -2193,18 +2179,18 @@ acxpci_e_close(netdevice_t *dev) ** Called from network core. Must not sleep! */ static void -acxpci_i_tx_timeout(netdevice_t *dev) +acxpci_i_tx_timeout(struct net_device *ndev) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); unsigned long flags; unsigned int tx_num_cleaned; FN_ENTER; - acx_lock(priv, flags); + acx_lock(adev, flags); /* clean processed tx descs, they may have been completely full */ - tx_num_cleaned = acxpci_l_clean_txdesc(priv); + tx_num_cleaned = acxpci_l_clean_txdesc(adev); /* nothing cleaned, yet (almost) no free buffers available? * --> clean all tx descs, no matter which status!! @@ -2214,24 +2200,24 @@ acxpci_i_tx_timeout(netdevice_t *dev) * * TODO: it's best to simply reset & reinit hw from scratch... */ - if ((priv->tx_free <= TX_EMERG_CLEAN) && (tx_num_cleaned == 0)) { + if ((adev->tx_free <= TX_EMERG_CLEAN) && (tx_num_cleaned == 0)) { printk("%s: FAILED to free any of the many full tx buffers. " "Switching to emergency freeing. " - "Please report!\n", dev->name); - acxpci_l_clean_txdesc_emergency(priv); + "Please report!\n", ndev->name); + acxpci_l_clean_txdesc_emergency(adev); } - if (acx_queue_stopped(dev) && (ACX_STATUS_4_ASSOCIATED == priv->status)) - acx_wake_queue(dev, "after tx timeout"); + if (acx_queue_stopped(ndev) && (ACX_STATUS_4_ASSOCIATED == adev->status)) + acx_wake_queue(ndev, "after tx timeout"); /* stall may have happened due to radio drift, so recalib radio */ - acx_schedule_task(priv, ACX_AFTER_IRQ_CMD_RADIO_RECALIB); + acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_RADIO_RECALIB); /* do unimportant work last */ - printk("%s: tx timeout!\n", dev->name); - priv->stats.tx_errors++; + printk("%s: tx timeout!\n", ndev->name); + adev->stats.tx_errors++; - acx_unlock(priv, flags); + acx_unlock(adev, flags); FN_EXIT0; } @@ -2242,34 +2228,34 @@ acxpci_i_tx_timeout(netdevice_t *dev) ** FIXME: most likely needs refinement */ static void -acxpci_i_set_multicast_list(netdevice_t *dev) +acxpci_i_set_multicast_list(struct net_device *ndev) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); unsigned long flags; FN_ENTER; - acx_lock(priv, flags); + acx_lock(adev, flags); /* firmwares don't have allmulti capability, * so just use promiscuous mode instead in this case. */ - if (dev->flags & (IFF_PROMISC|IFF_ALLMULTI)) { - SET_BIT(priv->rx_config_1, RX_CFG1_RCV_PROMISCUOUS); - CLEAR_BIT(priv->rx_config_1, RX_CFG1_FILTER_ALL_MULTI); - SET_BIT(priv->set_mask, SET_RXCONFIG); + if (ndev->flags & (IFF_PROMISC|IFF_ALLMULTI)) { + SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS); + CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI); + SET_BIT(adev->set_mask, SET_RXCONFIG); /* let kernel know in case *we* needed to set promiscuous */ - dev->flags |= (IFF_PROMISC|IFF_ALLMULTI); + ndev->flags |= (IFF_PROMISC|IFF_ALLMULTI); } else { - CLEAR_BIT(priv->rx_config_1, RX_CFG1_RCV_PROMISCUOUS); - SET_BIT(priv->rx_config_1, RX_CFG1_FILTER_ALL_MULTI); - SET_BIT(priv->set_mask, SET_RXCONFIG); - dev->flags &= ~(IFF_PROMISC|IFF_ALLMULTI); + CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS); + SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI); + SET_BIT(adev->set_mask, SET_RXCONFIG); + ndev->flags &= ~(IFF_PROMISC|IFF_ALLMULTI); } /* cannot update card settings directly here, atomic context */ - acx_schedule_task(priv, ACX_AFTER_IRQ_UPDATE_CARD_CFG); + acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG); - acx_unlock(priv, flags); + acx_unlock(adev, flags); FN_EXIT0; } @@ -2282,16 +2268,16 @@ acxpci_i_set_multicast_list(netdevice_t */ #if !ACX_DEBUG -static inline void log_rxbuffer(const wlandevice_t *priv) {} +static inline void log_rxbuffer(const acx_device_t *adev) {} #else static void -log_rxbuffer(const wlandevice_t *priv) +log_rxbuffer(const acx_device_t *adev) { register const struct rxhostdesc *rxhostdesc; int i; /* no FN_ENTER here, we don't want that */ - rxhostdesc = priv->rxhostdesc_start; + rxhostdesc = adev->rxhostdesc_start; if (unlikely(!rxhostdesc)) return; for (i = 0; i < RX_CNT; i++) { if ((rxhostdesc->Ctl_16 & cpu_to_le16(DESC_CTL_HOSTOWN)) @@ -2303,7 +2289,7 @@ log_rxbuffer(const wlandevice_t *priv) #endif static void -acxpci_l_process_rxdesc(wlandevice_t *priv) +acxpci_l_process_rxdesc(acx_device_t *adev) { register rxhostdesc_t *hostdesc; int count, tail; @@ -2311,15 +2297,15 @@ acxpci_l_process_rxdesc(wlandevice_t *pr FN_ENTER; if (unlikely(acx_debug & L_BUFR)) - log_rxbuffer(priv); + log_rxbuffer(adev); /* First, have a loop to determine the first descriptor that's * full, just in case there's a mismatch between our current * rx_tail and the full descriptor we're supposed to handle. */ - tail = priv->rx_tail; + tail = adev->rx_tail; count = RX_CNT; while (1) { - hostdesc = &priv->rxhostdesc_start[tail]; + hostdesc = &adev->rxhostdesc_start[tail]; /* advance tail regardless of outcome of the below test */ tail = (tail + 1) % RX_CNT; @@ -2336,7 +2322,7 @@ acxpci_l_process_rxdesc(wlandevice_t *pr log(L_BUFR, "rx: tail=%u Ctl_16=%04X Status=%08X\n", tail, hostdesc->Ctl_16, hostdesc->Status); - acx_l_process_rxbuf(priv, hostdesc->data); + acx_l_process_rxbuf(adev, hostdesc->data); hostdesc->Status = 0; /* flush all writes before adapter sees CTL_HOSTOWN change */ @@ -2345,7 +2331,7 @@ acxpci_l_process_rxdesc(wlandevice_t *pr CLEAR_BIT(hostdesc->Ctl_16, cpu_to_le16(DESC_CTL_HOSTOWN)); /* ok, descriptor is handled, now check the next descriptor */ - hostdesc = &priv->rxhostdesc_start[tail]; + hostdesc = &adev->rxhostdesc_start[tail]; /* if next descriptor is empty, then bail out */ if (!(hostdesc->Ctl_16 & cpu_to_le16(DESC_CTL_HOSTOWN)) @@ -2355,7 +2341,7 @@ acxpci_l_process_rxdesc(wlandevice_t *pr tail = (tail + 1) % RX_CNT; } end: - priv->rx_tail = tail; + adev->rx_tail = tail; FN_EXIT0; } @@ -2399,7 +2385,7 @@ more bytes may follow */ static void -handle_info_irq(wlandevice_t *priv) +handle_info_irq(acx_device_t *adev) { #if ACX_DEBUG static const char * const info_type_msg[] = { @@ -2424,14 +2410,14 @@ handle_info_irq(wlandevice_t *priv) #endif u32 info_type, info_status; - info_type = readl(priv->info_area); + info_type = readl(adev->info_area); info_status = (info_type >> 16); info_type = (u16)info_type; /* inform fw that we have read this info message */ - writel(info_type | 0x00010000, priv->info_area); - write_reg16(priv, IO_ACX_INT_TRIG, INT_TRIG_INFOACK); - write_flush(priv); + writel(info_type | 0x00010000, adev->info_area); + write_reg16(adev, IO_ACX_INT_TRIG, INT_TRIG_INFOACK); + write_flush(adev); log(L_CTL, "info_type:%04X info_status:%04X\n", info_type, info_status); @@ -2495,19 +2481,19 @@ log_unusual_irq(u16 irqtype) { static void -update_link_quality_led(wlandevice_t *priv) +update_link_quality_led(acx_device_t *adev) { int qual; - qual = acx_signal_determine_quality(priv->wstats.qual.level, priv->wstats.qual.noise); - if (qual > priv->brange_max_quality) - qual = priv->brange_max_quality; - - if (time_after(jiffies, priv->brange_time_last_state_change + - (HZ/2 - HZ/2 * (unsigned long)qual / priv->brange_max_quality ) )) { - acxpci_l_power_led(priv, (priv->brange_last_state == 0)); - priv->brange_last_state ^= 1; /* toggle */ - priv->brange_time_last_state_change = jiffies; + qual = acx_signal_determine_quality(adev->wstats.qual.level, adev->wstats.qual.noise); + if (qual > adev->brange_max_quality) + qual = adev->brange_max_quality; + + if (time_after(jiffies, adev->brange_time_last_state_change + + (HZ/2 - HZ/2 * (unsigned long)qual / adev->brange_max_quality ) )) { + acxpci_l_power_led(adev, (adev->brange_last_state == 0)); + adev->brange_last_state ^= 1; /* toggle */ + adev->brange_time_last_state_change = jiffies; } } @@ -2517,19 +2503,19 @@ update_link_quality_led(wlandevice_t *pr static irqreturn_t acxpci_i_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - wlandevice_t *priv; + acx_device_t *adev; unsigned long flags; unsigned int irqcount = MAX_IRQLOOPS_PER_JIFFY; register u16 irqtype; u16 unmasked; - priv = (wlandevice_t *) (((netdevice_t *) dev_id)->priv); + adev = ndev2adev((struct net_device*)dev_id); /* LOCKING: can just spin_lock() since IRQs are disabled anyway. * I am paranoid */ - acx_lock(priv, flags); + acx_lock(adev, flags); - unmasked = read_reg16(priv, IO_ACX_IRQ_STATUS_CLEAR); + unmasked = read_reg16(adev, IO_ACX_IRQ_STATUS_CLEAR); if (unlikely(0xffff == unmasked)) { /* 0xffff value hints at missing hardware, * so don't do anything. @@ -2539,11 +2525,11 @@ acxpci_i_interrupt(int irq, void *dev_id } /* We will check only "interesting" IRQ types */ - irqtype = unmasked & ~priv->irq_mask; + irqtype = unmasked & ~adev->irq_mask; if (!irqtype) { /* We are on a shared IRQ line and it wasn't our IRQ */ log(L_IRQ, "IRQ type:%04X, mask:%04X - all are masked, IRQ_NONE\n", - unmasked, priv->irq_mask); + unmasked, adev->irq_mask); goto none; } @@ -2553,9 +2539,9 @@ acxpci_i_interrupt(int irq, void *dev_id #define IRQ_ITERATE 1 #if IRQ_ITERATE -if (jiffies != priv->irq_last_jiffies) { - priv->irq_loops_this_jiffy = 0; - priv->irq_last_jiffies = jiffies; +if (jiffies != adev->irq_last_jiffies) { + adev->irq_loops_this_jiffy = 0; + adev->irq_last_jiffies = jiffies; } /* safety condition; we'll normally abort loop below @@ -2563,15 +2549,15 @@ if (jiffies != priv->irq_last_jiffies) { while (likely(--irqcount)) { #endif /* ACK all IRQs ASAP */ - write_reg16(priv, IO_ACX_IRQ_ACK, 0xffff); + write_reg16(adev, IO_ACX_IRQ_ACK, 0xffff); log(L_IRQ, "IRQ type:%04X, mask:%04X, type & ~mask:%04X\n", - unmasked, priv->irq_mask, irqtype); + unmasked, adev->irq_mask, irqtype); /* Handle most important IRQ types first */ if (irqtype & HOST_INT_RX_COMPLETE) { log(L_IRQ, "got Rx_Complete IRQ\n"); - acxpci_l_process_rxdesc(priv); + acxpci_l_process_rxdesc(adev); } if (irqtype & HOST_INT_TX_COMPLETE) { log(L_IRQ, "got Tx_Complete IRQ\n"); @@ -2581,11 +2567,11 @@ while (likely(--irqcount)) { * with a full Tx buffer if we go into * acxpci_l_clean_txdesc() at a time when we won't wakeup * the net queue in there for some reason...) */ - if (priv->tx_free <= TX_START_CLEAN) { + if (adev->tx_free <= TX_START_CLEAN) { #if TX_CLEANUP_IN_SOFTIRQ - acx_schedule_task(priv, ACX_AFTER_IRQ_TX_CLEANUP); + acx_schedule_task(adev, ACX_AFTER_IRQ_TX_CLEANUP); #else - acxpci_l_clean_txdesc(priv); + acxpci_l_clean_txdesc(adev); #endif } } @@ -2599,17 +2585,17 @@ while (likely(--irqcount)) { if (irqtype & HOST_INT_CMD_COMPLETE) { log(L_IRQ, "got Command_Complete IRQ\n"); /* save the state for the running issue_cmd() */ - SET_BIT(priv->irq_status, HOST_INT_CMD_COMPLETE); + SET_BIT(adev->irq_status, HOST_INT_CMD_COMPLETE); } if (irqtype & HOST_INT_INFO) { - handle_info_irq(priv); + handle_info_irq(adev); } if (irqtype & HOST_INT_SCAN_COMPLETE) { log(L_IRQ, "got Scan_Complete IRQ\n"); /* need to do that in process context */ - acx_schedule_task(priv, ACX_AFTER_IRQ_COMPLETE_SCAN); + acx_schedule_task(adev, ACX_AFTER_IRQ_COMPLETE_SCAN); /* remember that fw is not scanning anymore */ - SET_BIT(priv->irq_status, HOST_INT_SCAN_COMPLETE); + SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE); } } @@ -2637,35 +2623,35 @@ while (likely(--irqcount)) { } #if IRQ_ITERATE - unmasked = read_reg16(priv, IO_ACX_IRQ_STATUS_CLEAR); - irqtype = unmasked & ~priv->irq_mask; + unmasked = read_reg16(adev, IO_ACX_IRQ_STATUS_CLEAR); + irqtype = unmasked & ~adev->irq_mask; /* Bail out if no new IRQ bits or if all are masked out */ if (!irqtype) break; - if (unlikely(++priv->irq_loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY)) { + if (unlikely(++adev->irq_loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY)) { printk(KERN_ERR "acx: too many interrupts per jiffy!\n"); /* Looks like card floods us with IRQs! Try to stop that */ - write_reg16(priv, IO_ACX_IRQ_MASK, 0xffff); + write_reg16(adev, IO_ACX_IRQ_MASK, 0xffff); /* This will short-circuit all future attempts to handle IRQ. * We cant do much more... */ - priv->irq_mask = 0; + adev->irq_mask = 0; break; } } #endif /* Routine to perform blink with range */ - if (unlikely(priv->led_power == 2)) - update_link_quality_led(priv); + if (unlikely(adev->led_power == 2)) + update_link_quality_led(adev); /* handled: */ - /* write_flush(priv); - not needed, last op was read anyway */ - acx_unlock(priv, flags); + /* write_flush(adev); - not needed, last op was read anyway */ + acx_unlock(adev, flags); FN_EXIT0; return IRQ_HANDLED; none: - acx_unlock(priv, flags); + acx_unlock(adev, flags); return IRQ_NONE; } @@ -2674,11 +2660,11 @@ none: ** acxpci_l_power_led */ void -acxpci_l_power_led(wlandevice_t *priv, int enable) +acxpci_l_power_led(acx_device_t *adev, int enable) { - u16 gpio_pled = IS_ACX111(priv) ? 0x0040 : 0x0800; + u16 gpio_pled = IS_ACX111(adev) ? 0x0040 : 0x0800; - /* A hack. Not moving message rate limiting to priv->xxx + /* A hack. Not moving message rate limiting to adev->xxx * (it's only a debug message after all) */ static int rate_limit = 0; @@ -2686,11 +2672,11 @@ acxpci_l_power_led(wlandevice_t *priv, i log(L_IOCTL, "Please report in case toggling the power " "LED doesn't work for your card!\n"); if (enable) - write_reg16(priv, IO_ACX_GPIO_OUT, - read_reg16(priv, IO_ACX_GPIO_OUT) & ~gpio_pled); + write_reg16(adev, IO_ACX_GPIO_OUT, + read_reg16(adev, IO_ACX_GPIO_OUT) & ~gpio_pled); else - write_reg16(priv, IO_ACX_GPIO_OUT, - read_reg16(priv, IO_ACX_GPIO_OUT) | gpio_pled); + write_reg16(adev, IO_ACX_GPIO_OUT, + read_reg16(adev, IO_ACX_GPIO_OUT) | gpio_pled); } @@ -2702,13 +2688,13 @@ acxpci_l_power_led(wlandevice_t *priv, i */ int acx111pci_ioctl_info( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { #if ACX_DEBUG > 1 - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); rxdesc_t *rxdesc; txdesc_t *txdesc; rxhostdesc_t *rxhostdesc; @@ -2726,9 +2712,9 @@ acx111pci_ioctl_info( return OK; /* using printk() since we checked debug flag already */ - acx_sem_lock(priv); + acx_sem_lock(adev); - if (!IS_ACX111(priv)) { + if (!IS_ACX111(adev)) { printk("acx111-specific function called " "with non-acx111 chip, aborting\n"); goto end_ok; @@ -2738,31 +2724,31 @@ acx111pci_ioctl_info( memset(&memconf, 0, sizeof(memconf)); /* BTW, fails with 12 (Write only) error code. ** Retained for easy testing of issue_cmd error handling :) */ - acx_s_interrogate(priv, &memconf, ACX1xx_IE_QUEUE_CONFIG); + acx_s_interrogate(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG); /* get Acx111 Queue Configuration */ memset(&queueconf, 0, sizeof(queueconf)); - acx_s_interrogate(priv, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS); + acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS); /* get Acx111 Memory Map */ memset(memmap, 0, sizeof(memmap)); - acx_s_interrogate(priv, &memmap, ACX1xx_IE_MEMORY_MAP); + acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP); /* get Acx111 Rx Config */ memset(rxconfig, 0, sizeof(rxconfig)); - acx_s_interrogate(priv, &rxconfig, ACX1xx_IE_RXCONFIG); + acx_s_interrogate(adev, &rxconfig, ACX1xx_IE_RXCONFIG); /* get Acx111 fcs error count */ memset(fcserror, 0, sizeof(fcserror)); - acx_s_interrogate(priv, &fcserror, ACX1xx_IE_FCS_ERROR_COUNT); + acx_s_interrogate(adev, &fcserror, ACX1xx_IE_FCS_ERROR_COUNT); /* get Acx111 rate fallback */ memset(ratefallback, 0, sizeof(ratefallback)); - acx_s_interrogate(priv, &ratefallback, ACX1xx_IE_RATE_FALLBACK); + acx_s_interrogate(adev, &ratefallback, ACX1xx_IE_RATE_FALLBACK); /* force occurrence of a beacon interrupt */ /* TODO: comment why is this necessary */ - write_reg16(priv, IO_ACX_HINT_TRIG, HOST_INT_BEACON); + write_reg16(adev, IO_ACX_HINT_TRIG, HOST_INT_BEACON); /* dump Acx111 Mem Configuration */ printk("dump mem config:\n" @@ -2834,8 +2820,8 @@ acx111pci_ioctl_info( *((u32 *)&memmap[0x28]), *((u32 *)&memmap[0x2C]), *((u32 *)&memmap[0x30]), - priv->iobase, - priv->iobase2); + adev->iobase, + adev->iobase2); /* dump Acx111 Rx Config */ printk("dump rx config:\n" @@ -2861,10 +2847,10 @@ acx111pci_ioctl_info( *((u8 *)&ratefallback[0x04])); /* protect against IRQ */ - acx_lock(priv, flags); + acx_lock(adev, flags); /* dump acx111 internal rx descriptor ring buffer */ - rxdesc = priv->rxdesc_start; + rxdesc = adev->rxdesc_start; /* loop over complete receive pool */ if (rxdesc) for (i = 0; i < RX_CNT; i++) { @@ -2889,7 +2875,7 @@ acx111pci_ioctl_info( /* dump host rx descriptor ring buffer */ - rxhostdesc = priv->rxhostdesc_start; + rxhostdesc = adev->rxhostdesc_start; /* loop over complete receive pool */ if (rxhostdesc) for (i = 0; i < RX_CNT; i++) { @@ -2913,7 +2899,7 @@ acx111pci_ioctl_info( } /* dump acx111 internal tx descriptor ring buffer */ - txdesc = priv->txdesc_start; + txdesc = adev->txdesc_start; /* loop over complete transmit pool */ if (txdesc) for (i = 0; i < TX_CNT; i++) { @@ -2938,12 +2924,12 @@ acx111pci_ioctl_info( txdesc->Ctl_8, txdesc->Ctl2_8, txdesc->error, txdesc->u.r1.rate); - txdesc = advance_txdesc(priv, txdesc, 1); + txdesc = advance_txdesc(adev, txdesc, 1); } /* dump host tx descriptor ring buffer */ - txhostdesc = priv->txhostdesc_start; + txhostdesc = adev->txhostdesc_start; /* loop over complete host send pool */ if (txhostdesc) for (i = 0; i < TX_CNT * 2; i++) { @@ -2966,12 +2952,12 @@ acx111pci_ioctl_info( txhostdesc++; } - /* write_reg16(priv, 0xb4, 0x4); */ + /* write_reg16(adev, 0xb4, 0x4); */ - acx_unlock(priv, flags); + acx_unlock(adev, flags); end_ok: - acx_sem_unlock(priv); + acx_sem_unlock(adev); #endif /* ACX_DEBUG */ return OK; } @@ -2981,16 +2967,16 @@ end_ok: */ int acx100pci_ioctl_set_phy_amp_bias( - struct net_device *dev, + struct net_device *ndev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); unsigned long flags; u16 gpio_old; - if (!IS_ACX100(priv)) { + if (!IS_ACX100(adev)) { /* WARNING!!! * Removing this check *might* damage * hardware, since we're tweaking GPIOs here after all!!! @@ -3006,21 +2992,21 @@ acx100pci_ioctl_set_phy_amp_bias( return -EINVAL; } - acx_sem_lock(priv); + acx_sem_lock(adev); /* Need to lock accesses to [IO_ACX_GPIO_OUT]: * IRQ handler uses it to update LED */ - acx_lock(priv, flags); - gpio_old = read_reg16(priv, IO_ACX_GPIO_OUT); - write_reg16(priv, IO_ACX_GPIO_OUT, (gpio_old & 0xf8ff) | ((u16)*extra << 8)); - acx_unlock(priv, flags); + acx_lock(adev, flags); + gpio_old = read_reg16(adev, IO_ACX_GPIO_OUT); + write_reg16(adev, IO_ACX_GPIO_OUT, (gpio_old & 0xf8ff) | ((u16)*extra << 8)); + acx_unlock(adev, flags); log(L_DEBUG, "gpio_old: 0x%04X\n", gpio_old); printk("%s: PHY power amplifier bias: old:%d, new:%d\n", - dev->name, + ndev->name, (gpio_old & 0x0700) >> 8, (unsigned char)*extra); - acx_sem_unlock(priv); + acx_sem_unlock(adev); return OK; } @@ -3029,9 +3015,13 @@ acx100pci_ioctl_set_phy_amp_bias( /*************************************************************** ** acxpci_l_alloc_tx ** Actually returns a txdesc_t* ptr +** +** FIXME: in case of fragments, should allocate multiple descrs +** after figuring out how many we need and whether we still have +** sufficiently many. */ tx_t* -acxpci_l_alloc_tx(wlandevice_t* priv) +acxpci_l_alloc_tx(acx_device_t *adev) { struct txdesc *txdesc; int head; @@ -3039,14 +3029,14 @@ acxpci_l_alloc_tx(wlandevice_t* priv) FN_ENTER; - if (unlikely(!priv->tx_free)) { + if (unlikely(!adev->tx_free)) { printk("acx: BUG: no free txdesc left\n"); txdesc = NULL; goto end; } - head = priv->tx_head; - txdesc = get_txdesc(priv, head); + head = adev->tx_head; + txdesc = get_txdesc(adev, head); ctl8 = txdesc->Ctl_8; /* 2005-10-11: there were several bug reports on this happening @@ -3063,19 +3053,19 @@ acxpci_l_alloc_tx(wlandevice_t* priv) /* Needed in case txdesc won't be eventually submitted for tx */ txdesc->Ctl_8 = DESC_CTL_ACXDONE_HOSTOWN; - priv->tx_free--; + adev->tx_free--; log(L_BUFT, "tx: got desc %u, %u remain\n", - head, priv->tx_free); + head, adev->tx_free); /* Keep a few free descs between head and tail of tx ring. ** It is not absolutely needed, just feels safer */ - if (priv->tx_free < TX_STOP_QUEUE) { + if (adev->tx_free < TX_STOP_QUEUE) { log(L_BUF, "stop queue (%u tx desc left)\n", - priv->tx_free); - acx_stop_queue(priv->netdev, NULL); + adev->tx_free); + acx_stop_queue(adev->ndev, NULL); } /* returning current descriptor, so advance to next free one */ - priv->tx_head = (head + 1) % TX_CNT; + adev->tx_head = (head + 1) % TX_CNT; end: FN_EXIT0; @@ -3086,9 +3076,9 @@ end: /*********************************************************************** */ void* -acxpci_l_get_txbuf(wlandevice_t *priv, tx_t* tx_opaque) +acxpci_l_get_txbuf(acx_device_t *adev, tx_t* tx_opaque) { - return get_txhostdesc(priv, (txdesc_t*)tx_opaque)->data; + return get_txhostdesc(adev, (txdesc_t*)tx_opaque)->data; } @@ -3097,9 +3087,13 @@ acxpci_l_get_txbuf(wlandevice_t *priv, t ** ** Can be called from IRQ (rx -> (AP bridging or mgmt response) -> tx). ** Can be called from acx_i_start_xmit (data frames from net core). +** +** FIXME: in case of fragments, should loop over the number of +** pre-allocated tx descrs, properly setting up transfer data and +** CTL_xxx flags according to fragment number. */ void -acxpci_l_tx_data(wlandevice_t *priv, tx_t* tx_opaque, int len) +acxpci_l_tx_data(acx_device_t *adev, tx_t* tx_opaque, int len) { txdesc_t *txdesc = (txdesc_t*)tx_opaque; txhostdesc_t *hostdesc1, *hostdesc2; @@ -3110,38 +3104,37 @@ acxpci_l_tx_data(wlandevice_t *priv, tx_ FN_ENTER; /* fw doesn't tx such packets anyhow */ - if (len < WLAN_HDR_A3_LEN) + if (unlikely(len < WLAN_HDR_A3_LEN)) goto end; - hostdesc1 = get_txhostdesc(priv, txdesc); + hostdesc1 = get_txhostdesc(adev, txdesc); /* modify flag status in separate variable to be able to write it back * in one big swoop later (also in order to have less device memory * accesses) */ Ctl_8 = txdesc->Ctl_8; - Ctl2_8 = txdesc->Ctl2_8; + Ctl2_8 = 0; /* really need to init it to 0, not txdesc->Ctl2_8, it seems */ hostdesc2 = hostdesc1 + 1; /* DON'T simply set Ctl field to 0 here globally, * it needs to maintain a consistent flag status (those are state flags!!), * otherwise it may lead to severe disruption. Only set or reset particular - * flags at the exact moment this is needed... - * FIXME: what about Ctl2? Equally problematic? */ + * flags at the exact moment this is needed... */ /* let chip do RTS/CTS handshaking before sending * in case packet size exceeds threshold */ - if (len > priv->rts_threshold) + if (len > adev->rts_threshold) SET_BIT(Ctl2_8, DESC_CTL2_RTS); else CLEAR_BIT(Ctl2_8, DESC_CTL2_RTS); - switch (priv->mode) { + switch (adev->mode) { case ACX_MODE_0_ADHOC: case ACX_MODE_3_AP: - clt = acx_l_sta_list_get(priv, ((wlan_hdr_t*)hostdesc1->data)->a1); + clt = acx_l_sta_list_get(adev, ((wlan_hdr_t*)hostdesc1->data)->a1); break; case ACX_MODE_2_STA: - clt = priv->ap_client; + clt = adev->ap_client; break; #if 0 /* testing was done on acx111: */ @@ -3169,18 +3162,18 @@ acxpci_l_tx_data(wlandevice_t *priv, tx_ break; } - rate_cur = clt ? clt->rate_cur : priv->rate_bcast; + rate_cur = clt ? clt->rate_cur : adev->rate_bcast; if (unlikely(!rate_cur)) { printk("acx: driver bug! bad ratemask\n"); goto end; } /* used in tx cleanup routine for auto rate and accounting: */ - put_txcr(priv, txdesc, clt, rate_cur); + put_txcr(adev, txdesc, clt, rate_cur); txdesc->total_length = cpu_to_le16(len); hostdesc2->length = cpu_to_le16(len - WLAN_HDR_A3_LEN); - if (IS_ACX111(priv)) { + if (IS_ACX111(adev)) { /* note that if !txdesc->do_auto, txrate->cur ** has only one nonzero bit */ txdesc->u.r2.rate111 = cpu_to_le16( @@ -3198,7 +3191,7 @@ acxpci_l_tx_data(wlandevice_t *priv, tx_ #endif hostdesc1->length = cpu_to_le16(len); } else { /* ACX100 */ - u8 rate_100 = clt ? clt->rate_100 : priv->rate_bcast100; + u8 rate_100 = clt ? clt->rate_100 : adev->rate_bcast100; txdesc->u.r1.rate = rate_100; #ifdef TODO_FIGURE_OUT_WHEN_TO_SET_THIS if (clt->pbcc511) { @@ -3211,6 +3204,9 @@ acxpci_l_tx_data(wlandevice_t *priv, tx_ #endif /* set autodma and reclaim and 1st mpdu */ SET_BIT(Ctl_8, DESC_CTL_AUTODMA | DESC_CTL_RECLAIM | DESC_CTL_FIRSTFRAG); +#if ACX_FRAGMENTATION + /* SET_BIT(Ctl2_8, DESC_CTL2_MORE_FRAG); cannot set it unconditionally, needs to be set for all non-last fragments */ +#endif hostdesc1->length = cpu_to_le16(WLAN_HDR_A3_LEN); } /* don't need to clean ack/rts statistics here, already @@ -3231,27 +3227,27 @@ acxpci_l_tx_data(wlandevice_t *priv, tx_ /* flush writes before we tell the adapter that it's its turn now */ mmiowb(); - write_reg16(priv, IO_ACX_INT_TRIG, INT_TRIG_TXPRC); - write_flush(priv); + write_reg16(adev, IO_ACX_INT_TRIG, INT_TRIG_TXPRC); + write_flush(adev); /* log the packet content AFTER sending it, * in order to not delay sending any further than absolutely needed * Do separate logs for acx100/111 to have human-readable rates */ if (unlikely(acx_debug & (L_XFER|L_DATA))) { u16 fc = ((wlan_hdr_t*)hostdesc1->data)->fc; - if (IS_ACX111(priv)) + if (IS_ACX111(adev)) printk("tx: pkt (%s): len %d " "rate %04X%s status %u\n", acx_get_packet_type_string(le16_to_cpu(fc)), len, le16_to_cpu(txdesc->u.r2.rate111), (le16_to_cpu(txdesc->u.r2.rate111) & RATE111_SHORTPRE) ? "(SPr)" : "", - priv->status); + adev->status); else printk("tx: pkt (%s): len %d rate %03u%s status %u\n", acx_get_packet_type_string(fc), len, txdesc->u.r1.rate, (Ctl_8 & DESC_CTL_SHORT_PREAMBLE) ? "(SPr)" : "", - priv->status); + adev->status); if (acx_debug & L_DATA) { printk("tx: 802.11 [%d]: ", len); @@ -3275,22 +3271,22 @@ end: */ #if !ACX_DEBUG -static inline void log_txbuffer(const wlandevice_t *priv) {} +static inline void log_txbuffer(const acx_device_t *adev) {} #else static void -log_txbuffer(wlandevice_t *priv) +log_txbuffer(acx_device_t *adev) { txdesc_t *txdesc; int i; /* no FN_ENTER here, we don't want that */ /* no locks here, since it's entirely non-critical code */ - txdesc = priv->txdesc_start; + txdesc = adev->txdesc_start; if (unlikely(!txdesc)) return; printk("tx: desc->Ctl8's:"); for (i = 0; i < TX_CNT; i++) { printk(" %02X", txdesc->Ctl_8); - txdesc = advance_txdesc(priv, txdesc, 1); + txdesc = advance_txdesc(adev, txdesc, 1); } printk("\n"); } @@ -3298,7 +3294,7 @@ log_txbuffer(wlandevice_t *priv) static void -handle_tx_error(wlandevice_t *priv, u8 error, unsigned int finger) +handle_tx_error(acx_device_t *adev, u8 error, unsigned int finger) { const char *err = "unknown error"; @@ -3309,90 +3305,84 @@ handle_tx_error(wlandevice_t *priv, u8 e switch (error) { case 0x01: err = "no Tx due to error in other fragment"; - priv->wstats.discard.fragment++; + adev->wstats.discard.fragment++; break; case 0x02: err = "Tx aborted"; - priv->stats.tx_aborted_errors++; + adev->stats.tx_aborted_errors++; break; case 0x04: err = "Tx desc wrong parameters"; - priv->wstats.discard.misc++; + adev->wstats.discard.misc++; break; case 0x08: err = "WEP key not found"; - priv->wstats.discard.misc++; + adev->wstats.discard.misc++; break; case 0x10: err = "MSDU lifetime timeout? - try changing " "'iwconfig retry lifetime XXX'"; - priv->wstats.discard.misc++; + adev->wstats.discard.misc++; break; case 0x20: err = "excessive Tx retries due to either distance " "too high or unable to Tx or Tx frame error - " "try changing 'iwconfig txpower XXX' or " "'sens'itivity or 'retry'"; - priv->wstats.discard.retries++; - /* FIXME: set (GETSET_TX|GETSET_RX) here - * (this seems to recalib radio on ACX100) - * after some more jiffies passed?? - * But OTOH Tx error 0x20 also seems to occur on + adev->wstats.discard.retries++; + /* Tx error 0x20 also seems to occur on * overheating, so I'm not sure whether we - * actually want that, since people maybe won't notice - * then that their hardware is slowly getting - * cooked... + * actually want to do aggressive radio recalibration, + * since people maybe won't notice then that their hardware + * is slowly getting cooked... * Or is it still a safe long distance from utter - * radio non-functionality despite many radio - * recalibs + * radio non-functionality despite many radio recalibs * to final destructive overheating of the hardware? * In this case we really should do recalib here... * I guess the only way to find out is to do a * potentially fatal self-experiment :-\ * Or maybe only recalib in case we're using Tx * rate auto (on errors switching to lower speed - * --> less heat?) or 802.11 power save mode? */ - - /* ok, just do it. - * ENABLE_TX|ENABLE_RX helps, so even do - * DISABLE_TX and DISABLE_RX in order to perhaps - * have more impact. */ - if (++priv->retry_errors_msg_ratelimit % 4 == 0) { - if (priv->retry_errors_msg_ratelimit <= 20) + * --> less heat?) or 802.11 power save mode? + * + * ok, just do it. */ + if (++adev->retry_errors_msg_ratelimit % 4 == 0) { + if (adev->retry_errors_msg_ratelimit <= 20) { printk("%s: several excessive Tx " "retry errors occurred, attempting " "to recalibrate radio. Radio " "drift might be caused by increasing " "card temperature, please check the card " "before it's too late!\n", - priv->netdev->name); - if (priv->retry_errors_msg_ratelimit == 20) - printk("disabling above message\n"); + adev->ndev->name); + if (adev->retry_errors_msg_ratelimit == 20) + printk("disabling above message\n"); + } - acx_schedule_task(priv, ACX_AFTER_IRQ_CMD_RADIO_RECALIB); + acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_RADIO_RECALIB); } break; case 0x40: err = "Tx buffer overflow"; - priv->stats.tx_fifo_errors++; + adev->stats.tx_fifo_errors++; break; case 0x80: err = "DMA error"; - priv->wstats.discard.misc++; + adev->wstats.discard.misc++; break; } - priv->stats.tx_errors++; - if (priv->stats.tx_errors <= 20) + adev->stats.tx_errors++; + if (adev->stats.tx_errors <= 20) printk("%s: tx error 0x%02X, buf %02u! (%s)\n", - priv->netdev->name, error, finger, err); + adev->ndev->name, error, finger, err); else printk("%s: tx error 0x%02X, buf %02u!\n", - priv->netdev->name, error, finger); + adev->ndev->name, error, finger); } unsigned int -acxpci_l_clean_txdesc(wlandevice_t *priv) +acxpci_l_clean_txdesc(acx_device_t *adev) { txdesc_t *txdesc; int finger; @@ -3403,9 +3393,9 @@ acxpci_l_clean_txdesc(wlandevice_t *priv FN_ENTER; if (unlikely(acx_debug & L_DEBUG)) - log_txbuffer(priv); + log_txbuffer(adev); - log(L_BUFT, "tx: cleaning up bufs from %u\n", priv->tx_tail); + log(L_BUFT, "tx: cleaning up bufs from %u\n", adev->tx_tail); /* We know first descr which is not free yet. We advance it as far ** as we see correct bits set in following descs (if next desc @@ -3413,10 +3403,10 @@ acxpci_l_clean_txdesc(wlandevice_t *priv ** front of tx_tail may be "holes" with isolated free descs. ** We will catch up when all intermediate descs will be freed also */ - finger = priv->tx_tail; + finger = adev->tx_tail; num_cleaned = 0; - while (likely(finger != priv->tx_head)) { - txdesc = get_txdesc(priv, finger); + while (likely(finger != adev->tx_head)) { + txdesc = get_txdesc(adev, finger); /* If we allocated txdesc on tx path but then decided ** to NOT use it, then it will be left as a free "bubble" @@ -3429,7 +3419,7 @@ acxpci_l_clean_txdesc(wlandevice_t *priv if (unlikely(!num_cleaned)) { /* maybe remove completely */ log(L_BUFT, "clean_txdesc: tail isn't free. " "tail:%d head:%d\n", - priv->tx_tail, priv->tx_head); + adev->tx_tail, adev->tx_head); } break; } @@ -3440,9 +3430,8 @@ acxpci_l_clean_txdesc(wlandevice_t *priv rts_failures = txdesc->rts_failures; rts_ok = txdesc->rts_ok; r100 = txdesc->u.r1.rate; - r111 = txdesc->u.r2.rate111; + r111 = le16_to_cpu(txdesc->u.r2.rate111); -#if WIRELESS_EXT > 13 /* wireless_send_event() and IWEVTXDROP are WE13 */ /* need to check for certain error conditions before we * clean the descriptor: we still need valid descr data here */ if (unlikely(0x30 & error)) { @@ -3452,12 +3441,12 @@ acxpci_l_clean_txdesc(wlandevice_t *priv wlan_hdr_t *hdr; txhostdesc_t *hostdesc; - hostdesc = get_txhostdesc(priv, txdesc); + hostdesc = get_txhostdesc(adev, txdesc); hdr = (wlan_hdr_t *)hostdesc->data; MAC_COPY(wrqu.addr.sa_data, hdr->a1); - wireless_send_event(priv->netdev, IWEVTXDROP, &wrqu, NULL); + wireless_send_event(adev->ndev, IWEVTXDROP, &wrqu, NULL); } -#endif + /* ...and free the desc */ txdesc->error = 0; txdesc->ack_failures = 0; @@ -3467,40 +3456,40 @@ acxpci_l_clean_txdesc(wlandevice_t *priv ** descriptor is finished since it set Ctl_8 accordingly. */ txdesc->Ctl_8 = DESC_CTL_HOSTOWN; - priv->tx_free++; + adev->tx_free++; num_cleaned++; - if ((priv->tx_free >= TX_START_QUEUE) - && (priv->status == ACX_STATUS_4_ASSOCIATED) - && (acx_queue_stopped(priv->netdev)) + if ((adev->tx_free >= TX_START_QUEUE) + && (adev->status == ACX_STATUS_4_ASSOCIATED) + && (acx_queue_stopped(adev->ndev)) ) { log(L_BUF, "tx: wake queue (avail. Tx desc %u)\n", - priv->tx_free); - acx_wake_queue(priv->netdev, NULL); + adev->tx_free); + acx_wake_queue(adev->ndev, NULL); } /* do error checking, rate handling and logging * AFTER having done the work, it's faster */ /* do rate handling */ - if (priv->rate_auto) { - struct client *clt = get_txc(priv, txdesc); + if (adev->rate_auto) { + struct client *clt = get_txc(adev, txdesc); if (clt) { - u16 cur = get_txr(priv, txdesc); + u16 cur = get_txr(adev, txdesc); if (clt->rate_cur == cur) { - acx_l_handle_txrate_auto(priv, clt, + acx_l_handle_txrate_auto(adev, clt, cur, /* intended rate */ r100, r111, /* actually used rate */ (error & 0x30), /* was there an error? */ - TX_CNT + TX_CLEAN_BACKLOG - priv->tx_free); + TX_CNT + TX_CLEAN_BACKLOG - adev->tx_free); } } } if (unlikely(error)) - handle_tx_error(priv, error, finger); + handle_tx_error(adev, error, finger); - if (IS_ACX111(priv)) + if (IS_ACX111(adev)) log(L_BUFT, "tx: cleaned %u: !ACK=%u !RTS=%u RTS=%u r111=%04X\n", finger, ack_failures, rts_failures, rts_ok, r111); else @@ -3512,7 +3501,7 @@ acxpci_l_clean_txdesc(wlandevice_t *priv } /* remember last position */ - priv->tx_tail = finger; + adev->tx_tail = finger; /* end: */ FN_EXIT1(num_cleaned); return num_cleaned; @@ -3521,7 +3510,7 @@ acxpci_l_clean_txdesc(wlandevice_t *priv /* clean *all* Tx descriptors, and regardless of their previous state. * Used for brute-force reset handling. */ void -acxpci_l_clean_txdesc_emergency(wlandevice_t *priv) +acxpci_l_clean_txdesc_emergency(acx_device_t *adev) { txdesc_t *txdesc; int i; @@ -3529,7 +3518,7 @@ acxpci_l_clean_txdesc_emergency(wlandevi FN_ENTER; for (i = 0; i < TX_CNT; i++) { - txdesc = get_txdesc(priv, i); + txdesc = get_txdesc(adev, i); /* free it */ txdesc->ack_failures = 0; @@ -3539,7 +3528,7 @@ acxpci_l_clean_txdesc_emergency(wlandevi txdesc->Ctl_8 = DESC_CTL_HOSTOWN; } - priv->tx_free = TX_CNT; + adev->tx_free = TX_CNT; FN_EXIT0; } @@ -3550,18 +3539,12 @@ acxpci_l_clean_txdesc_emergency(wlandevi */ static void* -allocate(wlandevice_t *priv, size_t size, dma_addr_t *phy, const char *msg) +allocate(acx_device_t *adev, size_t size, dma_addr_t *phy, const char *msg) { void *ptr; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 53) - ptr = dma_alloc_coherent(priv->pdev ? &priv->pdev->dev : NULL, + ptr = dma_alloc_coherent(adev->pdev ? &adev->pdev->dev : NULL, size, phy, GFP_KERNEL); -#else -#warning Using old PCI-specific DMA allocation, may fail with out-of-mem! -#warning Upgrade kernel if it does... - ptr = pci_alloc_consistent(priv->pdev, size, phy); -#endif if (ptr) { log(L_DEBUG, "%s sz=%d adr=0x%p phy=0x%08llx\n", @@ -3576,7 +3559,7 @@ allocate(wlandevice_t *priv, size_t size static int -acxpci_s_create_tx_host_desc_queue(wlandevice_t *priv) +acxpci_s_create_tx_host_desc_queue(acx_device_t *adev) { txhostdesc_t *hostdesc; u8 *txbuf; @@ -3587,52 +3570,48 @@ acxpci_s_create_tx_host_desc_queue(wland FN_ENTER; /* allocate TX buffer */ - priv->txbuf_area_size = TX_CNT * WLAN_A4FR_MAXLEN_WEP_FCS; - priv->txbuf_start = allocate(priv, priv->txbuf_area_size, - &priv->txbuf_startphy, "txbuf_start"); - if (!priv->txbuf_start) + adev->txbuf_area_size = TX_CNT * WLAN_A4FR_MAXLEN_WEP_FCS; + adev->txbuf_start = allocate(adev, adev->txbuf_area_size, + &adev->txbuf_startphy, "txbuf_start"); + if (!adev->txbuf_start) goto fail; /* allocate the TX host descriptor queue pool */ - priv->txhostdesc_area_size = TX_CNT * 2*sizeof(txhostdesc_t); - priv->txhostdesc_start = allocate(priv, priv->txhostdesc_area_size, - &priv->txhostdesc_startphy, "txhostdesc_start"); - if (!priv->txhostdesc_start) + adev->txhostdesc_area_size = TX_CNT * 2*sizeof(*hostdesc); + adev->txhostdesc_start = allocate(adev, adev->txhostdesc_area_size, + &adev->txhostdesc_startphy, "txhostdesc_start"); + if (!adev->txhostdesc_start) goto fail; /* check for proper alignment of TX host descriptor pool */ - if ((long) priv->txhostdesc_start & 3) { + if ((long) adev->txhostdesc_start & 3) { printk("acx: driver bug: dma alloc returns unaligned address\n"); goto fail; } -/* Each tx frame buffer is accessed by hardware via -** txdesc -> txhostdesc(s) -> framebuffer(s) + hostdesc = adev->txhostdesc_start; + hostdesc_phy = adev->txhostdesc_startphy; + txbuf = adev->txbuf_start; + txbuf_phy = adev->txbuf_startphy; + +#if 0 +/* Each tx buffer is accessed by hardware via +** txdesc -> txhostdesc(s) -> txbuffer(s). ** We use only one txhostdesc per txdesc, but it looks like ** acx111 is buggy: it accesses second txhostdesc ** (via hostdesc.desc_phy_next field) even if ** txdesc->length == hostdesc->length and thus ** entire packet was placed into first txhostdesc. ** Due to this bug acx111 hangs unless second txhostdesc -** has hostdesc.length = 3 (or larger) +** has le16_to_cpu(hostdesc.length) = 3 (or larger) ** Storing NULL into hostdesc.desc_phy_next ** doesn't seem to help. ** -** It is not known whether we need to have 'extra' second -** txhostdescs for acx100. Maybe it is acx111-only bug. -** -** Update: acx111 WG311v2 is even more bogus than this. -** We will initialize two hostdesc so that they point -** to adjacent memory areas. -*/ - hostdesc = priv->txhostdesc_start; - hostdesc_phy = priv->txhostdesc_startphy; - txbuf = priv->txbuf_start; - txbuf_phy = priv->txbuf_startphy; - -#if 0 -/* Works for xterasys xn2522g, does not for WG311v2 !!? */ +** Update: although it worked on Xterasys XN-2522g +** with len=3 trick, WG311v2 is even more bogus, doesn't work. +** Keeping this code (#ifdef'ed out) for documentational purposes. +*/ for (i = 0; i < TX_CNT*2; i++) { - hostdesc_phy += sizeof(txhostdesc_t); + hostdesc_phy += sizeof(*hostdesc); if (!(i & 1)) { hostdesc->data_phy = cpu2acx(txbuf_phy); /* hostdesc->data_offset = ... */ @@ -3652,7 +3631,7 @@ acxpci_s_create_tx_host_desc_queue(wland /* hostdesc->data_offset = ... */ /* hostdesc->reserved = ... */ /* hostdesc->Ctl_16 = ... */ - hostdesc->length = 3; /* bug workaround */ + hostdesc->length = cpu_to_le16(3); /* bug workaround */ /* hostdesc->desc_phy_next = ... */ /* hostdesc->pNext = ... */ /* hostdesc->Status = ... */ @@ -3662,8 +3641,10 @@ acxpci_s_create_tx_host_desc_queue(wland hostdesc++; } #endif +/* We initialize two hostdescs so that they point to adjacent +** memory areas. Thus txbuf is really just a contiguous memory area */ for (i = 0; i < TX_CNT*2; i++) { - hostdesc_phy += sizeof(txhostdesc_t); + hostdesc_phy += sizeof(*hostdesc); hostdesc->data_phy = cpu2acx(txbuf_phy); /* done by memset(0): hostdesc->data_offset = 0; */ @@ -3686,7 +3667,7 @@ acxpci_s_create_tx_host_desc_queue(wland hostdesc++; } hostdesc--; - hostdesc->desc_phy_next = cpu2acx(priv->txhostdesc_startphy); + hostdesc->desc_phy_next = cpu2acx(adev->txhostdesc_startphy); FN_EXIT1(OK); return OK; @@ -3706,7 +3687,7 @@ fail: #define RX_BUFFER_SIZE (sizeof(rxbuffer_t) + 32) static int -acxpci_s_create_rx_host_desc_queue(wlandevice_t *priv) +acxpci_s_create_rx_host_desc_queue(acx_device_t *adev) { rxhostdesc_t *hostdesc; rxbuffer_t *rxbuf; @@ -3717,29 +3698,29 @@ acxpci_s_create_rx_host_desc_queue(wland FN_ENTER; /* allocate the RX host descriptor queue pool */ - priv->rxhostdesc_area_size = RX_CNT * sizeof(rxhostdesc_t); - priv->rxhostdesc_start = allocate(priv, priv->rxhostdesc_area_size, - &priv->rxhostdesc_startphy, "rxhostdesc_start"); - if (!priv->rxhostdesc_start) + adev->rxhostdesc_area_size = RX_CNT * sizeof(*hostdesc); + adev->rxhostdesc_start = allocate(adev, adev->rxhostdesc_area_size, + &adev->rxhostdesc_startphy, "rxhostdesc_start"); + if (!adev->rxhostdesc_start) goto fail; /* check for proper alignment of RX host descriptor pool */ - if ((long) priv->rxhostdesc_start & 3) { + if ((long) adev->rxhostdesc_start & 3) { printk("acx: driver bug: dma alloc returns unaligned address\n"); goto fail; } /* allocate Rx buffer pool which will be used by the acx * to store the whole content of the received frames in it */ - priv->rxbuf_area_size = RX_CNT * RX_BUFFER_SIZE; - priv->rxbuf_start = allocate(priv, priv->rxbuf_area_size, - &priv->rxbuf_startphy, "rxbuf_start"); - if (!priv->rxbuf_start) + adev->rxbuf_area_size = RX_CNT * RX_BUFFER_SIZE; + adev->rxbuf_start = allocate(adev, adev->rxbuf_area_size, + &adev->rxbuf_startphy, "rxbuf_start"); + if (!adev->rxbuf_start) goto fail; - rxbuf = priv->rxbuf_start; - rxbuf_phy = priv->rxbuf_startphy; - hostdesc = priv->rxhostdesc_start; - hostdesc_phy = priv->rxhostdesc_startphy; + rxbuf = adev->rxbuf_start; + rxbuf_phy = adev->rxbuf_startphy; + hostdesc = adev->rxhostdesc_start; + hostdesc_phy = adev->rxhostdesc_startphy; /* don't make any popular C programming pointer arithmetic mistakes * here, otherwise I'll kill you... @@ -3750,13 +3731,13 @@ acxpci_s_create_rx_host_desc_queue(wland hostdesc->length = cpu_to_le16(RX_BUFFER_SIZE); CLEAR_BIT(hostdesc->Ctl_16, cpu_to_le16(DESC_CTL_HOSTOWN)); rxbuf++; - rxbuf_phy += sizeof(rxbuffer_t); - hostdesc_phy += sizeof(rxhostdesc_t); + rxbuf_phy += sizeof(*rxbuf); + hostdesc_phy += sizeof(*hostdesc); hostdesc->desc_phy_next = cpu2acx(hostdesc_phy); hostdesc++; } hostdesc--; - hostdesc->desc_phy_next = cpu2acx(priv->rxhostdesc_startphy); + hostdesc->desc_phy_next = cpu2acx(adev->rxhostdesc_startphy); FN_EXIT1(OK); return OK; fail: @@ -3771,12 +3752,12 @@ fail: ** acxpci_s_create_hostdesc_queues */ int -acxpci_s_create_hostdesc_queues(wlandevice_t *priv) +acxpci_s_create_hostdesc_queues(acx_device_t *adev) { int result; - result = acxpci_s_create_tx_host_desc_queue(priv); + result = acxpci_s_create_tx_host_desc_queue(adev); if (OK != result) return result; - result = acxpci_s_create_rx_host_desc_queue(priv); + result = acxpci_s_create_rx_host_desc_queue(adev); return result; } @@ -3785,7 +3766,7 @@ acxpci_s_create_hostdesc_queues(wlandevi ** acxpci_create_tx_desc_queue */ static void -acxpci_create_tx_desc_queue(wlandevice_t *priv, u32 tx_queue_start) +acxpci_create_tx_desc_queue(acx_device_t *adev, u32 tx_queue_start) { txdesc_t *txdesc; txhostdesc_t *hostdesc; @@ -3795,31 +3776,30 @@ acxpci_create_tx_desc_queue(wlandevice_t FN_ENTER; - priv->txdesc_size = sizeof(txdesc_t); - - if (IS_ACX111(priv)) { + if (IS_ACX100(adev)) + adev->txdesc_size = sizeof(*txdesc); + else /* the acx111 txdesc is 4 bytes larger */ - priv->txdesc_size = sizeof(txdesc_t) + 4; - } + adev->txdesc_size = sizeof(*txdesc) + 4; - priv->txdesc_start = (txdesc_t *) (priv->iobase2 + tx_queue_start); + adev->txdesc_start = (txdesc_t *) (adev->iobase2 + tx_queue_start); - log(L_DEBUG, "priv->iobase2=%p\n" + log(L_DEBUG, "adev->iobase2=%p\n" "tx_queue_start=%08X\n" - "priv->txdesc_start=%p\n", - priv->iobase2, + "adev->txdesc_start=%p\n", + adev->iobase2, tx_queue_start, - priv->txdesc_start); + adev->txdesc_start); - priv->tx_free = TX_CNT; - /* done by memset: priv->tx_head = 0; */ - /* done by memset: priv->tx_tail = 0; */ - txdesc = priv->txdesc_start; + adev->tx_free = TX_CNT; + /* done by memset: adev->tx_head = 0; */ + /* done by memset: adev->tx_tail = 0; */ + txdesc = adev->txdesc_start; mem_offs = tx_queue_start; - hostmemptr = priv->txhostdesc_startphy; - hostdesc = priv->txhostdesc_start; + hostmemptr = adev->txhostdesc_startphy; + hostdesc = adev->txhostdesc_start; - if (IS_ACX111(priv)) { + if (IS_ACX111(adev)) { /* ACX111 has a preinitialized Tx buffer! */ /* loop over whole send pool */ /* FIXME: do we have to do the hostmemptr stuff here?? */ @@ -3828,18 +3808,18 @@ acxpci_create_tx_desc_queue(wlandevice_t txdesc->Ctl_8 = DESC_CTL_HOSTOWN; /* reserve two (hdr desc and payload desc) */ hostdesc += 2; - hostmemptr += 2 * sizeof(txhostdesc_t); - txdesc = advance_txdesc(priv, txdesc, 1); + hostmemptr += 2 * sizeof(*hostdesc); + txdesc = advance_txdesc(adev, txdesc, 1); } } else { /* ACX100 Tx buffer needs to be initialized by us */ /* clear whole send pool. sizeof is safe here (we are acx100) */ - memset(priv->txdesc_start, 0, TX_CNT * sizeof(txdesc_t)); + memset(adev->txdesc_start, 0, TX_CNT * sizeof(*txdesc)); /* loop over whole send pool */ for (i = 0; i < TX_CNT; i++) { log(L_DEBUG, "configure card tx descriptor: 0x%p, " - "size: 0x%X\n", txdesc, priv->txdesc_size); + "size: 0x%X\n", txdesc, adev->txdesc_size); /* pointer to hostdesc memory */ txdesc->HostMemPtr = ptr2acx(hostmemptr); @@ -3848,12 +3828,12 @@ acxpci_create_tx_desc_queue(wlandevice_t | DESC_CTL_AUTODMA | DESC_CTL_FIRSTFRAG); /* done by memset(0): txdesc->Ctl2_8 = 0; */ /* point to next txdesc */ - txdesc->pNextDesc = cpu2acx(mem_offs + priv->txdesc_size); + txdesc->pNextDesc = cpu2acx(mem_offs + adev->txdesc_size); /* reserve two (hdr desc and payload desc) */ hostdesc += 2; - hostmemptr += 2 * sizeof(txhostdesc_t); + hostmemptr += 2 * sizeof(*hostdesc); /* go to the next one */ - mem_offs += priv->txdesc_size; + mem_offs += adev->txdesc_size; /* ++ is safe here (we are acx100) */ txdesc++; } @@ -3870,7 +3850,7 @@ acxpci_create_tx_desc_queue(wlandevice_t ** acxpci_create_rx_desc_queue */ static void -acxpci_create_rx_desc_queue(wlandevice_t *priv, u32 rx_queue_start) +acxpci_create_rx_desc_queue(acx_device_t *adev, u32 rx_queue_start) { rxdesc_t *rxdesc; u32 mem_offs; @@ -3878,42 +3858,42 @@ acxpci_create_rx_desc_queue(wlandevice_t FN_ENTER; - /* done by memset: priv->rx_tail = 0; */ + /* done by memset: adev->rx_tail = 0; */ /* ACX111 doesn't need any further config: preconfigures itself. * Simply print ring buffer for debugging */ - if (IS_ACX111(priv)) { + if (IS_ACX111(adev)) { /* rxdesc_start already set here */ - priv->rxdesc_start = (rxdesc_t *) ((u8 *)priv->iobase2 + rx_queue_start); + adev->rxdesc_start = (rxdesc_t *) ((u8 *)adev->iobase2 + rx_queue_start); - rxdesc = priv->rxdesc_start; + rxdesc = adev->rxdesc_start; for (i = 0; i < RX_CNT; i++) { log(L_DEBUG, "rx descriptor %d @ 0x%p\n", i, rxdesc); - rxdesc = priv->rxdesc_start = (rxdesc_t *) - (priv->iobase2 + acx2cpu(rxdesc->pNextDesc)); + rxdesc = adev->rxdesc_start = (rxdesc_t *) + (adev->iobase2 + acx2cpu(rxdesc->pNextDesc)); } } else { /* we didn't pre-calculate rxdesc_start in case of ACX100 */ /* rxdesc_start should be right AFTER Tx pool */ - priv->rxdesc_start = (rxdesc_t *) - ((u8 *) priv->txdesc_start + (TX_CNT * sizeof(txdesc_t))); + adev->rxdesc_start = (rxdesc_t *) + ((u8 *) adev->txdesc_start + (TX_CNT * sizeof(txdesc_t))); /* NB: sizeof(txdesc_t) above is valid because we know ** we are in if (acx100) block. Beware of cut-n-pasting elsewhere! ** acx111's txdesc is larger! */ - memset(priv->rxdesc_start, 0, RX_CNT * sizeof(rxdesc_t)); + memset(adev->rxdesc_start, 0, RX_CNT * sizeof(*rxdesc)); /* loop over whole receive pool */ - rxdesc = priv->rxdesc_start; + rxdesc = adev->rxdesc_start; mem_offs = rx_queue_start; for (i = 0; i < RX_CNT; i++) { log(L_DEBUG, "rx descriptor @ 0x%p\n", rxdesc); rxdesc->Ctl_8 = DESC_CTL_RECLAIM | DESC_CTL_AUTODMA; /* point to next rxdesc */ - rxdesc->pNextDesc = cpu2acx(mem_offs + sizeof(rxdesc_t)); + rxdesc->pNextDesc = cpu2acx(mem_offs + sizeof(*rxdesc)); /* go to the next one */ - mem_offs += sizeof(rxdesc_t); + mem_offs += sizeof(*rxdesc); rxdesc++; } /* go to the last one */ @@ -3930,10 +3910,10 @@ acxpci_create_rx_desc_queue(wlandevice_t ** acxpci_create_desc_queues */ void -acxpci_create_desc_queues(wlandevice_t *priv, u32 tx_queue_start, u32 rx_queue_start) +acxpci_create_desc_queues(acx_device_t *adev, u32 tx_queue_start, u32 rx_queue_start) { - acxpci_create_tx_desc_queue(priv, tx_queue_start); - acxpci_create_rx_desc_queue(priv, rx_queue_start); + acxpci_create_tx_desc_queue(adev, tx_queue_start); + acxpci_create_rx_desc_queue(adev, rx_queue_start); } @@ -3941,7 +3921,7 @@ acxpci_create_desc_queues(wlandevice_t * ** acxpci_s_proc_diag_output */ char* -acxpci_s_proc_diag_output(char *p, wlandevice_t *priv) +acxpci_s_proc_diag_output(char *p, acx_device_t *adev) { const char *rtl, *thd, *ttl; rxhostdesc_t *rxhostdesc; @@ -3951,9 +3931,9 @@ acxpci_s_proc_diag_output(char *p, wland FN_ENTER; p += sprintf(p, "** Rx buf **\n"); - rxhostdesc = priv->rxhostdesc_start; + rxhostdesc = adev->rxhostdesc_start; if (rxhostdesc) for (i = 0; i < RX_CNT; i++) { - rtl = (i == priv->rx_tail) ? " [tail]" : ""; + rtl = (i == adev->rx_tail) ? " [tail]" : ""; if ((rxhostdesc->Ctl_16 & cpu_to_le16(DESC_CTL_HOSTOWN)) && (rxhostdesc->Status & cpu_to_le32(DESC_STATUS_FULL)) ) p += sprintf(p, "%02u FULL%s\n", i, rtl); @@ -3961,17 +3941,17 @@ acxpci_s_proc_diag_output(char *p, wland p += sprintf(p, "%02u empty%s\n", i, rtl); rxhostdesc++; } - p += sprintf(p, "** Tx buf (free %d, Linux netqueue %s) **\n", priv->tx_free, - acx_queue_stopped(priv->netdev) ? "STOPPED" : "running"); - txdesc = priv->txdesc_start; + p += sprintf(p, "** Tx buf (free %d, Linux netqueue %s) **\n", adev->tx_free, + acx_queue_stopped(adev->ndev) ? "STOPPED" : "running"); + txdesc = adev->txdesc_start; if (txdesc) for (i = 0; i < TX_CNT; i++) { - thd = (i == priv->tx_head) ? " [head]" : ""; - ttl = (i == priv->tx_tail) ? " [tail]" : ""; + thd = (i == adev->tx_head) ? " [head]" : ""; + ttl = (i == adev->tx_tail) ? " [tail]" : ""; if (txdesc->Ctl_8 & DESC_CTL_ACXDONE) p += sprintf(p, "%02u free (%02X)%s%s\n", i, txdesc->Ctl_8, thd, ttl); else p += sprintf(p, "%02u tx (%02X)%s%s\n", i, txdesc->Ctl_8, thd, ttl); - txdesc = advance_txdesc(priv, txdesc, 1); + txdesc = advance_txdesc(adev, txdesc, 1); } p += sprintf(p, "\n" @@ -3982,12 +3962,12 @@ acxpci_s_proc_diag_output(char *p, wland "rxdesc_start %p\n" "rxhostdesc_start %p, rxhostdesc_area_size %u, rxhostdesc_startphy %08llx\n" "rxbuf_start %p, rxbuf_area_size %u, rxbuf_startphy %08llx\n", - priv->txbuf_start, priv->txbuf_area_size, (u64)priv->txbuf_startphy, - priv->txdesc_size, priv->txdesc_start, - priv->txhostdesc_start, priv->txhostdesc_area_size, (u64)priv->txhostdesc_startphy, - priv->rxdesc_start, - priv->rxhostdesc_start, priv->rxhostdesc_area_size, (u64)priv->rxhostdesc_startphy, - priv->rxbuf_start, priv->rxbuf_area_size, (u64)priv->rxbuf_startphy); + adev->txbuf_start, adev->txbuf_area_size, (u64)adev->txbuf_startphy, + adev->txdesc_size, adev->txdesc_start, + adev->txhostdesc_start, adev->txhostdesc_area_size, (u64)adev->txhostdesc_startphy, + adev->rxdesc_start, + adev->rxhostdesc_start, adev->rxhostdesc_area_size, (u64)adev->rxhostdesc_startphy, + adev->rxbuf_start, adev->rxbuf_area_size, (u64)adev->rxbuf_startphy); FN_EXIT0; return p; @@ -3997,7 +3977,7 @@ acxpci_s_proc_diag_output(char *p, wland /*********************************************************************** */ int -acxpci_proc_eeprom_output(char *buf, wlandevice_t *priv) +acxpci_proc_eeprom_output(char *buf, acx_device_t *adev) { char *p = buf; int i; @@ -4005,7 +3985,7 @@ acxpci_proc_eeprom_output(char *buf, wla FN_ENTER; for (i = 0; i < 0x400; i++) { - acxpci_read_eeprom_byte(priv, i, p++); + acxpci_read_eeprom_byte(adev, i, p++); } FN_EXIT1(p - buf); @@ -4016,10 +3996,10 @@ acxpci_proc_eeprom_output(char *buf, wla /*********************************************************************** */ void -acxpci_set_interrupt_mask(wlandevice_t *priv) +acxpci_set_interrupt_mask(acx_device_t *adev) { - if (IS_ACX111(priv)) { - priv->irq_mask = (u16) ~(0 + if (IS_ACX111(adev)) { + adev->irq_mask = (u16) ~(0 /* | HOST_INT_RX_DATA */ | HOST_INT_TX_COMPLETE /* | HOST_INT_TX_XFER */ @@ -4037,9 +4017,10 @@ acxpci_set_interrupt_mask(wlandevice_t * | HOST_INT_FCS_THRESHOLD /* | HOST_INT_UNKNOWN */ ); - priv->irq_mask_off = (u16)~( HOST_INT_CMD_COMPLETE ); /* 0xfdff */ + /* Or else acx100 won't signal cmd completion, right? */ + adev->irq_mask_off = (u16)~( HOST_INT_CMD_COMPLETE ); /* 0xfdff */ } else { - priv->irq_mask = (u16) ~(0 + adev->irq_mask = (u16) ~(0 /* | HOST_INT_RX_DATA */ | HOST_INT_TX_COMPLETE /* | HOST_INT_TX_XFER */ @@ -4057,7 +4038,7 @@ acxpci_set_interrupt_mask(wlandevice_t * /* | HOST_INT_FCS_THRESHOLD */ /* | HOST_INT_UNKNOWN */ ); - priv->irq_mask_off = (u16)~( HOST_INT_UNKNOWN ); /* 0x7fff */ + adev->irq_mask_off = (u16)~( HOST_INT_UNKNOWN ); /* 0x7fff */ } } @@ -4065,7 +4046,7 @@ acxpci_set_interrupt_mask(wlandevice_t * /*********************************************************************** */ int -acx100pci_s_set_tx_level(wlandevice_t *priv, u8 level_dbm) +acx100pci_s_set_tx_level(acx_device_t *adev, u8 level_dbm) { /* since it can be assumed that at least the Maxim radio has a * maximum power output of 20dBm and since it also can be @@ -4101,7 +4082,7 @@ acx100pci_s_set_tx_level(wlandevice_t *p }; const u8 *table; - switch (priv->radio_type) { + switch (adev->radio_type) { case RADIO_MAXIM_0D: table = &dbm2val_maxim[0]; break; @@ -4112,12 +4093,12 @@ acx100pci_s_set_tx_level(wlandevice_t *p default: printk("%s: unknown/unsupported radio type, " "cannot modify tx power level yet!\n", - priv->netdev->name); + adev->ndev->name); return NOT_OK; } printk("%s: changing radio power level to %u dBm (%u)\n", - priv->netdev->name, level_dbm, table[level_dbm]); - acxpci_s_write_phy_reg(priv, 0x11, table[level_dbm]); + adev->ndev->name, level_dbm, table[level_dbm]); + acxpci_s_write_phy_reg(adev, 0x11, table[level_dbm]); return OK; } @@ -4160,13 +4141,6 @@ acxpci_id_tbl[] __devinitdata = { MODULE_DEVICE_TABLE(pci, acxpci_id_tbl); /* FIXME: checks should be removed once driver is included in the kernel */ -#ifndef __devexit_p -#warning *** your kernel is EXTREMELY old since it does not even know about -#warning __devexit_p - this driver could easily FAIL to work, so better -#warning upgrade your kernel! *** -#define __devexit_p(x) x -#endif - #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) /* pci_name() got introduced at start of 2.6.x, * got mandatory (slot_name member removed) in 2.6.11-bk1 */ @@ -4218,7 +4192,7 @@ acxpci_e_init_module(void) "waiting for cards to probe...\n" ); - res = pci_module_init(&acxpci_drv_id); + res = pci_register_driver(&acxpci_drv_id); FN_EXIT1(res); return res; } @@ -4233,7 +4207,7 @@ acxpci_e_init_module(void) void __exit acxpci_e_cleanup_module(void) { - struct net_device *dev; + struct net_device *ndev; unsigned long flags; FN_ENTER; @@ -4246,54 +4220,53 @@ acxpci_e_cleanup_module(void) * that's why hardware operations have to be done here instead * when the hardware is available. */ - down(&root_acx_dev_sem); + down(&root_adev_sem); - dev = root_acx_dev.newest; - while (dev != NULL) { - /* doh, netdev_priv() doesn't have const! */ - wlandevice_t *priv = netdev_priv(dev); + ndev = root_adev_newest; + while (ndev) { + acx_device_t *adev = ndev2adev(ndev); - acx_sem_lock(priv); + acx_sem_lock(adev); /* disable both Tx and Rx to shut radio down properly */ - acx_s_issue_cmd(priv, ACX1xx_CMD_DISABLE_TX, NULL, 0); - acx_s_issue_cmd(priv, ACX1xx_CMD_DISABLE_RX, NULL, 0); + acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0); + acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0); #ifdef REDUNDANT /* put the eCPU to sleep to save power * Halting is not possible currently, * since not supported by all firmware versions */ - acx_s_issue_cmd(priv, ACX100_CMD_SLEEP, NULL, 0); + acx_s_issue_cmd(adev, ACX100_CMD_SLEEP, NULL, 0); #endif - acx_lock(priv, flags); + acx_lock(adev, flags); /* disable power LED to save power :-) */ - log(L_INIT, "switching off power LED to save power :-)\n"); - acxpci_l_power_led(priv, 0); + log(L_INIT, "switching off power LED to save power\n"); + acxpci_l_power_led(adev, 0); /* stop our eCPU */ - if (IS_ACX111(priv)) { + if (IS_ACX111(adev)) { /* FIXME: does this actually keep halting the eCPU? * I don't think so... */ - acxpci_l_reset_mac(priv); + acxpci_l_reset_mac(adev); } else { u16 temp; /* halt eCPU */ - temp = read_reg16(priv, IO_ACX_ECPU_CTRL) | 0x1; - write_reg16(priv, IO_ACX_ECPU_CTRL, temp); - write_flush(priv); + temp = read_reg16(adev, IO_ACX_ECPU_CTRL) | 0x1; + write_reg16(adev, IO_ACX_ECPU_CTRL, temp); + write_flush(adev); } - acx_unlock(priv, flags); + acx_unlock(adev, flags); - acx_sem_unlock(priv); + acx_sem_unlock(adev); - dev = priv->prev_nd; + ndev = adev->prev_nd; } - up(&root_acx_dev_sem); + up(&root_adev_sem); /* now let the PCI layer recursively remove * all PCI related things (acxpci_e_remove()) */ diff -puN drivers/net/wireless/tiacx/README~update-mm-acx-driver-to-version-0331 drivers/net/wireless/tiacx/README --- devel/drivers/net/wireless/tiacx/README~update-mm-acx-driver-to-version-0331 2006-01-31 18:11:09.000000000 -0800 +++ devel-akpm/drivers/net/wireless/tiacx/README 2006-01-31 18:11:09.000000000 -0800 @@ -1,4 +1,5 @@ Contact: +netdev@vger.kernel.org acx100-devel@lists.sourceforge.net acx100-users@lists.sourceforge.net diff -puN drivers/net/wireless/tiacx/usb.c~update-mm-acx-driver-to-version-0331 drivers/net/wireless/tiacx/usb.c --- devel/drivers/net/wireless/tiacx/usb.c~update-mm-acx-driver-to-version-0331 2006-01-31 18:11:09.000000000 -0800 +++ devel-akpm/drivers/net/wireless/tiacx/usb.c 2006-01-31 18:11:09.000000000 -0800 @@ -48,18 +48,14 @@ #include #include #include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) #include -#endif #include #include #include #include #include #include -#if WIRELESS_EXT >= 13 #include -#endif #include #include "acx.h" @@ -112,7 +108,7 @@ static int acxusb_e_close(struct net_dev static void acxusb_i_set_rx_mode(struct net_device *); static int acxusb_boot(struct usb_device *); -static void acxusb_l_poll_rx(wlandevice_t *, usb_rx_t* rx); +static void acxusb_l_poll_rx(acx_device_t *adev, usb_rx_t* rx); static void acxusb_i_tx_timeout(struct net_device *); @@ -201,18 +197,22 @@ acxusb_unlink_urb(struct urb* urb) ** acxusb_s_read_phy_reg */ int -acxusb_s_read_phy_reg(wlandevice_t *priv, u32 reg, u8 *charbuf) +acxusb_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf) { - mem_read_write_t mem; + /* mem_read_write_t mem; */ FN_ENTER; + printk("%s doesn't seem to work yet, disabled.\n", __func__); + + /* mem.addr = cpu_to_le16(reg); mem.type = cpu_to_le16(0x82); mem.len = cpu_to_le32(4); - acx_s_issue_cmd(priv, ACX1xx_CMD_MEM_READ, &mem, sizeof(mem)); + acx_s_issue_cmd(adev, ACX1xx_CMD_MEM_READ, &mem, sizeof(mem)); *charbuf = mem.data; log(L_DEBUG, "read radio PHY[0x%04X]=0x%02X\n", reg, *charbuf); + */ FN_EXIT1(OK); return OK; @@ -222,7 +222,7 @@ acxusb_s_read_phy_reg(wlandevice_t *priv /*********************************************************************** */ int -acxusb_s_write_phy_reg(wlandevice_t *priv, u32 reg, u8 value) +acxusb_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value) { mem_read_write_t mem; @@ -232,7 +232,7 @@ acxusb_s_write_phy_reg(wlandevice_t *pri mem.type = cpu_to_le16(0x82); mem.len = cpu_to_le32(4); mem.data = value; - acx_s_issue_cmd(priv, ACX1xx_CMD_MEM_WRITE, &mem, sizeof(mem)); + acx_s_issue_cmd(adev, ACX1xx_CMD_MEM_WRITE, &mem, sizeof(mem)); log(L_DEBUG, "write radio PHY[0x%04X]=0x%02X\n", reg, value); FN_EXIT1(OK); @@ -258,7 +258,7 @@ acxusb_s_write_phy_reg(wlandevice_t *pri #if !ACX_DEBUG int acxusb_s_issue_cmd_timeo( - wlandevice_t *priv, + acx_device_t *adev, unsigned cmd, void *buffer, unsigned buflen, @@ -267,7 +267,7 @@ acxusb_s_issue_cmd_timeo( #else int acxusb_s_issue_cmd_timeo_debug( - wlandevice_t *priv, + acx_device_t *adev, unsigned cmd, void *buffer, unsigned buflen, @@ -290,7 +290,7 @@ acxusb_s_issue_cmd_timeo_debug( FN_ENTER; - devname = priv->netdev->name; + devname = adev->ndev->name; /* no "wlan%%d: ..." please */ if (!devname || !devname[0] || devname[4]=='%') devname = "acx"; @@ -305,8 +305,8 @@ acxusb_s_issue_cmd_timeo_debug( goto bad; } - /* get context from wlandevice */ - usbdev = priv->usbdev; + /* get context from acx_device */ + usbdev = adev->usbdev; /* check which kind of command was issued */ loc->cmd = cpu_to_le16(cmd); @@ -367,7 +367,7 @@ acxusb_s_issue_cmd_timeo_debug( /* check for device acknowledge */ log(L_CTL, "sending USB control msg (in) (acklen=%d)\n", acklen); loc->status = 0; /* delete old status flag -> set to IDLE */ -//shall we zero out the rest? + /* shall we zero out the rest? */ result = usb_control_msg(usbdev, inpipe, ACX_USB_REQ_CMD, /* request */ USB_TYPE_VENDOR|USB_DIR_IN, /* requesttype */ @@ -386,8 +386,9 @@ acxusb_s_issue_cmd_timeo_debug( acx_dump_bytes(loc, result); } -//check for result==buflen+4? Was seen: /* + check for result==buflen+4? Was seen: + interrogate(type:ACX100_IE_DOT11_ED_THRESHOLD,len:4) issue_cmd(cmd:ACX1xx_CMD_INTERROGATE,buflen:8,type:4111) ctrl inpipe=0x80000280 outpipe=0x80000200 @@ -550,6 +551,27 @@ end: } +/* + * temporary helper function to at least fill important cfgopt members with + * useful replacement values until we figure out how one manages to fetch + * the configoption struct in the USB device case... + */ +int +acxusb_s_fill_configoption(acx_device_t *adev) +{ + printk("FIXME: haven't figured out how to fetch configoption struct " + "from USB device, passing hardcoded values instead\n"); + adev->cfgopt_probe_delay = 200; + adev->cfgopt_dot11CCAModes = 4; + adev->cfgopt_dot11Diversity = 1; + adev->cfgopt_dot11ShortPreambleOption = 1; + adev->cfgopt_dot11PBCCOption = 1; + adev->cfgopt_dot11ChannelAgility = 0; + adev->cfgopt_dot11PhyType = 5; + adev->cfgopt_dot11TempType = 1; + return OK; +} + /*********************************************************************** ** acxusb_e_probe() ** @@ -561,14 +583,14 @@ end: */ static void -dummy_netdev_init(struct net_device *dev) {} +dummy_netdev_init(struct net_device *ndev) {} static int acxusb_e_probe(struct usb_interface *intf, const struct usb_device_id *devID) { struct usb_device *usbdev = interface_to_usbdev(intf); - wlandevice_t *priv = NULL; - struct net_device *dev = NULL; + acx_device_t *adev = NULL; + struct net_device *ndev = NULL; struct usb_config_descriptor *config; struct usb_endpoint_descriptor *epdesc; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) @@ -607,45 +629,46 @@ acxusb_e_probe(struct usb_interface *int /* Allocate memory for a network device */ - dev = alloc_netdev(sizeof(wlandevice_t), "wlan%d", dummy_netdev_init); + ndev = alloc_netdev(sizeof(*adev), "wlan%d", dummy_netdev_init); /* (NB: memsets to 0 entire area) */ - if (!dev) { + if (!ndev) { msg = "acx: no memory for netdev\n"; goto end_nomem; } /* Register the callbacks for the network device functions */ - ether_setup(dev); - dev->open = &acxusb_e_open; - dev->stop = &acxusb_e_close; - dev->hard_start_xmit = (void *)&acx_i_start_xmit; - dev->get_stats = (void *)&acx_e_get_stats; - dev->get_wireless_stats = (void *)&acx_e_get_wireless_stats; -#if WIRELESS_EXT >= 13 - dev->wireless_handlers = (struct iw_handler_def *)&acx_ioctl_handler_def; -#else - dev->do_ioctl = (void *)&acx_e_ioctl_old; + ether_setup(ndev); + ndev->open = &acxusb_e_open; + ndev->stop = &acxusb_e_close; + ndev->hard_start_xmit = (void *)&acx_i_start_xmit; + ndev->get_stats = (void *)&acx_e_get_stats; +#if IW_HANDLER_VERSION <= 5 + ndev->get_wireless_stats = (void *)&acx_e_get_wireless_stats; #endif - dev->set_multicast_list = (void *)&acxusb_i_set_rx_mode; + ndev->wireless_handlers = (struct iw_handler_def *)&acx_ioctl_handler_def; + ndev->set_multicast_list = (void *)&acxusb_i_set_rx_mode; #ifdef HAVE_TX_TIMEOUT - dev->tx_timeout = &acxusb_i_tx_timeout; - dev->watchdog_timeo = 4 * HZ; + ndev->tx_timeout = &acxusb_i_tx_timeout; + ndev->watchdog_timeo = 4 * HZ; #endif - dev->change_mtu = &acx_e_change_mtu; - SET_MODULE_OWNER(dev); + ndev->change_mtu = &acx_e_change_mtu; + SET_MODULE_OWNER(ndev); /* Setup private driver context */ - priv = netdev_priv(dev); - priv->netdev = dev; - priv->dev_type = DEVTYPE_USB; - priv->chip_type = CHIPTYPE_ACX100; + adev = ndev2adev(ndev); + adev->ndev = ndev; + + adev->dev_type = DEVTYPE_USB; + adev->chip_type = CHIPTYPE_ACX100; + /* FIXME: should be read from register (via firmware) using standard ACX code */ - priv->radio_type = RADIO_MAXIM_0D; - priv->usbdev = usbdev; - spin_lock_init(&priv->lock); /* initial state: unlocked */ - sema_init(&priv->sem, 1); /* initial state: 1 (upped) */ + adev->radio_type = RADIO_MAXIM_0D; + + adev->usbdev = usbdev; + spin_lock_init(&adev->lock); /* initial state: unlocked */ + sema_init(&adev->sem, 1); /* initial state: 1 (upped) */ /* Check that this is really the hardware we know about. ** If not sure, at least notify the user that he @@ -671,8 +694,8 @@ acxusb_e_probe(struct usb_interface *int /* obtain information about the endpoint ** addresses, begin with some default values */ - priv->bulkoutep = 1; - priv->bulkinep = 1; + adev->bulkoutep = 1; + adev->bulkinep = 1; for (i = 0; i < numep; i++) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) ep = usbdev->ep_in[i]; @@ -686,88 +709,91 @@ acxusb_e_probe(struct usb_interface *int #endif if (epdesc->bmAttributes & USB_ENDPOINT_XFER_BULK) { if (epdesc->bEndpointAddress & 0x80) - priv->bulkinep = epdesc->bEndpointAddress & 0xF; + adev->bulkinep = epdesc->bEndpointAddress & 0xF; else - priv->bulkoutep = epdesc->bEndpointAddress & 0xF; + adev->bulkoutep = epdesc->bEndpointAddress & 0xF; } } - log(L_DEBUG, "bulkout ep: 0x%X\n", priv->bulkoutep); - log(L_DEBUG, "bulkin ep: 0x%X\n", priv->bulkinep); + log(L_DEBUG, "bulkout ep: 0x%X\n", adev->bulkoutep); + log(L_DEBUG, "bulkin ep: 0x%X\n", adev->bulkinep); - /* already done by memset: priv->rxtruncsize = 0; */ + /* already done by memset: adev->rxtruncsize = 0; */ log(L_DEBUG, "TXBUFSIZE=%d RXBUFSIZE=%d\n", (int) TXBUFSIZE, (int) RXBUFSIZE); /* Allocate the RX/TX containers. */ - priv->usb_tx = kmalloc(sizeof(usb_tx_t) * ACX_TX_URB_CNT, GFP_KERNEL); - if (!priv->usb_tx) { + adev->usb_tx = kmalloc(sizeof(usb_tx_t) * ACX_TX_URB_CNT, GFP_KERNEL); + if (!adev->usb_tx) { msg = "acx: no memory for tx container"; goto end_nomem; } - priv->usb_rx = kmalloc(sizeof(usb_rx_t) * ACX_RX_URB_CNT, GFP_KERNEL); - if (!priv->usb_rx) { + adev->usb_rx = kmalloc(sizeof(usb_rx_t) * ACX_RX_URB_CNT, GFP_KERNEL); + if (!adev->usb_rx) { msg = "acx: no memory for rx container"; goto end_nomem; } /* Setup URBs for bulk-in/out messages */ for (i = 0; i < ACX_RX_URB_CNT; i++) { - priv->usb_rx[i].urb = usb_alloc_urb(0, GFP_KERNEL); - if (!priv->usb_rx[i].urb) { + adev->usb_rx[i].urb = usb_alloc_urb(0, GFP_KERNEL); + if (!adev->usb_rx[i].urb) { msg = "acx: no memory for input URB\n"; goto end_nomem; } - priv->usb_rx[i].urb->status = 0; - priv->usb_rx[i].priv = priv; - priv->usb_rx[i].busy = 0; + adev->usb_rx[i].urb->status = 0; + adev->usb_rx[i].adev = adev; + adev->usb_rx[i].busy = 0; } for (i = 0; i< ACX_TX_URB_CNT; i++) { - priv->usb_tx[i].urb = usb_alloc_urb(0, GFP_KERNEL); - if (!priv->usb_tx[i].urb) { + adev->usb_tx[i].urb = usb_alloc_urb(0, GFP_KERNEL); + if (!adev->usb_tx[i].urb) { msg = "acx: no memory for output URB\n"; goto end_nomem; } - priv->usb_tx[i].urb->status = 0; - priv->usb_tx[i].priv = priv; - priv->usb_tx[i].busy = 0; + adev->usb_tx[i].urb->status = 0; + adev->usb_tx[i].adev = adev; + adev->usb_tx[i].busy = 0; } - priv->tx_free = ACX_TX_URB_CNT; + adev->tx_free = ACX_TX_URB_CNT; - usb_set_intfdata(intf, priv); - SET_NETDEV_DEV(dev, &intf->dev); + usb_set_intfdata(intf, adev); + SET_NETDEV_DEV(ndev, &intf->dev); -//TODO: move all of fw cmds to open()? But then we won't know our MAC addr -//until ifup (it's available via reading ACX1xx_IE_DOT11_STATION_ID)... + /* TODO: move all of fw cmds to open()? But then we won't know our MAC addr + until ifup (it's available via reading ACX1xx_IE_DOT11_STATION_ID)... */ /* put acx out of sleep mode and initialize it */ - acx_s_issue_cmd(priv, ACX1xx_CMD_WAKE, NULL, 0); - result = acx_s_init_mac(priv); + acx_s_issue_cmd(adev, ACX1xx_CMD_WAKE, NULL, 0); + + acxusb_s_fill_configoption(adev); + + result = acx_s_init_mac(adev); if (result) goto end; - acx_s_set_defaults(priv); - acx_s_get_firmware_version(priv); - acx_display_hardware_details(priv); + acx_s_set_defaults(adev); + acx_s_get_firmware_version(adev); + acx_display_hardware_details(adev); /* Register the network device */ log(L_INIT, "registering network device\n"); - result = register_netdev(dev); + result = register_netdev(ndev); if (result) { msg = "acx: failed to register USB network device " "(error %d)\n"; goto end_nomem; } - acx_proc_register_entries(dev); + acx_proc_register_entries(ndev); - acx_stop_queue(dev, "on probe"); - acx_carrier_off(dev, "on probe"); + acx_stop_queue(ndev, "on probe"); + acx_carrier_off(ndev, "on probe"); printk("acx: USB module " ACX_RELEASE " loaded successfully\n"); #if CMD_DISCOVERY - great_inquisitor(priv); + great_inquisitor(adev); #endif /* Everything went OK, we are happy now */ @@ -777,25 +803,24 @@ acxusb_e_probe(struct usb_interface *int end_nomem: printk(msg, result); - if (dev) { - if (priv->usb_rx) { + if (ndev) { + if (adev->usb_rx) { for (i = 0; i < ACX_RX_URB_CNT; i++) - usb_free_urb(priv->usb_rx[i].urb); - kfree(priv->usb_rx); + usb_free_urb(adev->usb_rx[i].urb); + kfree(adev->usb_rx); } - if (priv->usb_tx) { + if (adev->usb_tx) { for (i = 0; i < ACX_TX_URB_CNT; i++) - usb_free_urb(priv->usb_tx[i].urb); - kfree(priv->usb_tx); + usb_free_urb(adev->usb_tx[i].urb); + kfree(adev->usb_tx); } - free_netdev(dev); + free_netdev(ndev); } result = -ENOMEM; goto end; end_nodev: - /* no device we could handle, return error. */ result = -EIO; @@ -816,14 +841,14 @@ end: static void acxusb_e_disconnect(struct usb_interface *intf) { - wlandevice_t *priv = usb_get_intfdata(intf); + acx_device_t *adev = usb_get_intfdata(intf); unsigned long flags; int i; FN_ENTER; /* No WLAN device... no sense */ - if (!priv) + if (!adev) goto end; /* Unregister network device @@ -836,33 +861,33 @@ acxusb_e_disconnect(struct usb_interface * _close() will try to grab it as well if it's called, * deadlocking the machine. */ - unregister_netdev(priv->netdev); + unregister_netdev(adev->ndev); - acx_sem_lock(priv); - acx_lock(priv, flags); + acx_sem_lock(adev); + acx_lock(adev, flags); /* This device exists no more */ usb_set_intfdata(intf, NULL); - acx_proc_unregister_entries(priv->netdev); + acx_proc_unregister_entries(adev->ndev); /* * Here we only free them. _close() took care of * unlinking them. */ for (i = 0; i < ACX_RX_URB_CNT; ++i) { - usb_free_urb(priv->usb_rx[i].urb); + usb_free_urb(adev->usb_rx[i].urb); } for (i = 0; i< ACX_TX_URB_CNT; ++i) { - usb_free_urb(priv->usb_tx[i].urb); + usb_free_urb(adev->usb_tx[i].urb); } /* Freeing containers */ - kfree(priv->usb_rx); - kfree(priv->usb_tx); + kfree(adev->usb_rx); + kfree(adev->usb_tx); - acx_unlock(priv, flags); - acx_sem_unlock(priv); + acx_unlock(adev, flags); + acx_sem_unlock(adev); - free_netdev(priv->netdev); + free_netdev(adev->ndev); end: FN_EXIT0; } @@ -875,43 +900,41 @@ end: ** the network tx queue and USB receive. */ static int -acxusb_e_open(struct net_device *dev) +acxusb_e_open(struct net_device *ndev) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); unsigned long flags; int i; FN_ENTER; - acx_sem_lock(priv); + acx_sem_lock(adev); /* put the ACX100 out of sleep mode */ - acx_s_issue_cmd(priv, ACX1xx_CMD_WAKE, NULL, 0); + acx_s_issue_cmd(adev, ACX1xx_CMD_WAKE, NULL, 0); - acx_init_task_scheduler(priv); + acx_init_task_scheduler(adev); - init_timer(&priv->mgmt_timer); - priv->mgmt_timer.function = acx_i_timer; - priv->mgmt_timer.data = (unsigned long)priv; + init_timer(&adev->mgmt_timer); + adev->mgmt_timer.function = acx_i_timer; + adev->mgmt_timer.data = (unsigned long)adev; /* acx_s_start needs it */ - SET_BIT(priv->dev_state_mask, ACX_STATE_IFACE_UP); - acx_s_start(priv); + SET_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP); + acx_s_start(adev); /* don't acx_start_queue() here, we need to associate first */ - acx_lock(priv, flags); + acx_lock(adev, flags); for (i = 0; i < ACX_RX_URB_CNT; i++) { - priv->usb_rx[i].urb->status = 0; + adev->usb_rx[i].urb->status = 0; } - acxusb_l_poll_rx(priv, &priv->usb_rx[0]); - - acx_unlock(priv, flags); + acxusb_l_poll_rx(adev, &adev->usb_rx[0]); - WLAN_MOD_INC_USE_COUNT; + acx_unlock(adev, flags); - acx_sem_unlock(priv); + acx_sem_unlock(adev); FN_EXIT0; return 0; @@ -928,9 +951,9 @@ acxusb_e_open(struct net_device *dev) ** is also decreased in this function. */ static int -acxusb_e_close(struct net_device *dev) +acxusb_e_close(struct net_device *ndev) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); unsigned long flags; int i; @@ -939,54 +962,51 @@ acxusb_e_close(struct net_device *dev) #ifdef WE_STILL_DONT_CARE_ABOUT_IT /* Transmit a disassociate frame */ lock - acx_l_transmit_disassoc(priv, &client); + acx_l_transmit_disassoc(adev, &client); unlock #endif - acx_sem_lock(priv); + acx_sem_lock(adev); - CLEAR_BIT(priv->dev_state_mask, ACX_STATE_IFACE_UP); + CLEAR_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP); -//Code below is remarkably similar to acxpci_s_down(). Maybe we can merge them? +/* Code below is remarkably similar to acxpci_s_down(). Maybe we can merge them? */ /* Make sure we don't get any more rx requests */ - acx_s_issue_cmd(priv, ACX1xx_CMD_DISABLE_RX, NULL, 0); - acx_s_issue_cmd(priv, ACX1xx_CMD_DISABLE_TX, NULL, 0); + acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0); + acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0); /* * We must do FLUSH *without* holding sem to avoid a deadlock. * See pci.c:acxpci_s_down() for deails. */ - acx_sem_unlock(priv); + acx_sem_unlock(adev); FLUSH_SCHEDULED_WORK(); - acx_sem_lock(priv); + acx_sem_lock(adev); /* Power down the device */ - acx_s_issue_cmd(priv, ACX1xx_CMD_SLEEP, NULL, 0); + acx_s_issue_cmd(adev, ACX1xx_CMD_SLEEP, NULL, 0); /* Stop the transmit queue, mark the device as DOWN */ - acx_lock(priv, flags); - acx_stop_queue(dev, "on ifdown"); - acx_set_status(priv, ACX_STATUS_0_STOPPED); + acx_lock(adev, flags); + acx_stop_queue(ndev, "on ifdown"); + acx_set_status(adev, ACX_STATUS_0_STOPPED); /* stop pending rx/tx urb transfers */ for (i = 0; i < ACX_TX_URB_CNT; i++) { - acxusb_unlink_urb(priv->usb_tx[i].urb); - priv->usb_tx[i].busy = 0; + acxusb_unlink_urb(adev->usb_tx[i].urb); + adev->usb_tx[i].busy = 0; } for (i = 0; i < ACX_RX_URB_CNT; i++) { - acxusb_unlink_urb(priv->usb_rx[i].urb); - priv->usb_rx[i].busy = 0; + acxusb_unlink_urb(adev->usb_rx[i].urb); + adev->usb_rx[i].busy = 0; } - priv->tx_free = ACX_TX_URB_CNT; - acx_unlock(priv, flags); + adev->tx_free = ACX_TX_URB_CNT; + acx_unlock(adev, flags); /* Must do this outside of lock */ - del_timer_sync(&priv->mgmt_timer); + del_timer_sync(&adev->mgmt_timer); - acx_sem_unlock(priv); - - /* Decrease module-in-use count (if necessary) */ - WLAN_MOD_DEC_USE_COUNT; + acx_sem_unlock(adev); FN_EXIT0; return 0; @@ -998,7 +1018,7 @@ acxusb_e_close(struct net_device *dev) ** This function (re)initiates a bulk-in USB transfer on a given urb */ static void -acxusb_l_poll_rx(wlandevice_t *priv, usb_rx_t* rx) +acxusb_l_poll_rx(acx_device_t *adev, usb_rx_t* rx) { struct usb_device *usbdev; struct urb *rxurb; @@ -1008,11 +1028,11 @@ acxusb_l_poll_rx(wlandevice_t *priv, usb FN_ENTER; rxurb = rx->urb; - usbdev = priv->usbdev; + usbdev = adev->usbdev; - rxnum = rx - priv->usb_rx; + rxnum = rx - adev->usb_rx; - inpipe = usb_rcvbulkpipe(usbdev, priv->bulkinep); + inpipe = usb_rcvbulkpipe(usbdev, adev->bulkinep); if (unlikely(rxurb->status == -EINPROGRESS)) { printk(KERN_ERR "acx: error, rx triggered while rx urb in progress\n"); /* FIXME: this is nasty, receive is being cancelled by this code @@ -1057,7 +1077,7 @@ end: static void acxusb_i_complete_rx(struct urb *urb, struct pt_regs *regs) { - wlandevice_t *priv; + acx_device_t *adev; rxbuffer_t *ptr; rxbuffer_t *inbuf; usb_rx_t *rx; @@ -1069,15 +1089,15 @@ acxusb_i_complete_rx(struct urb *urb, st BUG_ON(!urb->context); rx = (usb_rx_t *)urb->context; - priv = rx->priv; + adev = rx->adev; - acx_lock(priv, flags); + acx_lock(adev, flags); /* * Happens on disconnect or close. Don't play with the urb. * Don't resubmit it. It will get unlinked by close() */ - if (unlikely(!(priv->dev_state_mask & ACX_STATE_IFACE_UP))) { + if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) { log(L_USBRXTX, "rx: device is down, not doing anything\n"); goto end_unlock; } @@ -1085,14 +1105,14 @@ acxusb_i_complete_rx(struct urb *urb, st inbuf = &rx->bulkin; size = urb->actual_length; remsize = size; - rxnum = rx - priv->usb_rx; + rxnum = rx - adev->usb_rx; log(L_USBRXTX, "RETURN RX (%d) status=%d size=%d\n", rxnum, urb->status, size); /* Send the URB that's waiting. */ log(L_USBRXTX, "rxnum=%d, sending=%d\n", rxnum, rxnum^1); - acxusb_l_poll_rx(priv, &priv->usb_rx[rxnum^1]); + acxusb_l_poll_rx(adev, &adev->usb_rx[rxnum^1]); if (unlikely(size > sizeof(rxbuffer_t))) printk("acx_usb: rx too large: %d, please report\n", size); @@ -1103,17 +1123,17 @@ acxusb_i_complete_rx(struct urb *urb, st break; case -EOVERFLOW: printk(KERN_ERR "acx: rx data overrun\n"); - priv->rxtruncsize = 0; /* Not valid anymore. */ + adev->rxtruncsize = 0; /* Not valid anymore. */ goto end_unlock; case -ECONNRESET: - priv->rxtruncsize = 0; + adev->rxtruncsize = 0; goto end_unlock; case -ESHUTDOWN: /* rmmod */ - priv->rxtruncsize = 0; + adev->rxtruncsize = 0; goto end_unlock; default: - priv->rxtruncsize = 0; - priv->stats.rx_errors++; + adev->rxtruncsize = 0; + adev->stats.rx_errors++; printk("acx: rx error (urb status=%d)\n", urb->status); goto end_unlock; } @@ -1129,28 +1149,28 @@ acxusb_i_complete_rx(struct urb *urb, st ** of consecutive packets! */ ptr = inbuf; - if (priv->rxtruncsize) { + if (adev->rxtruncsize) { int tail_size; - ptr = &priv->rxtruncbuf; + ptr = &adev->rxtruncbuf; packetsize = RXBUF_BYTES_USED(ptr); if (acx_debug & L_USBRXTX) { printk("handling truncated frame (truncsize=%d size=%d " "packetsize(from trunc)=%d)\n", - priv->rxtruncsize, size, packetsize); + adev->rxtruncsize, size, packetsize); acx_dump_bytes(ptr, RXBUF_HDRSIZE); acx_dump_bytes(inbuf, RXBUF_HDRSIZE); } /* bytes needed for rxtruncbuf completion: */ - tail_size = packetsize - priv->rxtruncsize; + tail_size = packetsize - adev->rxtruncsize; if (size < tail_size) { /* there is not enough data to complete this packet, ** simply append the stuff to the truncation buffer */ - memcpy(((char *)ptr) + priv->rxtruncsize, inbuf, size); - priv->rxtruncsize += size; + memcpy(((char *)ptr) + adev->rxtruncsize, inbuf, size); + adev->rxtruncsize += size; remsize = 0; } else { /* ok, this data completes the previously @@ -1158,18 +1178,18 @@ acxusb_i_complete_rx(struct urb *urb, st ** and give it to the rest of the stack */ /* append tail to previously truncated part - ** NB: priv->rxtruncbuf (pointed to by ptr) can't + ** NB: adev->rxtruncbuf (pointed to by ptr) can't ** overflow because this is already checked before ** truncation buffer was filled. See below, ** "if (packetsize > sizeof(rxbuffer_t))..." code */ - memcpy(((char *)ptr) + priv->rxtruncsize, inbuf, tail_size); + memcpy(((char *)ptr) + adev->rxtruncsize, inbuf, tail_size); if (acx_debug & L_USBRXTX) { printk("full trailing packet + 12 bytes:\n"); acx_dump_bytes(inbuf, tail_size + RXBUF_HDRSIZE); } - acx_l_process_rxbuf(priv, ptr); - priv->rxtruncsize = 0; + acx_l_process_rxbuf(adev, ptr); + adev->rxtruncsize = 0; ptr = (rxbuffer_t *) (((char *)inbuf) + tail_size); remsize -= tail_size; } @@ -1207,18 +1227,18 @@ acxusb_i_complete_rx(struct urb *urb, st stat->rate, stat->ack_failures, stat->rts_failures, stat->rts_ok); - if (priv->rate_auto && client_no < VEC_SIZE(priv->sta_list)) { - client_t *clt = &priv->sta_list[client_no]; + if (adev->rate_auto && client_no < VEC_SIZE(adev->sta_list)) { + client_t *clt = &adev->sta_list[client_no]; u16 cur = stat->hostdata >> 16; if (clt && clt->rate_cur == cur) { - acx_l_handle_txrate_auto(priv, clt, + acx_l_handle_txrate_auto(adev, clt, cur, /* intended rate */ stat->rate, 0, /* actually used rate */ stat->mac_status, /* error? */ - ACX_TX_URB_CNT - priv->tx_free); + ACX_TX_URB_CNT - adev->tx_free); } - } + } goto next; } @@ -1241,14 +1261,14 @@ acxusb_i_complete_rx(struct urb *urb, st packetsize, remsize, size); acx_dump_bytes(ptr, RXBUF_HDRSIZE); } - memcpy(&priv->rxtruncbuf, ptr, remsize); - priv->rxtruncsize = remsize; + memcpy(&adev->rxtruncbuf, ptr, remsize); + adev->rxtruncsize = remsize; break; } /* packetsize <= remsize */ /* now handle the received data */ - acx_l_process_rxbuf(priv, ptr); + acx_l_process_rxbuf(adev, ptr); next: ptr = (rxbuffer_t *)(((char *)ptr) + packetsize); remsize -= packetsize; @@ -1260,7 +1280,7 @@ next: } end_unlock: - acx_unlock(priv, flags); + acx_unlock(adev, flags); /* end: */ FN_EXIT0; } @@ -1277,7 +1297,7 @@ end_unlock: static void acxusb_i_complete_tx(struct urb *urb, struct pt_regs *regs) { - wlandevice_t *priv; + acx_device_t *adev; usb_tx_t *tx; unsigned long flags; int txnum; @@ -1287,17 +1307,17 @@ acxusb_i_complete_tx(struct urb *urb, st BUG_ON(!urb->context); tx = (usb_tx_t *)urb->context; - priv = tx->priv; + adev = tx->adev; - txnum = tx - priv->usb_tx; + txnum = tx - adev->usb_tx; - acx_lock(priv, flags); + acx_lock(adev, flags); /* * If the iface isn't up, we don't have any right * to play with them. The urb may get unlinked. */ - if (unlikely(!(priv->dev_state_mask & ACX_STATE_IFACE_UP))) { + if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) { log(L_USBRXTX, "tx: device is down, not doing anything\n"); goto end_unlock; } @@ -1323,18 +1343,18 @@ acxusb_i_complete_tx(struct urb *urb, st /* free the URB and check for more data */ tx->busy = 0; - priv->tx_free++; - if ((priv->tx_free >= TX_START_QUEUE) - && (priv->status == ACX_STATUS_4_ASSOCIATED) - && (acx_queue_stopped(priv->netdev)) + adev->tx_free++; + if ((adev->tx_free >= TX_START_QUEUE) + && (adev->status == ACX_STATUS_4_ASSOCIATED) + && (acx_queue_stopped(adev->ndev)) ) { log(L_BUF, "tx: wake queue (%u free txbufs)\n", - priv->tx_free); - acx_wake_queue(priv->netdev, NULL); + adev->tx_free); + acx_wake_queue(adev->ndev, NULL); } end_unlock: - acx_unlock(priv, flags); + acx_unlock(adev, flags); /* end: */ FN_EXIT0; } @@ -1345,35 +1365,35 @@ end_unlock: ** Actually returns a usb_tx_t* ptr */ tx_t* -acxusb_l_alloc_tx(wlandevice_t* priv) +acxusb_l_alloc_tx(acx_device_t *adev) { usb_tx_t *tx; int head; FN_ENTER; - head = priv->tx_head; + head = adev->tx_head; do { head = (head + 1) % ACX_TX_URB_CNT; - if (!priv->usb_tx[head].busy) { + if (!adev->usb_tx[head].busy) { log(L_USBRXTX, "allocated tx %d\n", head); - tx = &priv->usb_tx[head]; + tx = &adev->usb_tx[head]; tx->busy = 1; - priv->tx_free--; + adev->tx_free--; /* Keep a few free descs between head and tail of tx ring. ** It is not absolutely needed, just feels safer */ - if (priv->tx_free < TX_STOP_QUEUE) { + if (adev->tx_free < TX_STOP_QUEUE) { log(L_BUF, "tx: stop queue " - "(%u free txbufs)\n", priv->tx_free); - acx_stop_queue(priv->netdev, NULL); + "(%u free txbufs)\n", adev->tx_free); + acx_stop_queue(adev->ndev, NULL); } goto end; } - } while (likely(head!=priv->tx_head)); + } while (likely(head!=adev->tx_head)); tx = NULL; printk_ratelimited("acx: tx buffers full\n"); end: - priv->tx_head = head; + adev->tx_head = head; FN_EXIT0; return (tx_t*)tx; } @@ -1393,7 +1413,7 @@ acxusb_l_dealloc_tx(tx_t *tx_opaque) /*************************************************************** */ void* -acxusb_l_get_txbuf(wlandevice_t *priv, tx_t* tx_opaque) +acxusb_l_get_txbuf(acx_device_t *adev, tx_t* tx_opaque) { usb_tx_t* tx = (usb_tx_t*)tx_opaque; return &tx->bulkout.data; @@ -1407,7 +1427,7 @@ acxusb_l_get_txbuf(wlandevice_t *priv, t ** Can be called from acx_i_start_xmit (data frames from net core). */ void -acxusb_l_tx_data(wlandevice_t *priv, tx_t* tx_opaque, int wlanpkt_len) +acxusb_l_tx_data(acx_device_t *adev, tx_t* tx_opaque, int wlanpkt_len) { struct usb_device *usbdev; struct urb* txurb; @@ -1424,18 +1444,18 @@ acxusb_l_tx_data(wlandevice_t *priv, tx_ txurb = tx->urb; txbuf = &tx->bulkout; whdr = (wlan_hdr_t *)txbuf->data; - txnum = tx - priv->usb_tx; + txnum = tx - adev->usb_tx; log(L_DEBUG, "using buf#%d free=%d len=%d\n", - txnum, priv->tx_free, wlanpkt_len); + txnum, adev->tx_free, wlanpkt_len); - switch (priv->mode) { + switch (adev->mode) { case ACX_MODE_0_ADHOC: case ACX_MODE_3_AP: - clt = acx_l_sta_list_get(priv, whdr->a1); + clt = acx_l_sta_list_get(adev, whdr->a1); break; case ACX_MODE_2_STA: - clt = priv->ap_client; + clt = adev->ap_client; break; default: /* ACX_MODE_OFF, ACX_MODE_MONITOR */ clt = NULL; @@ -1453,18 +1473,18 @@ acxusb_l_tx_data(wlandevice_t *priv, tx_ txbuf->queue_index = 1; if (clt) { txbuf->rate = clt->rate_100; - txbuf->hostdata = (clt - priv->sta_list) | (clt->rate_cur << 16); + txbuf->hostdata = (clt - adev->sta_list) | (clt->rate_cur << 16); } else { - txbuf->rate = priv->rate_bcast100; - txbuf->hostdata = ((u16)-1) | (priv->rate_bcast << 16); + txbuf->rate = adev->rate_bcast100; + txbuf->hostdata = ((u16)-1) | (adev->rate_bcast << 16); } txbuf->ctrl1 = DESC_CTL_FIRSTFRAG; - if (1 == priv->preamble_cur) + if (1 == adev->preamble_cur) SET_BIT(txbuf->ctrl1, DESC_CTL_SHORT_PREAMBLE); txbuf->ctrl2 = 0; txbuf->data_len = cpu_to_le16(wlanpkt_len); - if (acx_debug & L_DATA) { + if (unlikely(acx_debug & L_DATA)) { printk("dump of bulk out urb:\n"); acx_dump_bytes(txbuf, wlanpkt_len + USB_TXBUF_HDRSIZE); } @@ -1474,8 +1494,8 @@ acxusb_l_tx_data(wlandevice_t *priv, tx_ } /* now schedule the USB transfer */ - usbdev = priv->usbdev; - outpipe = usb_sndbulkpipe(usbdev, priv->bulkoutep); + usbdev = adev->usbdev; + outpipe = usb_sndbulkpipe(usbdev, adev->bulkoutep); usb_fill_bulk_urb(txurb, usbdev, outpipe, txbuf, /* dataptr */ @@ -1497,10 +1517,10 @@ acxusb_l_tx_data(wlandevice_t *priv, tx_ /* on error, just mark the frame as done and update ** the statistics */ - priv->stats.tx_errors++; + adev->stats.tx_errors++; tx->busy = 0; - priv->tx_free++; - /* needed? if (priv->tx_free > TX_START_QUEUE) acx_wake_queue(...) */ + adev->tx_free++; + /* needed? if (adev->tx_free > TX_START_QUEUE) acx_wake_queue(...) */ } end: FN_EXIT0; @@ -1510,7 +1530,7 @@ end: /*********************************************************************** */ static void -acxusb_i_set_rx_mode(struct net_device *dev) +acxusb_i_set_rx_mode(struct net_device *ndev) { } @@ -1519,23 +1539,23 @@ acxusb_i_set_rx_mode(struct net_device * */ #ifdef HAVE_TX_TIMEOUT static void -acxusb_i_tx_timeout(struct net_device *dev) +acxusb_i_tx_timeout(struct net_device *ndev) { - wlandevice_t *priv = netdev_priv(dev); + acx_device_t *adev = ndev2adev(ndev); unsigned long flags; int i; FN_ENTER; - acx_lock(priv, flags); + acx_lock(adev, flags); /* unlink the URBs */ for (i = 0; i < ACX_TX_URB_CNT; i++) { - acxusb_unlink_urb(priv->usb_tx[i].urb); - priv->usb_tx[i].busy = 0; + acxusb_unlink_urb(adev->usb_tx[i].urb); + adev->usb_tx[i].busy = 0; } - priv->tx_free = ACX_TX_URB_CNT; + adev->tx_free = ACX_TX_URB_CNT; /* TODO: stats update */ - acx_unlock(priv, flags); + acx_unlock(adev, flags); FN_EXIT0; } @@ -1591,13 +1611,6 @@ dump_device(struct usb_device *usbdev) printk(" tt: 0x%X\n", (unsigned int)(usbdev->tt)); printk(" ttport: %d\n", (unsigned int)(usbdev->ttport)); printk(" toggle[0]: 0x%X toggle[1]: 0x%X\n", (unsigned int)(usbdev->toggle[0]), (unsigned int)(usbdev->toggle[1])); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 8) - /* halted removed in 2.6.9-rc1 */ - /* DOH, Canbreak... err... Mandrake decided to do their very own very - * special version "2.6.8.1" which already includes this change, so we - * need to blacklist that version already (i.e. 2.6.8) */ - printk(" halted[0]: 0x%X halted[1]: 0x%X\n", usbdev->halted[0], usbdev->halted[1]); -#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) /* This saw a change after 2.6.10 */ printk(" ep_in wMaxPacketSize: "); @@ -1605,7 +1618,7 @@ dump_device(struct usb_device *usbdev) printk("%d ", usbdev->ep_in[i]->desc.wMaxPacketSize); printk("\n"); printk(" ep_out wMaxPacketSize: "); - for (i = 0; i < 15; ++i) + for (i = 0; i < VEC_SIZE(usbdev->ep_out); ++i) printk("%d ", usbdev->ep_out[i]->desc.wMaxPacketSize); printk("\n"); #else @@ -1620,7 +1633,7 @@ dump_device(struct usb_device *usbdev) #endif printk(" parent: 0x%X\n", (unsigned int)usbdev->parent); printk(" bus: 0x%X\n", (unsigned int)usbdev->bus); -#if NO_DATATYPE +#ifdef NO_DATATYPE printk(" configs: "); for (i = 0; i < usbdev->descriptor.bNumConfigurations; i++) printk("0x%X ", usbdev->config[i]); diff -puN drivers/net/wireless/tiacx/wlan.c~update-mm-acx-driver-to-version-0331 drivers/net/wireless/tiacx/wlan.c --- devel/drivers/net/wireless/tiacx/wlan.c~update-mm-acx-driver-to-version-0331 2006-01-31 18:11:09.000000000 -0800 +++ devel-akpm/drivers/net/wireless/tiacx/wlan.c 2006-01-31 18:11:09.000000000 -0800 @@ -39,13 +39,10 @@ #include #include - #include #include #include -#if WIRELESS_EXT >= 13 #include -#endif #include "acx.h" @@ -124,8 +121,13 @@ wlan_mgmt_decode_beacon(wlan_fr_beacon_t case WLAN_EID_ERP_INFO: f->erp = (wlan_ie_erp_t *) ie_ptr; break; + case WLAN_EID_COUNTRY: /* was seen: 07 06 47 42 20 01 0D 14 */ + case WLAN_EID_PWR_CONSTRAINT: + /* was seen by Ashwin Mansinghka from + Atheros-based PCI card in AP mode using madwifi drivers: */ + /* 20 01 00 */ case WLAN_EID_NONERP: /* was seen from WRT54GS with OpenWrt: 2F 01 07 */ case WLAN_EID_UNKNOWN128: @@ -135,7 +137,6 @@ wlan_mgmt_decode_beacon(wlan_fr_beacon_t /* was seen by David Bronaugh from ???? */ /* 85 1E 00 00 84 12 07 00 FF 00 11 00 61 70 63 31 */ /* 63 73 72 30 34 32 00 00 00 00 00 00 00 00 00 25 */ - case WLAN_EID_UNKNOWN223: /* was seen by Carlos Martin from ???? */ /* DF 20 01 1E 04 00 00 00 06 63 09 02 FF 0F 30 30 */ @@ -158,6 +159,7 @@ wlan_mgmt_decode_beacon(wlan_fr_beacon_t rsn_len = pos[1] + 2; */ break; + default: LOG_BAD_EID(f->hdr, f->len, ie_ptr); break; @@ -239,6 +241,7 @@ wlan_mgmt_decode_assocresp(wlan_fr_assoc } +#ifdef UNUSED void wlan_mgmt_decode_reassocreq(wlan_fr_reassocreq_t * f) { @@ -320,6 +323,7 @@ wlan_mgmt_decode_probereq(wlan_fr_prober ie_ptr = ie_ptr + 2 + IE_LEN(ie_ptr); } } +#endif /* UNUSED */ /* TODO: decoding of beacon and proberesp can be merged (similar structure) */ @@ -366,6 +370,15 @@ wlan_mgmt_decode_proberesp(wlan_fr_probe break; ... #endif +#ifdef SENT_HERE_BY_OPENWRT + /* should those be trapped or handled?? */ + case WLAN_EID_ERP_INFO: + break; + case WLAN_EID_NONERP: + break; + case WLAN_EID_GENERIC: + break; +#endif default: LOG_BAD_EID(f->hdr, f->len, ie_ptr); break; diff -puN drivers/net/wireless/tiacx/wlan_compat.h~update-mm-acx-driver-to-version-0331 drivers/net/wireless/tiacx/wlan_compat.h --- devel/drivers/net/wireless/tiacx/wlan_compat.h~update-mm-acx-driver-to-version-0331 2006-01-31 18:11:09.000000000 -0800 +++ devel-akpm/drivers/net/wireless/tiacx/wlan_compat.h 2006-01-31 18:11:09.000000000 -0800 @@ -219,24 +219,6 @@ #define __WLAN_PRAGMA_PACK1__ #define __WLAN_PRAGMA_PACKDFLT__ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38)) - typedef struct device netdevice_t; -#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4)) - typedef struct net_device netdevice_t; -#else - #undef netdevice_t - typedef struct net_device netdevice_t; -#endif - -#ifdef WIRELESS_EXT -#if (WIRELESS_EXT < 13) -struct iw_request_info { - __u16 cmd; /* Wireless Extension command */ - __u16 flags; /* More to come ;-) */ -}; -#endif -#endif - /* Interrupt handler backwards compatibility stuff */ #ifndef IRQ_NONE #define IRQ_NONE @@ -244,33 +226,16 @@ struct iw_request_info { typedef void irqreturn_t; #endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,41) /* more or less */ -#define WLAN_MOD_INC_USE_COUNT MOD_INC_USE_COUNT -#define WLAN_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT -#else -#define WLAN_MOD_INC_USE_COUNT -#define WLAN_MOD_DEC_USE_COUNT -#endif - #ifndef ARPHRD_IEEE80211_PRISM #define ARPHRD_IEEE80211_PRISM 802 #endif -#define ETH_P_80211_RAW (ETH_P_ECONET + 1) +#define ETH_P_80211_RAW (ETH_P_ECONET + 1) /*============================================================================* * Constants * *============================================================================*/ -#define WLAN_IEEE_OUI_LEN 3 -/* unused -#define WLAN_ETHHDR_LEN 14 -#define WLAN_ETHCONV_ENCAP 1 -#define WLAN_ETHCONV_RFC1042 2 -#define WLAN_ETHCONV_8021h 3 -#define WLAN_MIN_ETHFRM_LEN 60 -#define WLAN_MAX_ETHFRM_LEN 1514 -*/ +#define WLAN_IEEE_OUI_LEN 3 /*============================================================================* * Types * diff -puN drivers/net/wireless/tiacx/wlan_mgmt.h~update-mm-acx-driver-to-version-0331 drivers/net/wireless/tiacx/wlan_mgmt.h --- devel/drivers/net/wireless/tiacx/wlan_mgmt.h~update-mm-acx-driver-to-version-0331 2006-01-31 18:11:09.000000000 -0800 +++ devel-akpm/drivers/net/wireless/tiacx/wlan_mgmt.h 2006-01-31 18:11:09.000000000 -0800 @@ -56,26 +56,26 @@ /*-- values 11-15 reserved --*/ #define WLAN_EID_CHALLENGE 16 /*-- values 17-31 reserved for challenge text extension --*/ -#define WLAN_EID_ERP_INFO 42 +#define WLAN_EID_PWR_CONSTRAINT 32 /* 11h PowerConstraint */ +#define WLAN_EID_ERP_INFO 42 /* was seen from WRT54GS with OpenWrt */ #define WLAN_EID_NONERP 47 /* was seen from WRT54GS with OpenWrt */ #define WLAN_EID_RSN 48 #define WLAN_EID_EXT_RATES 50 #define WLAN_EID_UNKNOWN128 128 #define WLAN_EID_UNKNOWN133 133 -#define WLAN_EID_GENERIC 221 +#define WLAN_EID_GENERIC 221 /* was seen from WRT54GS with OpenWrt */ #define WLAN_EID_UNKNOWN223 223 #if 0 -#define WLAN_EID_PWR_CONSTRAINT 32 /* 11H PowerConstraint */ -#define WLAN_EID_PWR_CAP 33 /* 11H PowerCapability */ -#define WLAN_EID_TPC_REQUEST 34 /* 11H TPC Request */ -#define WLAN_EID_TPC_REPORT 35 /* 11H TPC Report */ -#define WLAN_EID_SUPP_CHANNELS 36 /* 11H Supported Channels */ -#define WLAN_EID_CHANNEL_SWITCH 37 /* 11H ChannelSwitch */ -#define WLAN_EID_MEASURE_REQUEST 38 /* 11H MeasurementRequest */ -#define WLAN_EID_MEASURE_REPORT 39 /* 11H MeasurementReport */ -#define WLAN_EID_QUIET_ID 40 /* 11H Quiet */ -#define WLAN_EID_IBSS_DFS_ID 41 /* 11H IBSS_DFS */ +#define WLAN_EID_PWR_CAP 33 /* 11h PowerCapability */ +#define WLAN_EID_TPC_REQUEST 34 /* 11h TPC Request */ +#define WLAN_EID_TPC_REPORT 35 /* 11h TPC Report */ +#define WLAN_EID_SUPP_CHANNELS 36 /* 11h Supported Channels */ +#define WLAN_EID_CHANNEL_SWITCH 37 /* 11h ChannelSwitch */ +#define WLAN_EID_MEASURE_REQUEST 38 /* 11h MeasurementRequest */ +#define WLAN_EID_MEASURE_REPORT 39 /* 11h MeasurementReport */ +#define WLAN_EID_QUIET_ID 40 /* 11h Quiet */ +#define WLAN_EID_IBSS_DFS_ID 41 /* 11h IBSS_DFS */ #endif /*-- Reason Codes -------------------------------*/ _