| 
									
										
										
										
											2013-05-24 20:04:38 -04:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Common private data for ST-Ericsson CW1200 drivers | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (c) 2010, ST-Ericsson | 
					
						
							|  |  |  |  * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Based on the mac80211 Prism54 code, which is | 
					
						
							|  |  |  |  * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Based on the islsm (softmac prism54) driver, which is: | 
					
						
							|  |  |  |  * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU General Public License version 2 as | 
					
						
							|  |  |  |  * published by the Free Software Foundation. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef CW1200_H
 | 
					
						
							|  |  |  | #define CW1200_H
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <linux/wait.h>
 | 
					
						
							|  |  |  | #include <linux/mutex.h>
 | 
					
						
							|  |  |  | #include <linux/workqueue.h>
 | 
					
						
							|  |  |  | #include <net/mac80211.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "queue.h"
 | 
					
						
							|  |  |  | #include "wsm.h"
 | 
					
						
							|  |  |  | #include "scan.h"
 | 
					
						
							|  |  |  | #include "txrx.h"
 | 
					
						
							|  |  |  | #include "pm.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Forward declarations */ | 
					
						
							| 
									
										
										
										
											2013-06-01 08:08:42 -04:00
										 |  |  | struct hwbus_ops; | 
					
						
							| 
									
										
										
										
											2013-05-24 20:04:38 -04:00
										 |  |  | struct task_struct; | 
					
						
							|  |  |  | struct cw1200_debug_priv; | 
					
						
							|  |  |  | struct firmware; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define CW1200_MAX_CTRL_FRAME_LEN	(0x1000)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define CW1200_MAX_STA_IN_AP_MODE	(5)
 | 
					
						
							|  |  |  | #define CW1200_LINK_ID_AFTER_DTIM	(CW1200_MAX_STA_IN_AP_MODE + 1)
 | 
					
						
							|  |  |  | #define CW1200_LINK_ID_UAPSD		(CW1200_MAX_STA_IN_AP_MODE + 2)
 | 
					
						
							|  |  |  | #define CW1200_LINK_ID_MAX		(CW1200_MAX_STA_IN_AP_MODE + 3)
 | 
					
						
							|  |  |  | #define CW1200_MAX_REQUEUE_ATTEMPTS	(5)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define CW1200_MAX_TID			(8)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define CW1200_BLOCK_ACK_CNT		(30)
 | 
					
						
							|  |  |  | #define CW1200_BLOCK_ACK_THLD		(800)
 | 
					
						
							|  |  |  | #define CW1200_BLOCK_ACK_HIST		(3)
 | 
					
						
							|  |  |  | #define CW1200_BLOCK_ACK_INTERVAL	(1 * HZ / CW1200_BLOCK_ACK_HIST)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define CW1200_JOIN_TIMEOUT		(1 * HZ)
 | 
					
						
							|  |  |  | #define CW1200_AUTH_TIMEOUT		(5 * HZ)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct cw1200_ht_info { | 
					
						
							|  |  |  | 	struct ieee80211_sta_ht_cap     ht_cap; | 
					
						
							|  |  |  | 	enum nl80211_channel_type       channel_type; | 
					
						
							|  |  |  | 	u16                             operation_mode; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Please keep order */ | 
					
						
							|  |  |  | enum cw1200_join_status { | 
					
						
							|  |  |  | 	CW1200_JOIN_STATUS_PASSIVE = 0, | 
					
						
							|  |  |  | 	CW1200_JOIN_STATUS_MONITOR, | 
					
						
							|  |  |  | 	CW1200_JOIN_STATUS_JOINING, | 
					
						
							|  |  |  | 	CW1200_JOIN_STATUS_PRE_STA, | 
					
						
							|  |  |  | 	CW1200_JOIN_STATUS_STA, | 
					
						
							|  |  |  | 	CW1200_JOIN_STATUS_IBSS, | 
					
						
							|  |  |  | 	CW1200_JOIN_STATUS_AP, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | enum cw1200_link_status { | 
					
						
							|  |  |  | 	CW1200_LINK_OFF, | 
					
						
							|  |  |  | 	CW1200_LINK_RESERVE, | 
					
						
							|  |  |  | 	CW1200_LINK_SOFT, | 
					
						
							|  |  |  | 	CW1200_LINK_HARD, | 
					
						
							|  |  |  | 	CW1200_LINK_RESET, | 
					
						
							|  |  |  | 	CW1200_LINK_RESET_REMAP, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern int cw1200_power_mode; | 
					
						
							|  |  |  | extern const char * const cw1200_fw_types[]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct cw1200_link_entry { | 
					
						
							|  |  |  | 	unsigned long			timestamp; | 
					
						
							|  |  |  | 	enum cw1200_link_status		status; | 
					
						
							|  |  |  | 	enum cw1200_link_status		prev_status; | 
					
						
							|  |  |  | 	u8				mac[ETH_ALEN]; | 
					
						
							|  |  |  | 	u8				buffered[CW1200_MAX_TID]; | 
					
						
							|  |  |  | 	struct sk_buff_head		rx_queue; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct cw1200_common { | 
					
						
							|  |  |  | 	/* interfaces to the rest of the stack */ | 
					
						
							|  |  |  | 	struct ieee80211_hw		*hw; | 
					
						
							|  |  |  | 	struct ieee80211_vif		*vif; | 
					
						
							|  |  |  | 	struct device			*pdev; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Statistics */ | 
					
						
							|  |  |  | 	struct ieee80211_low_level_stats stats; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Our macaddr */ | 
					
						
							|  |  |  | 	u8 mac_addr[ETH_ALEN]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Hardware interface */ | 
					
						
							| 
									
										
										
										
											2013-06-01 08:08:42 -04:00
										 |  |  | 	const struct hwbus_ops		*hwbus_ops; | 
					
						
							|  |  |  | 	struct hwbus_priv		*hwbus_priv; | 
					
						
							| 
									
										
										
										
											2013-05-24 20:04:38 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Hardware information */ | 
					
						
							|  |  |  | 	enum { | 
					
						
							|  |  |  | 		HIF_9000_SILICON_VERSATILE = 0, | 
					
						
							|  |  |  | 		HIF_8601_VERSATILE, | 
					
						
							|  |  |  | 		HIF_8601_SILICON, | 
					
						
							|  |  |  | 	} hw_type; | 
					
						
							|  |  |  | 	enum { | 
					
						
							|  |  |  | 		CW1200_HW_REV_CUT10 = 10, | 
					
						
							|  |  |  | 		CW1200_HW_REV_CUT11 = 11, | 
					
						
							|  |  |  | 		CW1200_HW_REV_CUT20 = 20, | 
					
						
							|  |  |  | 		CW1200_HW_REV_CUT22 = 22, | 
					
						
							|  |  |  | 		CW1X60_HW_REV       = 40, | 
					
						
							|  |  |  | 	} hw_revision; | 
					
						
							|  |  |  | 	int                             hw_refclk; | 
					
						
							|  |  |  | 	bool				hw_have_5ghz; | 
					
						
							|  |  |  | 	const struct firmware		*sdd; | 
					
						
							|  |  |  | 	char                            *sdd_path; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct cw1200_debug_priv	*debug; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct workqueue_struct		*workqueue; | 
					
						
							|  |  |  | 	struct mutex			conf_mutex; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct cw1200_queue		tx_queue[4]; | 
					
						
							|  |  |  | 	struct cw1200_queue_stats	tx_queue_stats; | 
					
						
							|  |  |  | 	int				tx_burst_idx; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* firmware/hardware info */ | 
					
						
							|  |  |  | 	unsigned int tx_hdr_len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Radio data */ | 
					
						
							|  |  |  | 	int output_power; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* BBP/MAC state */ | 
					
						
							|  |  |  | 	struct ieee80211_rate		*rates; | 
					
						
							|  |  |  | 	struct ieee80211_rate		*mcs_rates; | 
					
						
							|  |  |  | 	struct ieee80211_channel	*channel; | 
					
						
							|  |  |  | 	struct wsm_edca_params		edca; | 
					
						
							|  |  |  | 	struct wsm_tx_queue_params	tx_queue_params; | 
					
						
							|  |  |  | 	struct wsm_mib_association_mode	association_mode; | 
					
						
							|  |  |  | 	struct wsm_set_bss_params	bss_params; | 
					
						
							|  |  |  | 	struct cw1200_ht_info		ht_info; | 
					
						
							|  |  |  | 	struct wsm_set_pm		powersave_mode; | 
					
						
							|  |  |  | 	struct wsm_set_pm		firmware_ps_mode; | 
					
						
							|  |  |  | 	int				cqm_rssi_thold; | 
					
						
							|  |  |  | 	unsigned			cqm_rssi_hyst; | 
					
						
							|  |  |  | 	bool				cqm_use_rssi; | 
					
						
							|  |  |  | 	int				cqm_beacon_loss_count; | 
					
						
							|  |  |  | 	int				channel_switch_in_progress; | 
					
						
							|  |  |  | 	wait_queue_head_t		channel_switch_done; | 
					
						
							|  |  |  | 	u8				long_frame_max_tx_count; | 
					
						
							|  |  |  | 	u8				short_frame_max_tx_count; | 
					
						
							|  |  |  | 	int				mode; | 
					
						
							|  |  |  | 	bool				enable_beacon; | 
					
						
							|  |  |  | 	int				beacon_int; | 
					
						
							|  |  |  | 	bool				listening; | 
					
						
							|  |  |  | 	struct wsm_rx_filter		rx_filter; | 
					
						
							|  |  |  | 	struct wsm_mib_multicast_filter multicast_filter; | 
					
						
							|  |  |  | 	bool				has_multicast_subscription; | 
					
						
							|  |  |  | 	bool				disable_beacon_filter; | 
					
						
							|  |  |  | 	struct work_struct		update_filtering_work; | 
					
						
							|  |  |  | 	struct work_struct		set_beacon_wakeup_period_work; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	u8				ba_rx_tid_mask; | 
					
						
							|  |  |  | 	u8				ba_tx_tid_mask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct cw1200_pm_state		pm_state; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct wsm_p2p_ps_modeinfo	p2p_ps_modeinfo; | 
					
						
							|  |  |  | 	struct wsm_uapsd_info		uapsd_info; | 
					
						
							|  |  |  | 	bool				setbssparams_done; | 
					
						
							|  |  |  | 	bool				bt_present; | 
					
						
							|  |  |  | 	u8				conf_listen_interval; | 
					
						
							|  |  |  | 	u32				listen_interval; | 
					
						
							|  |  |  | 	u32				erp_info; | 
					
						
							|  |  |  | 	u32				rts_threshold; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* BH */ | 
					
						
							|  |  |  | 	atomic_t			bh_rx; | 
					
						
							|  |  |  | 	atomic_t			bh_tx; | 
					
						
							|  |  |  | 	atomic_t			bh_term; | 
					
						
							|  |  |  | 	atomic_t			bh_suspend; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct workqueue_struct         *bh_workqueue; | 
					
						
							|  |  |  | 	struct work_struct              bh_work; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int				bh_error; | 
					
						
							|  |  |  | 	wait_queue_head_t		bh_wq; | 
					
						
							|  |  |  | 	wait_queue_head_t		bh_evt_wq; | 
					
						
							|  |  |  | 	u8				buf_id_tx; | 
					
						
							|  |  |  | 	u8				buf_id_rx; | 
					
						
							|  |  |  | 	u8				wsm_rx_seq; | 
					
						
							|  |  |  | 	u8				wsm_tx_seq; | 
					
						
							|  |  |  | 	int				hw_bufs_used; | 
					
						
							|  |  |  | 	bool				powersave_enabled; | 
					
						
							|  |  |  | 	bool				device_can_sleep; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Scan status */ | 
					
						
							|  |  |  | 	struct cw1200_scan scan; | 
					
						
							|  |  |  | 	/* Keep cw1200 awake (WUP = 1) 1 second after each scan to avoid
 | 
					
						
							| 
									
										
										
										
											2013-06-11 09:49:40 -04:00
										 |  |  | 	 * FW issue with sleeping/waking up. | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2013-05-24 20:04:38 -04:00
										 |  |  | 	atomic_t			recent_scan; | 
					
						
							|  |  |  | 	struct delayed_work		clear_recent_scan_work; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* WSM */ | 
					
						
							|  |  |  | 	struct wsm_startup_ind		wsm_caps; | 
					
						
							|  |  |  | 	struct mutex			wsm_cmd_mux; | 
					
						
							|  |  |  | 	struct wsm_buf			wsm_cmd_buf; | 
					
						
							|  |  |  | 	struct wsm_cmd			wsm_cmd; | 
					
						
							|  |  |  | 	wait_queue_head_t		wsm_cmd_wq; | 
					
						
							|  |  |  | 	wait_queue_head_t		wsm_startup_done; | 
					
						
							|  |  |  | 	int                             firmware_ready; | 
					
						
							|  |  |  | 	atomic_t			tx_lock; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* WSM debug */ | 
					
						
							|  |  |  | 	int				wsm_enable_wsm_dumps; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* WSM Join */ | 
					
						
							|  |  |  | 	enum cw1200_join_status	join_status; | 
					
						
							|  |  |  | 	u32			pending_frame_id; | 
					
						
							|  |  |  | 	bool			join_pending; | 
					
						
							|  |  |  | 	struct delayed_work	join_timeout; | 
					
						
							|  |  |  | 	struct work_struct	unjoin_work; | 
					
						
							|  |  |  | 	struct work_struct	join_complete_work; | 
					
						
							|  |  |  | 	int			join_complete_status; | 
					
						
							|  |  |  | 	int			join_dtim_period; | 
					
						
							|  |  |  | 	bool			delayed_unjoin; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* TX/RX and security */ | 
					
						
							|  |  |  | 	s8			wep_default_key_id; | 
					
						
							|  |  |  | 	struct work_struct	wep_key_work; | 
					
						
							|  |  |  | 	u32			key_map; | 
					
						
							|  |  |  | 	struct wsm_add_key	keys[WSM_KEY_MAX_INDEX + 1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* AP powersave */ | 
					
						
							|  |  |  | 	u32			link_id_map; | 
					
						
							|  |  |  | 	struct cw1200_link_entry link_id_db[CW1200_MAX_STA_IN_AP_MODE]; | 
					
						
							|  |  |  | 	struct work_struct	link_id_work; | 
					
						
							|  |  |  | 	struct delayed_work	link_id_gc_work; | 
					
						
							|  |  |  | 	u32			sta_asleep_mask; | 
					
						
							|  |  |  | 	u32			pspoll_mask; | 
					
						
							|  |  |  | 	bool			aid0_bit_set; | 
					
						
							|  |  |  | 	spinlock_t		ps_state_lock; /* Protect power save state */ | 
					
						
							|  |  |  | 	bool			buffered_multicasts; | 
					
						
							|  |  |  | 	bool			tx_multicast; | 
					
						
							|  |  |  | 	struct work_struct	set_tim_work; | 
					
						
							|  |  |  | 	struct work_struct	set_cts_work; | 
					
						
							|  |  |  | 	struct work_struct	multicast_start_work; | 
					
						
							|  |  |  | 	struct work_struct	multicast_stop_work; | 
					
						
							|  |  |  | 	struct timer_list	mcast_timeout; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* WSM events and CQM implementation */ | 
					
						
							|  |  |  | 	spinlock_t		event_queue_lock; /* Protect event queue */ | 
					
						
							|  |  |  | 	struct list_head	event_queue; | 
					
						
							|  |  |  | 	struct work_struct	event_handler; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct delayed_work	bss_loss_work; | 
					
						
							|  |  |  | 	spinlock_t		bss_loss_lock; /* Protect BSS loss state */ | 
					
						
							|  |  |  | 	int                     bss_loss_state; | 
					
						
							| 
									
										
										
										
											2013-06-20 23:03:12 -04:00
										 |  |  | 	u32                     bss_loss_confirm_id; | 
					
						
							| 
									
										
										
										
											2013-05-24 20:04:38 -04:00
										 |  |  | 	int			delayed_link_loss; | 
					
						
							|  |  |  | 	struct work_struct	bss_params_work; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* TX rate policy cache */ | 
					
						
							|  |  |  | 	struct tx_policy_cache tx_policy_cache; | 
					
						
							|  |  |  | 	struct work_struct tx_policy_upload_work; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* legacy PS mode switch in suspend */ | 
					
						
							|  |  |  | 	int			ps_mode_switch_in_progress; | 
					
						
							|  |  |  | 	wait_queue_head_t	ps_mode_switch_done; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Workaround for WFD testcase 6.1.10*/ | 
					
						
							|  |  |  | 	struct work_struct	linkid_reset_work; | 
					
						
							|  |  |  | 	u8			action_frame_sa[ETH_ALEN]; | 
					
						
							|  |  |  | 	u8			action_linkid; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct cw1200_sta_priv { | 
					
						
							|  |  |  | 	int link_id; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* interfaces for the drivers */ | 
					
						
							| 
									
										
										
										
											2013-06-01 08:08:42 -04:00
										 |  |  | int cw1200_core_probe(const struct hwbus_ops *hwbus_ops, | 
					
						
							|  |  |  | 		      struct hwbus_priv *hwbus, | 
					
						
							| 
									
										
										
										
											2013-05-24 20:04:38 -04:00
										 |  |  | 		      struct device *pdev, | 
					
						
							|  |  |  | 		      struct cw1200_common **pself, | 
					
						
							|  |  |  | 		      int ref_clk, const u8 *macaddr, | 
					
						
							|  |  |  | 		      const char *sdd_path, bool have_5ghz); | 
					
						
							|  |  |  | void cw1200_core_release(struct cw1200_common *self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define FWLOAD_BLOCK_SIZE (1024)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline int cw1200_is_ht(const struct cw1200_ht_info *ht_info) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return ht_info->channel_type != NL80211_CHAN_NO_HT; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline int cw1200_ht_greenfield(const struct cw1200_ht_info *ht_info) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return cw1200_is_ht(ht_info) && | 
					
						
							|  |  |  | 		(ht_info->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && | 
					
						
							|  |  |  | 		!(ht_info->operation_mode & | 
					
						
							|  |  |  | 		  IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline int cw1200_ht_ampdu_density(const struct cw1200_ht_info *ht_info) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!cw1200_is_ht(ht_info)) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	return ht_info->ht_cap.ampdu_density; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /* CW1200_H */
 |