aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/scripts/python/export-to-sqlite.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/scripts/python/export-to-sqlite.py')
0 files changed, 0 insertions, 0 deletions
pgm The LITMUS^RT kernel.Bjoern Brandenburg
aboutsummaryrefslogblamecommitdiffstats
path: root/drivers/net/wireless/rndis_wlan.c
blob: 828dc1825bba1da9afa3532a76330bb230410302 (plain) (tree)
1
2
3
4
5



                                                       
                                                                        

































                                                                            
                            



                           
                         















































                                                                            








                                                                       



























                                                                       









                                                                                



                        
   



                                          


                                                     

                                                                       








                                                                
                          



                                   


                           


                                     


                           







                                    


                             







                                        


                             

                                   

  

















                                                  
                             



                                                                   


                             

                                                               

  




























                                                                          
                        

                                          

                          
                                 



                           

                          
                        




                                                  

                          
                            











                                              

                          
                                 

                                            

                          
                             


                               

                          
                           



                        

                          
                       






                        

                          
                              


                     
                      

                          
                          




                            

                          



















                                       
                                                   




                                                                       









                                 
 


                                      
 

                                                                                































                                                                   








                            
                               
                           

                              

                                 

                                                   

                                           
                                      




                                   



                                                                      


                                       















                                       
                                     


                               
                                                






                              

                                               

  


               

                                                               


                                                                             


                                                                  

                                                                    



                                                                              
                                               
                                                         
                           
                                                   

                                           
  
 
                                                      
 





                                                                           
                                                                         
 
                                                             


 
                                                                 
 










                                                       


 








                                                                





























































                                                            

























                                                                                
                                                                   










                                                










                                                    

                                          
                                                    

                         
                                                   




                                                                              




                                                                             




                                                                           

         



                                          





                                                                             
                                                                   










                                                









                                                    





                                                           

                                                        

                                                  
                                                   





                                                                            

                                                          





                                                                                



                                          



                   





















                                                                        







                                                                            
                                          

































                                                                      




                                                                        




























                                                                           
                                                                               



















































                                                                         

                                                                                
















                                             
                                                
 
                                                                         






                                                                   
                                 




                                                               

                                                                    






                                                                     
                                                                         
 
                                                                      

























                                                                          





                                                                          













                                                                     
                                                                      
                                    















                                                                              





                                                                            







                                                                             
                                                                      







                                                                         
                                                         
                    
                                                             

                                                                
                                                        
                                                                  
                                                            
                    
                                                             

                                                      
                                                                
                    
                                                           
              
                                                 
















                                                                             
                                                                      





                                                                               
                                                             
            
                                                              







                                                                             
                                                                      







                                                                           
                                                         
                                                
                                                         

                                                                
                                                        
                                                 
                                                         
                                                 
                                                         
            
                                                     
















                                                                             
                                                                      










                                                                             
                                                                      
                   
                













                                                                             
                             





                                





























                                                                              

                                                        
                                                                      



                              
                                                       



















                                                                                
                                                                      
                                           
                        
 
                                                                      

                               




                                                  

                                               



                                                      

                                               
                                                                 














                                                                                



                                                               




                 
                                                                         

                                                                                
 
                                                                      
                                       
                        

                

                                                                              
                               



                                                                           
                               


                                                                            
                               





                                                                               
                               
         

                                                              


                                                                         







                                                                     
                                                                







                                                                             
                                                        

                                                
                                                     
                                  
                                                       

                               
                                                               










                                                                       







                                                                                
 
                                                   





                                                















































                                                                             


                                                                           
                                                                      
                                                
                        
                    

                
                                            

                         
                                         
 





                                                                             

                                                                  


                                                                     
                                                   
                                                                       

                                                                  
                      

                                                                          


























                                                                                
                                                                      

























































                                                                               

               

                                                               


                                                                             
                                                 

                 

                                  
                                              

                                    
                                              







                                            
 





















                                                                        



































                                                                               




                                                                  
                                                                      




























                                                                          
                                                                      



















































































                                                                            

                                                                              




                                             


                                







                                                        
  










                                                                      


                                                                      
                                    
                                        
                                                 






                                                                 
                                          
                       
                                                  
            
                                                               












                                                                      
                                    
                                                 



                                       
                                                       
                                      

                                                              













                                                                      
                                                 

                                      



                                       
                                                        












                                                                      
                                                 
                                                

                
                                                
















                                                                             
                                                 
                                                                      














































































                                                                                
                                                 
                                                                      

























                                                                   


                                                                      
                                                 
                                                                      
                                       
                                
                   

































                                                                             
                               

                                           
                                                    
                                       
                                             

                                      


                                                
                                                             













                                                                          
                                                 
                                                                      
                                  








                                                        

                                                                              
                               
         






                                                                           





                                                



                                                                


                                   

                                                        
                                                             
                                                        
                                                        
                                                      
                                                        
 


                                                                              


 


                                                                      
                                                 
                                                                      































                                                                        
                                                 
                                                                      

















                                                            


                                                                      
                                                 
                                      

















                                                                               
                                                 









                                                                                
                                                 
                                      




                                                                               
                                                                             





                                                        


                                                                      
                                                 
















                                                                      
                                                 
                                                                      






















                                                                             
                                                 
                                                                      













                                                                        
                                                                        

                                                       

                                                                        
                                                                         

                                                        

                                                                        

                                                        
                                                       



                                                                        

                                                                           








                                                             
                                                        

  
                                                              




                                                        

                                                                
                                                   

                                                                       



                                                       
                                                       
 

                                                                    


                                             


                                                            
 
                                                                    

                                              


                                                       
 





















                                                                             
 

                                               







                                                                                
                                                                      

                                               





                                                                        



                                                                             
                                                                 
 
                                                 
                                                                      
 


                                                                   



                                                              


















































































































































































                                                                                
                                                                               
 
                                                                      
                                         
 



                                                 
                                                                            






                                                           
                                                                            



                                                             



                                                                          




                                                          


 
                                                     





                                  
                                                                      
 

                                         
                                                                            






                                                                           

                                                        

                                                              
                                                    

                                                              
                                                    



                                                              








                                                                 

                                                                               


                                             
                        



























                                                                           
                                                                      





















                                                                         



                                                                            













                                                                            
                                     



























                                                                               










                                                                      
 
                                                                      














                                                                         











                                                                 




                                              









                                               
                                             
                                                      

                                                                               
 

                                                                               
                                                                            
                                                             

                                                                             
                                                                     
                                                     
                                                              
                                                    
                                                                   
                                                  
                                                                 



                 
                                                               
                                                            





                                                    
                                                                

  
 
                                                                             
 
                            
                                        


                        



                                                                     
                                                                                
                   

                               




                                                   
                                                                            
                                                                        
           
                                   

                                                            



                                          

                                                                      
                                                  


                                                                          
                                 
                                                                            







                                                                        
                                                          
           
                                                         
 
                                                                       
                                                                           


                                                                             

                                                                           



                                                   
                                                    
            
                                                     








                                                                







                                                                    
                                    







                                                                       
                                                         



                                                 

                                 

         
                                      
 



                                                                                

                           

                                       
 


                 





                                                    
                          



                      
                                                                                
 
                                                                      

                            
                                

                                                    
                                                   





                                           
 
                                   


                                           


 
                                                  
 
                                                                      
                   
 
                                           
 



                                                                    

                                                                        

                                   


                                                              
                                      


 

                                                 

                                                                      
                      
 
                                          








                                                    




                                                             





                                                                                
                      


 

                                                                

                                                                      

                                          


                                       
                                         
                                        
                                            
                                              



                                                                

                                                                      

                                          


                                       
                                         
                                        
                                            
                                              

  
                                                   
                                                

                                                                      

                                          


                                       
                                         
                                        
                                            
                                              












































































































                                                                               
                                                        


                                                                           
                                                        






























                                                                   
/*
 * Driver for RNDIS based wireless USB devices.
 *
 * Copyright (C) 2007 by Bjorge Dijkstra <bjd@jooz.net>
 * Copyright (C) 2008-2009 by Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *  Portions of this file are based on NDISwrapper project,
 *  Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
 *  http://ndiswrapper.sourceforge.net/
 */

// #define	DEBUG			// error path messages, extra info
// #define	VERBOSE			// more; success messages

#include <linux/module.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/workqueue.h>
#include <linux/mutex.h>
#include <linux/mii.h>
#include <linux/usb.h>
#include <linux/usb/cdc.h>
#include <linux/wireless.h>
#include <linux/ieee80211.h>
#include <linux/if_arp.h>
#include <linux/ctype.h>
#include <linux/spinlock.h>
#include <net/iw_handler.h>
#include <net/cfg80211.h>
#include <linux/usb/usbnet.h>
#include <linux/usb/rndis_host.h>


/* NOTE: All these are settings for Broadcom chipset */
static char modparam_country[4] = "EU";
module_param_string(country, modparam_country, 4, 0444);
MODULE_PARM_DESC(country, "Country code (ISO 3166-1 alpha-2), default: EU");

static int modparam_frameburst = 1;
module_param_named(frameburst, modparam_frameburst, int, 0444);
MODULE_PARM_DESC(frameburst, "enable frame bursting (default: on)");

static int modparam_afterburner = 0;
module_param_named(afterburner, modparam_afterburner, int, 0444);
MODULE_PARM_DESC(afterburner,
	"enable afterburner aka '125 High Speed Mode' (default: off)");

static int modparam_power_save = 0;
module_param_named(power_save, modparam_power_save, int, 0444);
MODULE_PARM_DESC(power_save,
	"set power save mode: 0=off, 1=on, 2=fast (default: off)");

static int modparam_power_output = 3;
module_param_named(power_output, modparam_power_output, int, 0444);
MODULE_PARM_DESC(power_output,
	"set power output: 0=25%, 1=50%, 2=75%, 3=100% (default: 100%)");

static int modparam_roamtrigger = -70;
module_param_named(roamtrigger, modparam_roamtrigger, int, 0444);
MODULE_PARM_DESC(roamtrigger,
	"set roaming dBm trigger: -80=optimize for distance, "
				"-60=bandwidth (default: -70)");

static int modparam_roamdelta = 1;
module_param_named(roamdelta, modparam_roamdelta, int, 0444);
MODULE_PARM_DESC(roamdelta,
	"set roaming tendency: 0=aggressive, 1=moderate, "
				"2=conservative (default: moderate)");

static int modparam_workaround_interval = 500;
module_param_named(workaround_interval, modparam_workaround_interval,
							int, 0444);
MODULE_PARM_DESC(workaround_interval,
	"set stall workaround interval in msecs (default: 500)");


/* various RNDIS OID defs */
#define OID_GEN_LINK_SPEED			cpu_to_le32(0x00010107)
#define OID_GEN_RNDIS_CONFIG_PARAMETER		cpu_to_le32(0x0001021b)

#define OID_GEN_XMIT_OK				cpu_to_le32(0x00020101)
#define OID_GEN_RCV_OK				cpu_to_le32(0x00020102)
#define OID_GEN_XMIT_ERROR			cpu_to_le32(0x00020103)
#define OID_GEN_RCV_ERROR			cpu_to_le32(0x00020104)
#define OID_GEN_RCV_NO_BUFFER			cpu_to_le32(0x00020105)

#define OID_802_3_CURRENT_ADDRESS		cpu_to_le32(0x01010102)
#define OID_802_3_MULTICAST_LIST		cpu_to_le32(0x01010103)
#define OID_802_3_MAXIMUM_LIST_SIZE		cpu_to_le32(0x01010104)

#define OID_802_11_BSSID			cpu_to_le32(0x0d010101)
#define OID_802_11_SSID				cpu_to_le32(0x0d010102)
#define OID_802_11_INFRASTRUCTURE_MODE		cpu_to_le32(0x0d010108)
#define OID_802_11_ADD_WEP			cpu_to_le32(0x0d010113)
#define OID_802_11_REMOVE_WEP			cpu_to_le32(0x0d010114)
#define OID_802_11_DISASSOCIATE			cpu_to_le32(0x0d010115)
#define OID_802_11_AUTHENTICATION_MODE		cpu_to_le32(0x0d010118)
#define OID_802_11_PRIVACY_FILTER		cpu_to_le32(0x0d010119)
#define OID_802_11_BSSID_LIST_SCAN		cpu_to_le32(0x0d01011a)
#define OID_802_11_ENCRYPTION_STATUS		cpu_to_le32(0x0d01011b)
#define OID_802_11_ADD_KEY			cpu_to_le32(0x0d01011d)
#define OID_802_11_REMOVE_KEY			cpu_to_le32(0x0d01011e)
#define OID_802_11_ASSOCIATION_INFORMATION	cpu_to_le32(0x0d01011f)
#define OID_802_11_PMKID			cpu_to_le32(0x0d010123)
#define OID_802_11_NETWORK_TYPES_SUPPORTED	cpu_to_le32(0x0d010203)
#define OID_802_11_NETWORK_TYPE_IN_USE		cpu_to_le32(0x0d010204)
#define OID_802_11_TX_POWER_LEVEL		cpu_to_le32(0x0d010205)
#define OID_802_11_RSSI				cpu_to_le32(0x0d010206)
#define OID_802_11_RSSI_TRIGGER			cpu_to_le32(0x0d010207)
#define OID_802_11_FRAGMENTATION_THRESHOLD	cpu_to_le32(0x0d010209)
#define OID_802_11_RTS_THRESHOLD		cpu_to_le32(0x0d01020a)
#define OID_802_11_SUPPORTED_RATES		cpu_to_le32(0x0d01020e)
#define OID_802_11_CONFIGURATION		cpu_to_le32(0x0d010211)
#define OID_802_11_BSSID_LIST			cpu_to_le32(0x0d010217)


/* Typical noise/maximum signal level values taken from ndiswrapper iw_ndis.h */
#define	WL_NOISE	-96	/* typical noise level in dBm */
#define	WL_SIGMAX	-32	/* typical maximum signal level in dBm */


/* Assume that Broadcom 4320 (only chipset at time of writing known to be
 * based on wireless rndis) has default txpower of 13dBm.
 * This value is from Linksys WUSB54GSC User Guide, Appendix F: Specifications.
 *  100% : 20 mW ~ 13dBm
 *   75% : 15 mW ~ 12dBm
 *   50% : 10 mW ~ 10dBm
 *   25% :  5 mW ~  7dBm
 */
#define BCM4320_DEFAULT_TXPOWER_DBM_100 13
#define BCM4320_DEFAULT_TXPOWER_DBM_75  12
#define BCM4320_DEFAULT_TXPOWER_DBM_50  10
#define BCM4320_DEFAULT_TXPOWER_DBM_25  7


/* codes for "status" field of completion messages */
#define RNDIS_STATUS_ADAPTER_NOT_READY		cpu_to_le32(0xc0010011)
#define RNDIS_STATUS_ADAPTER_NOT_OPEN		cpu_to_le32(0xc0010012)


/* NDIS data structures. Taken from wpa_supplicant driver_ndis.c
 * slightly modified for datatype endianess, etc
 */
#define NDIS_802_11_LENGTH_SSID 32
#define NDIS_802_11_LENGTH_RATES 8
#define NDIS_802_11_LENGTH_RATES_EX 16

enum ndis_80211_net_type {
	NDIS_80211_TYPE_FREQ_HOP,
	NDIS_80211_TYPE_DIRECT_SEQ,
	NDIS_80211_TYPE_OFDM_A,
	NDIS_80211_TYPE_OFDM_G
};

enum ndis_80211_net_infra {
	NDIS_80211_INFRA_ADHOC,
	NDIS_80211_INFRA_INFRA,
	NDIS_80211_INFRA_AUTO_UNKNOWN
};

enum ndis_80211_auth_mode {
	NDIS_80211_AUTH_OPEN,
	NDIS_80211_AUTH_SHARED,
	NDIS_80211_AUTH_AUTO_SWITCH,
	NDIS_80211_AUTH_WPA,
	NDIS_80211_AUTH_WPA_PSK,
	NDIS_80211_AUTH_WPA_NONE,
	NDIS_80211_AUTH_WPA2,
	NDIS_80211_AUTH_WPA2_PSK
};

enum ndis_80211_encr_status {
	NDIS_80211_ENCR_WEP_ENABLED,
	NDIS_80211_ENCR_DISABLED,
	NDIS_80211_ENCR_WEP_KEY_ABSENT,
	NDIS_80211_ENCR_NOT_SUPPORTED,
	NDIS_80211_ENCR_TKIP_ENABLED,
	NDIS_80211_ENCR_TKIP_KEY_ABSENT,
	NDIS_80211_ENCR_CCMP_ENABLED,
	NDIS_80211_ENCR_CCMP_KEY_ABSENT
};

enum ndis_80211_priv_filter {
	NDIS_80211_PRIV_ACCEPT_ALL,
	NDIS_80211_PRIV_8021X_WEP
};

enum ndis_80211_status_type {
	NDIS_80211_STATUSTYPE_AUTHENTICATION,
	NDIS_80211_STATUSTYPE_MEDIASTREAMMODE,
	NDIS_80211_STATUSTYPE_PMKID_CANDIDATELIST,
	NDIS_80211_STATUSTYPE_RADIOSTATE,
};

enum ndis_80211_media_stream_mode {
	NDIS_80211_MEDIA_STREAM_OFF,
	NDIS_80211_MEDIA_STREAM_ON
};

enum ndis_80211_radio_status {
	NDIS_80211_RADIO_STATUS_ON,
	NDIS_80211_RADIO_STATUS_HARDWARE_OFF,
	NDIS_80211_RADIO_STATUS_SOFTWARE_OFF,
};

enum ndis_80211_addkey_bits {
	NDIS_80211_ADDKEY_8021X_AUTH = cpu_to_le32(1 << 28),
	NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ = cpu_to_le32(1 << 29),
	NDIS_80211_ADDKEY_PAIRWISE_KEY = cpu_to_le32(1 << 30),
	NDIS_80211_ADDKEY_TRANSMIT_KEY = cpu_to_le32(1 << 31)
};

enum ndis_80211_addwep_bits {
	NDIS_80211_ADDWEP_PERCLIENT_KEY = cpu_to_le32(1 << 30),
	NDIS_80211_ADDWEP_TRANSMIT_KEY = cpu_to_le32(1 << 31)
};

struct ndis_80211_auth_request {
	__le32 length;
	u8 bssid[6];
	u8 padding[2];
	__le32 flags;
} __attribute__((packed));

struct ndis_80211_pmkid_candidate {
	u8 bssid[6];
	u8 padding[2];
	__le32 flags;
} __attribute__((packed));

struct ndis_80211_pmkid_cand_list {
	__le32 version;
	__le32 num_candidates;
	struct ndis_80211_pmkid_candidate candidate_list[0];
} __attribute__((packed));

struct ndis_80211_status_indication {
	__le32 status_type;
	union {
		enum ndis_80211_media_stream_mode	media_stream_mode;
		enum ndis_80211_radio_status		radio_status;
		struct ndis_80211_auth_request		auth_request[0];
		struct ndis_80211_pmkid_cand_list	cand_list;
	} u;
} __attribute__((packed));

struct ndis_80211_ssid {
	__le32 length;
	u8 essid[NDIS_802_11_LENGTH_SSID];
} __attribute__((packed));

struct ndis_80211_conf_freq_hop {
	__le32 length;
	__le32 hop_pattern;
	__le32 hop_set;
	__le32 dwell_time;
} __attribute__((packed));

struct ndis_80211_conf {
	__le32 length;
	__le32 beacon_period;
	__le32 atim_window;
	__le32 ds_config;
	struct ndis_80211_conf_freq_hop fh_config;
} __attribute__((packed));

struct ndis_80211_bssid_ex {
	__le32 length;
	u8 mac[6];
	u8 padding[2];
	struct ndis_80211_ssid ssid;
	__le32 privacy;
	__le32 rssi;
	__le32 net_type;
	struct ndis_80211_conf config;
	__le32 net_infra;
	u8 rates[NDIS_802_11_LENGTH_RATES_EX];
	__le32 ie_length;
	u8 ies[0];
} __attribute__((packed));

struct ndis_80211_bssid_list_ex {
	__le32 num_items;
	struct ndis_80211_bssid_ex bssid[0];
} __attribute__((packed));

struct ndis_80211_fixed_ies {
	u8 timestamp[8];
	__le16 beacon_interval;
	__le16 capabilities;
} __attribute__((packed));

struct ndis_80211_wep_key {
	__le32 size;
	__le32 index;
	__le32 length;
	u8 material[32];
} __attribute__((packed));

struct ndis_80211_key {
	__le32 size;
	__le32 index;
	__le32 length;
	u8 bssid[6];
	u8 padding[6];
	u8 rsc[8];
	u8 material[32];
} __attribute__((packed));

struct ndis_80211_remove_key {
	__le32 size;
	__le32 index;
	u8 bssid[6];
	u8 padding[2];
} __attribute__((packed));

struct ndis_config_param {
	__le32 name_offs;
	__le32 name_length;
	__le32 type;
	__le32 value_offs;
	__le32 value_length;
} __attribute__((packed));

struct ndis_80211_assoc_info {
	__le32 length;
	__le16 req_ies;
	struct req_ie {
		__le16 capa;
		__le16 listen_interval;
		u8 cur_ap_address[6];
	} req_ie;
	__le32 req_ie_length;
	__le32 offset_req_ies;
	__le16 resp_ies;
	struct resp_ie {
		__le16 capa;
		__le16 status_code;
		__le16 assoc_id;
	} resp_ie;
	__le32 resp_ie_length;
	__le32 offset_resp_ies;
} __attribute__((packed));

/* these have to match what is in wpa_supplicant */
enum wpa_alg { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP };
enum wpa_cipher { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP,
		  CIPHER_WEP104 };
enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE,
		    KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE };

/*
 *  private data
 */
#define NET_TYPE_11FB	0

#define CAP_MODE_80211A		1
#define CAP_MODE_80211B		2
#define CAP_MODE_80211G		4
#define CAP_MODE_MASK		7

#define WORK_LINK_UP		(1<<0)
#define WORK_LINK_DOWN		(1<<1)
#define WORK_SET_MULTICAST_LIST	(1<<2)

#define COMMAND_BUFFER_SIZE	(CONTROL_BUFFER_SIZE + sizeof(struct rndis_set))

static const struct ieee80211_channel rndis_channels[] = {
	{ .center_freq = 2412 },
	{ .center_freq = 2417 },
	{ .center_freq = 2422 },
	{ .center_freq = 2427 },
	{ .center_freq = 2432 },
	{ .center_freq = 2437 },
	{ .center_freq = 2442 },
	{ .center_freq = 2447 },
	{ .center_freq = 2452 },
	{ .center_freq = 2457 },
	{ .center_freq = 2462 },
	{ .center_freq = 2467 },
	{ .center_freq = 2472 },
	{ .center_freq = 2484 },
};

static const struct ieee80211_rate rndis_rates[] = {
	{ .bitrate = 10 },
	{ .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 60 },
	{ .bitrate = 90 },
	{ .bitrate = 120 },
	{ .bitrate = 180 },
	{ .bitrate = 240 },
	{ .bitrate = 360 },
	{ .bitrate = 480 },
	{ .bitrate = 540 }
};

struct rndis_wlan_encr_key {
	int len;
	int cipher;
	u8 material[32];
	u8 bssid[ETH_ALEN];
	bool pairwise;
	bool tx_key;
};

/* RNDIS device private data */
struct rndis_wlan_private {
	struct usbnet *usbdev;

	struct wireless_dev wdev;

	struct cfg80211_scan_request *scan_request;

	struct workqueue_struct *workqueue;
	struct delayed_work stats_work;
	struct delayed_work scan_work;
	struct work_struct work;
	struct mutex command_lock;
	spinlock_t stats_lock;
	unsigned long work_pending;

	struct ieee80211_supported_band band;
	struct ieee80211_channel channels[ARRAY_SIZE(rndis_channels)];
	struct ieee80211_rate rates[ARRAY_SIZE(rndis_rates)];

	struct iw_statistics iwstats;
	struct iw_statistics privstats;

	int caps;
	int multicast_size;

	/* module parameters */
	char param_country[4];
	int  param_frameburst;
	int  param_afterburner;
	int  param_power_save;
	int  param_power_output;
	int  param_roamtrigger;
	int  param_roamdelta;
	u32  param_workaround_interval;

	/* hardware state */
	int radio_on;
	int infra_mode;
	struct ndis_80211_ssid essid;

	/* encryption stuff */
	int  encr_tx_key_index;
	struct rndis_wlan_encr_key encr_keys[4];
	int  wpa_version;
	int  wpa_keymgmt;
	int  wpa_authalg;
	int  wpa_ie_len;
	u8  *wpa_ie;
	int  wpa_cipher_pair;
	int  wpa_cipher_group;

	u8 command_buffer[COMMAND_BUFFER_SIZE];
};

/*
 * cfg80211 ops
 */
static int rndis_change_virtual_intf(struct wiphy *wiphy,
					struct net_device *dev,
					enum nl80211_iftype type, u32 *flags,
					struct vif_params *params);

static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
			struct cfg80211_scan_request *request);

static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed);

static int rndis_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type,
				int dbm);
static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm);

static struct cfg80211_ops rndis_config_ops = {
	.change_virtual_intf = rndis_change_virtual_intf,
	.scan = rndis_scan,
	.set_wiphy_params = rndis_set_wiphy_params,
	.set_tx_power = rndis_set_tx_power,
	.get_tx_power = rndis_get_tx_power,
};

static void *rndis_wiphy_privid = &rndis_wiphy_privid;


static const unsigned char zero_bssid[ETH_ALEN] = {0,};
static const unsigned char ffff_bssid[ETH_ALEN] = { 0xff, 0xff, 0xff,
							0xff, 0xff, 0xff };


static struct rndis_wlan_private *get_rndis_wlan_priv(struct usbnet *dev)
{
	return (struct rndis_wlan_private *)dev->driver_priv;
}


static u32 get_bcm4320_power_dbm(struct rndis_wlan_private *priv)
{
	switch (priv->param_power_output) {
	default:
	case 3:
		return BCM4320_DEFAULT_TXPOWER_DBM_100;
	case 2:
		return BCM4320_DEFAULT_TXPOWER_DBM_75;
	case 1:
		return BCM4320_DEFAULT_TXPOWER_DBM_50;
	case 0:
		return BCM4320_DEFAULT_TXPOWER_DBM_25;
	}
}


static bool is_wpa_key(struct rndis_wlan_private *priv, int idx)
{
	int cipher = priv->encr_keys[idx].cipher;

	return (cipher == WLAN_CIPHER_SUITE_CCMP ||
		cipher == WLAN_CIPHER_SUITE_TKIP);
}


#ifdef DEBUG
static const char *oid_to_string(__le32 oid)
{
	switch (oid) {
#define OID_STR(oid) case oid: return(#oid)
		/* from rndis_host.h */
		OID_STR(OID_802_3_PERMANENT_ADDRESS);
		OID_STR(OID_GEN_MAXIMUM_FRAME_SIZE);
		OID_STR(OID_GEN_CURRENT_PACKET_FILTER);
		OID_STR(OID_GEN_PHYSICAL_MEDIUM);

		/* from rndis_wlan.c */
		OID_STR(OID_GEN_LINK_SPEED);
		OID_STR(OID_GEN_RNDIS_CONFIG_PARAMETER);

		OID_STR(OID_GEN_XMIT_OK);
		OID_STR(OID_GEN_RCV_OK);
		OID_STR(OID_GEN_XMIT_ERROR);
		OID_STR(OID_GEN_RCV_ERROR);
		OID_STR(OID_GEN_RCV_NO_BUFFER);

		OID_STR(OID_802_3_CURRENT_ADDRESS);
		OID_STR(OID_802_3_MULTICAST_LIST);
		OID_STR(OID_802_3_MAXIMUM_LIST_SIZE);

		OID_STR(OID_802_11_BSSID);
		OID_STR(OID_802_11_SSID);
		OID_STR(OID_802_11_INFRASTRUCTURE_MODE);
		OID_STR(OID_802_11_ADD_WEP);
		OID_STR(OID_802_11_REMOVE_WEP);
		OID_STR(OID_802_11_DISASSOCIATE);
		OID_STR(OID_802_11_AUTHENTICATION_MODE);
		OID_STR(OID_802_11_PRIVACY_FILTER);
		OID_STR(OID_802_11_BSSID_LIST_SCAN);
		OID_STR(OID_802_11_ENCRYPTION_STATUS);
		OID_STR(OID_802_11_ADD_KEY);
		OID_STR(OID_802_11_REMOVE_KEY);
		OID_STR(OID_802_11_ASSOCIATION_INFORMATION);
		OID_STR(OID_802_11_PMKID);
		OID_STR(OID_802_11_NETWORK_TYPES_SUPPORTED);
		OID_STR(OID_802_11_NETWORK_TYPE_IN_USE);
		OID_STR(OID_802_11_TX_POWER_LEVEL);
		OID_STR(OID_802_11_RSSI);
		OID_STR(OID_802_11_RSSI_TRIGGER);
		OID_STR(OID_802_11_FRAGMENTATION_THRESHOLD);
		OID_STR(OID_802_11_RTS_THRESHOLD);
		OID_STR(OID_802_11_SUPPORTED_RATES);
		OID_STR(OID_802_11_CONFIGURATION);
		OID_STR(OID_802_11_BSSID_LIST);
#undef OID_STR
	}

	return "?";
}
#else
static const char *oid_to_string(__le32 oid)
{
	return "?";
}
#endif


/* translate error code */
static int rndis_error_status(__le32 rndis_status)
{
	int ret = -EINVAL;
	switch (rndis_status) {
	case RNDIS_STATUS_SUCCESS:
		ret = 0;
		break;
	case RNDIS_STATUS_FAILURE:
	case RNDIS_STATUS_INVALID_DATA:
		ret = -EINVAL;
		break;
	case RNDIS_STATUS_NOT_SUPPORTED:
		ret = -EOPNOTSUPP;
		break;
	case RNDIS_STATUS_ADAPTER_NOT_READY:
	case RNDIS_STATUS_ADAPTER_NOT_OPEN:
		ret = -EBUSY;
		break;
	}
	return ret;
}


static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
{
	struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev);
	union {
		void			*buf;
		struct rndis_msg_hdr	*header;
		struct rndis_query	*get;
		struct rndis_query_c	*get_c;
	} u;
	int ret, buflen;

	buflen = *len + sizeof(*u.get);
	if (buflen < CONTROL_BUFFER_SIZE)
		buflen = CONTROL_BUFFER_SIZE;

	if (buflen > COMMAND_BUFFER_SIZE) {
		u.buf = kmalloc(buflen, GFP_KERNEL);
		if (!u.buf)
			return -ENOMEM;
	} else {
		u.buf = priv->command_buffer;
	}

	mutex_lock(&priv->command_lock);

	memset(u.get, 0, sizeof *u.get);
	u.get->msg_type = RNDIS_MSG_QUERY;
	u.get->msg_len = cpu_to_le32(sizeof *u.get);
	u.get->oid = oid;

	ret = rndis_command(dev, u.header, buflen);
	if (ret < 0)
		devdbg(dev, "rndis_query_oid(%s): rndis_command() failed, %d "
			"(%08x)", oid_to_string(oid), ret,
			le32_to_cpu(u.get_c->status));

	if (ret == 0) {
		ret = le32_to_cpu(u.get_c->len);
		*len = (*len > ret) ? ret : *len;
		memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len);
		ret = rndis_error_status(u.get_c->status);

		if (ret < 0)
			devdbg(dev, "rndis_query_oid(%s): device returned "
				"error,  0x%08x (%d)", oid_to_string(oid),
				le32_to_cpu(u.get_c->status), ret);
	}

	mutex_unlock(&priv->command_lock);

	if (u.buf != priv->command_buffer)
		kfree(u.buf);
	return ret;
}


static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
{
	struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev);
	union {
		void			*buf;
		struct rndis_msg_hdr	*header;
		struct rndis_set	*set;
		struct rndis_set_c	*set_c;
	} u;
	int ret, buflen;

	buflen = len + sizeof(*u.set);
	if (buflen < CONTROL_BUFFER_SIZE)
		buflen = CONTROL_BUFFER_SIZE;

	if (buflen > COMMAND_BUFFER_SIZE) {
		u.buf = kmalloc(buflen, GFP_KERNEL);
		if (!u.buf)
			return -ENOMEM;
	} else {
		u.buf = priv->command_buffer;
	}

	mutex_lock(&priv->command_lock);

	memset(u.set, 0, sizeof *u.set);
	u.set->msg_type = RNDIS_MSG_SET;
	u.set->msg_len = cpu_to_le32(sizeof(*u.set) + len);
	u.set->oid = oid;
	u.set->len = cpu_to_le32(len);
	u.set->offset = cpu_to_le32(sizeof(*u.set) - 8);
	u.set->handle = cpu_to_le32(0);
	memcpy(u.buf + sizeof(*u.set), data, len);

	ret = rndis_command(dev, u.header, buflen);
	if (ret < 0)
		devdbg(dev, "rndis_set_oid(%s): rndis_command() failed, %d "
			"(%08x)", oid_to_string(oid), ret,
			le32_to_cpu(u.set_c->status));

	if (ret == 0) {
		ret = rndis_error_status(u.set_c->status);

		if (ret < 0)
			devdbg(dev, "rndis_set_oid(%s): device returned error, "
				"0x%08x (%d)", oid_to_string(oid),
				le32_to_cpu(u.set_c->status), ret);
	}

	mutex_unlock(&priv->command_lock);

	if (u.buf != priv->command_buffer)
		kfree(u.buf);
	return ret;
}


static int rndis_reset(struct usbnet *usbdev)
{
	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
	struct rndis_reset *reset;
	int ret;

	mutex_lock(&priv->command_lock);

	reset = (void *)priv->command_buffer;
	memset(reset, 0, sizeof(*reset));
	reset->msg_type = RNDIS_MSG_RESET;
	reset->msg_len = cpu_to_le32(sizeof(*reset));
	ret = rndis_command(usbdev, (void *)reset, CONTROL_BUFFER_SIZE);

	mutex_unlock(&priv->command_lock);

	if (ret < 0)
		return ret;
	return 0;
}


/*
 * Specs say that we can only set config parameters only soon after device
 * initialization.
 *   value_type: 0 = u32, 2 = unicode string
 */
static int rndis_set_config_parameter(struct usbnet *dev, char *param,
						int value_type, void *value)
{