iwlwifi (version 1.1.22)
v2 cover iwlwifi (version 1.1.22)
This is a resend of latest iwlwifi patches from Yi The version is rebased against current #everything branch and especially against iwlwifi 11n patches.
Some minor warnings were fixed as well.
---------------------------------------------------------------------
Intel Israel (74) Limited
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 1/34 iwlwifi: Support for uCode without init and bsm section
This patch enables loading fw w/o init and bsm section. It also provides general cleanup of the rutine.
--- drivers/net/wireless/iwlwifi/iwl3945-base.c | 120 ++++++++++++-------------- drivers/net/wireless/iwlwifi/iwl4965-base.c | 122 ++++++++++++-------------- 2 files changed, 112 insertions(+), 130 deletions(-)
drivers/net/wireless/iwlwifi/iwl3945-base.c +56 -64
@@ -5765,6 +5765,12 @@ static void iwl3945_nic_start(struct iwl3945_priv *priv)iwl3945_write32 (priv,CSR_RESET ,0 ); } +static int iwl3945_alloc_fw_desc (struct pci_dev *pci_dev,struct fw_desc *desc) +{ + desc->v_addr =pci_alloc_consistent (pci_dev, desc->len, &desc->p_addr); +return (desc->v_addr !=NULL ) ?0 : -ENOMEM ; +} +/** * iwl3945_read_ucode - Read uCode images from disk file. *
@@ -5773,7 +5779,7 @@ static void iwl3945_nic_start(struct iwl3945_priv *priv)static int iwl3945_read_ucode (struct iwl3945_priv *priv) {struct iwl3945_ucode *ucode; -int rc =0 ; +int ret =0 ;const struct firmware *ucode_raw;/* firmware file name contains uCode/driver compatibility version */ const char *name ="iwlwifi-3945" IWL3945_UCODE_API ".ucode" ;
@@ -5783,9 +5789,10 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)/* Ask kernel firmware_class module to get the boot firmware off disk. * request_firmware() is synchronous, file is in memory on return. */ - rc =request_firmware (&ucode_raw, name, &priv->pci_dev->dev); -if (rc <0 ) { -IWL_ERROR ("%s firmware file req failed: Reason %d\n" , name, rc); + ret =request_firmware (&ucode_raw, name, &priv->pci_dev->dev); +if (ret <0 ) { +IWL_ERROR ("%s firmware file req failed: Reason %d\n" , + name, ret); goto error; }
@@ -5795,7 +5802,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)/* Make sure that we got at least our header! */ if (ucode_raw->size <sizeof (*ucode)) {IWL_ERROR ("File size way too small!\n" ); - rc = -EINVAL ; + ret = -EINVAL ; goto err_release; }
@@ -5823,43 +5830,40 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)IWL_DEBUG_INFO ("uCode file size %d too small\n" , (int )ucode_raw->size); - rc = -EINVAL ; + ret = -EINVAL ; goto err_release; }/* Verify that uCode images will fit in card's SRAM */ if (inst_size >IWL_MAX_INST_SIZE ) { -IWL_DEBUG_INFO ("uCode instr len %d too large to fit in card\n" , - (int )inst_size); - rc = -EINVAL ; +IWL_DEBUG_INFO ("uCode instr len %d too large to fit in\n" , + inst_size); + ret = -EINVAL ; goto err_release; }if (data_size >IWL_MAX_DATA_SIZE ) { -IWL_DEBUG_INFO ("uCode data len %d too large to fit in card\n" , - (int )data_size); - rc = -EINVAL ; +IWL_DEBUG_INFO ("uCode data len %d too large to fit in\n" , + data_size); + ret = -EINVAL ; goto err_release; }if (init_size >IWL_MAX_INST_SIZE ) { -IWL_DEBUG_INFO - ("uCode init instr len %d too large to fit in card\n" , - (int )init_size); - rc = -EINVAL ; +IWL_DEBUG_INFO ("uCode init instr len %d too large to fit in\n" , + init_size); + ret = -EINVAL ; goto err_release; }if (init_data_size >IWL_MAX_DATA_SIZE ) { -IWL_DEBUG_INFO - ("uCode init data len %d too large to fit in card\n" , - (int )init_data_size); - rc = -EINVAL ; +IWL_DEBUG_INFO ("uCode init data len %d too large to fit in\n" , + init_data_size); + ret = -EINVAL ; goto err_release; }if (boot_size >IWL_MAX_BSM_SIZE ) { -IWL_DEBUG_INFO - ("uCode boot instr len %d too large to fit in bsm\n" , - (int )boot_size); - rc = -EINVAL ; +IWL_DEBUG_INFO ("uCode boot instr len %d too large to fit in\n" , + boot_size); + ret = -EINVAL ; goto err_release; }
@@ -5869,56 +5873,45 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)* 1) unmodified from disk * 2) backup cache for save/restore during power-downs */ priv->ucode_code.len = inst_size; - priv->ucode_code.v_addr = -pci_alloc_consistent (priv->pci_dev, - priv->ucode_code.len, - &(priv->ucode_code.p_addr)); +iwl3945_alloc_fw_desc (priv->pci_dev, &priv->ucode_code); priv->ucode_data.len = data_size; - priv->ucode_data.v_addr = -pci_alloc_consistent (priv->pci_dev, - priv->ucode_data.len, - &(priv->ucode_data.p_addr)); +iwl3945_alloc_fw_desc (priv->pci_dev, &priv->ucode_data); priv->ucode_data_backup.len = data_size; - priv->ucode_data_backup.v_addr = -pci_alloc_consistent (priv->pci_dev, - priv->ucode_data_backup.len, - &(priv->ucode_data_backup.p_addr)); +iwl3945_alloc_fw_desc (priv->pci_dev, &priv->ucode_data_backup); +if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr || + !priv->ucode_data_backup.v_addr) + goto err_pci_alloc;/* Initialization instructions and data */ - priv->ucode_init.len = init_size; - priv->ucode_init.v_addr = -pci_alloc_consistent (priv->pci_dev, - priv->ucode_init.len, - &(priv->ucode_init.p_addr)); - - priv->ucode_init_data.len = init_data_size; - priv->ucode_init_data.v_addr = -pci_alloc_consistent (priv->pci_dev, - priv->ucode_init_data.len, - &(priv->ucode_init_data.p_addr)); +if (init_size && init_data_size) { + priv->ucode_init.len = init_size; +iwl3945_alloc_fw_desc (priv->pci_dev, &priv->ucode_init); + + priv->ucode_init_data.len = init_data_size; +iwl3945_alloc_fw_desc (priv->pci_dev, &priv->ucode_init_data); + +if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr) + goto err_pci_alloc; + }/* Bootstrap (instructions only, no data) */ - priv->ucode_boot.len = boot_size; - priv->ucode_boot.v_addr = -pci_alloc_consistent (priv->pci_dev, - priv->ucode_boot.len, - &(priv->ucode_boot.p_addr)); +if (boot_size) { + priv->ucode_boot.len = boot_size; +iwl3945_alloc_fw_desc (priv->pci_dev, &priv->ucode_boot); -if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr || - !priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr || - !priv->ucode_boot.v_addr || !priv->ucode_data_backup.v_addr) - goto err_pci_alloc; +if (!priv->ucode_boot.v_addr) + goto err_pci_alloc; + }/* Copy images into buffers for card's bus-master reads ... */ /* Runtime instructions (first block of data in file) */ src = &ucode->data[0 ]; len = priv->ucode_code.len; -IWL_DEBUG_INFO ("Copying (but not loading) uCode instr len %d\n" , - (int )len); +IWL_DEBUG_INFO ("Copying (but not loading) uCode instr len %Zd\n" , len);memcpy (priv->ucode_code.v_addr, src, len);IWL_DEBUG_INFO ("uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n" , priv->ucode_code.v_addr, (u32 )priv->ucode_code.p_addr);
@@ -5927,8 +5920,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)* NOTE: Copy into backup buffer will be done in iwl3945_up() */ src = &ucode->data[inst_size]; len = priv->ucode_data.len; -IWL_DEBUG_INFO ("Copying (but not loading) uCode data len %d\n" , - (int )len); +IWL_DEBUG_INFO ("Copying (but not loading) uCode data len %Zd\n" , len);memcpy (priv->ucode_data.v_addr, src, len);memcpy (priv->ucode_data_backup.v_addr, src, len);
@@ -5936,8 +5928,8 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)if (init_size) { src = &ucode->data[inst_size + data_size]; len = priv->ucode_init.len; -IWL_DEBUG_INFO ("Copying (but not loading) init instr len %d\n" , - (int )len); +IWL_DEBUG_INFO ("Copying (but not loading) init instr len %Zd\n" , + len);memcpy (priv->ucode_init.v_addr, src, len); }
@@ -5963,14 +5955,14 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv) err_pci_alloc:IWL_ERROR ("failed to allocate pci memory\n" ); - rc = -ENOMEM ; + ret = -ENOMEM ;iwl3945_dealloc_ucode_pci (priv); err_release:release_firmware (ucode_raw); error: -return rc; +return ret; }
drivers/net/wireless/iwlwifi/iwl4965-base.c +56 -66
230 lines not on this page · raw message
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 2/34 iwlwifi: continue namespace changes - fix CONFIG variables
From: Reinette Chatre <[email protected]>
- Remove HT code from iwl-3945.h - it is not needed here as 3945 does not support HT. The code ended up here during the header file split.
- Modify a few places where the CONFIG variables were named
incorrectly: all changes are to comments only.
--- drivers/net/wireless/iwlwifi/iwl-3945.h | 24 ------------------------ drivers/net/wireless/iwlwifi/iwl-4965.c | 2 +- drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 +- drivers/net/wireless/iwlwifi/iwl4965-base.c | 2 +- 4 files changed, 3 insertions(+), 27 deletions(-)
drivers/net/wireless/iwlwifi/iwl-3945.h +0 -24
@@ -446,30 +446,6 @@ union iwl3945_ht_rate_supp { }; }; -#ifdef CONFIG_IWL3945_HT -#define CFG_HT_RX_AMPDU_FACTOR_DEF (0x3) -#define CFG_HT_MPDU_DENSITY_2USEC (0x5) -#define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_2USEC - -struct sta_ht_info { -u8 is_ht; -u16 rx_mimo_ps_mode; -u16 tx_mimo_ps_mode; -u16 control_channel; -u8 max_amsdu_size; -u8 ampdu_factor; -u8 mpdu_density; -u8 operating_mode; -u8 supported_chan_width; -u8 extension_chan_offset; -u8 is_green_field; -u8 sgf; -u8 supp_rates[16 ]; -u8 tx_chan_width; -u8 chan_width_cap; -}; -#endif /*CONFIG_IWL3945_HT */ -#ifdef CONFIG_IWL3945_QOS union iwl3945_qos_capabity {
drivers/net/wireless/iwlwifi/iwl-4965.c +1 -1
@@ -4697,7 +4697,7 @@ void iwl4965_hw_setup_deferred_work(struct iwl4965_priv *priv)#ifdef CONFIG_IWL4965_HT #ifdef CONFIG_IWL4965_HT_AGG INIT_WORK (&priv->agg_work, iwl4965_bg_agg_work); -#endif /* CONFIG_IWL4965_AGG */ +#endif /* CONFIG_IWL4965_HT_AGG */ #endif /* CONFIG_IWL4965_HT */ init_timer (&priv->statistics_periodic); priv->statistics_periodic.data = (unsigned long )priv;
drivers/net/wireless/iwlwifi/iwl3945-base.c +1 -1
@@ -7376,7 +7376,7 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue,#ifdef CONFIG_IWL3945_QOS unsigned long flags;int q; -#endif /* CONFIG_IWL_QOS */ +#endif /* CONFIG_IWL3945_QOS */ IWL_DEBUG_MAC80211 ("enter\n" );
drivers/net/wireless/iwlwifi/iwl4965-base.c +1 -1
@@ -7815,7 +7815,7 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue,#ifdef CONFIG_IWL4965_QOS unsigned long flags;int q; -#endif /* CONFIG_IWL_QOS */ +#endif /* CONFIG_IWL4965_QOS */ IWL_DEBUG_MAC80211 ("enter\n" );
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 3/34 iwl3945: re-align 3945 event log data
From: Ben Cahill <[email protected]>
Re-align 3945 event log data.
--- drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/wireless/iwlwifi/iwl3945-base.c +1 -1
@@ -4494,7 +4494,7 @@ static void iwl3945_dump_nic_error_log(struct iwl3945_priv *priv) } -#define EVENT_START_OFFSET (4 * sizeof(u32)) +#define EVENT_START_OFFSET (6 * sizeof(u32))/** * iwl3945_print_event_log - Dump error event log to syslog
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 4/34 iwl4965: add comments to rate scaling code
From: Ben Cahill <[email protected]>
Add comments to rate scaling code.
--- drivers/net/wireless/iwlwifi/iwl-4965-rs.c | 468 +++++++++++++++++++++++---- drivers/net/wireless/iwlwifi/iwl-4965-rs.h | 45 ++- drivers/net/wireless/iwlwifi/iwl-4965.h | 2 +- drivers/net/wireless/iwlwifi/iwl4965-base.c | 3 + 4 files changed, 443 insertions(+), 75 deletions(-)
drivers/net/wireless/iwlwifi/iwl-4965-rs.c +410 -58
@@ -47,13 +47,12 @@#define IWL_NUMBER_TRY 1#define IWL_HT_NUMBER_TRY 3 -#define IWL_RATE_MAX_WINDOW 62 -#define IWL_RATE_HIGH_TH 10880 -#define IWL_RATE_MIN_FAILURE_TH 6 -#define IWL_RATE_MIN_SUCCESS_TH 8 -#define IWL_RATE_DECREASE_TH 1920 -#define IWL_RATE_INCREASE_TH 8960 -#define IWL_RATE_SCALE_FLUSH_INTVL (2*HZ)/*2 seconds */ +#define IWL_RATE_MAX_WINDOW 62/* # tx in history window */ +#define IWL_RATE_MIN_FAILURE_TH 6/* min failures to calc tpt */ +#define IWL_RATE_MIN_SUCCESS_TH 8/* min successes to calc tpt */ + +/* max time to accum history 2 seconds */ +#define IWL_RATE_SCALE_FLUSH_INTVL (2*HZ)static u8 rs_ht_to_legacy[] = {IWL_RATE_6M_INDEX ,IWL_RATE_6M_INDEX ,
@@ -69,54 +68,74 @@ struct iwl4965_rate {u32 rate_n_flags; } __attribute__ ((packed)); +/** +* struct iwl4965_rate_scale_data -- tx success history for one rate +*/ struct iwl4965_rate_scale_data { -u64 data; -s32 success_counter; -s32 success_ratio; -s32 counter; -s32 average_tpt; +u64 data;/* bitmap of successful frames */ +s32 success_counter;/* number of frames successful */ +s32 success_ratio;/* per-cent * 128 */ +s32 counter;/* number of frames attempted */ +s32 average_tpt;/* success ratio * expected throughput */ unsigned long stamp; }; +/** +* struct iwl4965_scale_tbl_info -- tx params and success history for all rates +* +* There are two of these in struct iwl_rate_scale_priv, +* one for "active", and one for "search". +*/ struct iwl4965_scale_tbl_info {enum iwl4965_table_type lq_type;enum iwl4965_antenna_type antenna_type; -u8 is_SGI; -u8 is_fat; -u8 is_dup; -u8 action; -s32 *expected_tpt; -struct iwl4965_rate current_rate; -struct iwl4965_rate_scale_data win[IWL_RATE_COUNT ]; +u8 is_SGI;/* 1 = short guard interval */ +u8 is_fat;/* 1 = 40 MHz channel width */ +u8 is_dup;/* 1 = duplicated data streams */ +u8 action;/* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */ +s32 *expected_tpt;/* throughput metrics; expected_tpt_G, etc. */ +struct iwl4965_rate current_rate;/* rate_n_flags, uCode API format */ +struct iwl4965_rate_scale_data win[IWL_RATE_COUNT ];/* rate histories */ }; +/** +* struct iwl_rate_scale_priv -- driver's rate scaling private structure +* +* Pointer to this gets passed back and forth between driver and mac80211. +*/ struct iwl4965_rate_scale_priv { -u8 active_tbl; -u8 enable_counter; -u8 stay_in_tbl; -u8 search_better_tbl; +u8 active_tbl;/* index of active table, range 0-1 */ +u8 enable_counter;/* indicates HT mode */ +u8 stay_in_tbl;/* 1: disallow, 0: allow search for new mode */ +u8 search_better_tbl;/* 1: currently trying alternate mode */ s32 last_tpt; + +/* The following determine when to search for a new mode */ u32 table_count_limit; -u32 max_failure_limit; -u32 max_success_limit; +u32 max_failure_limit;/* # failed frames before new search */ +u32 max_success_limit;/* # successful frames before new search */ u32 table_count; -u32 total_failed; -u32 total_success; -u32 flush_timer; -u8 action_counter; +u32 total_failed;/* total failed frames, any/all rates */ +u32 total_success;/* total successful frames, any/all rates */ +u32 flush_timer;/* time staying in mode before new search */ + +u8 action_counter;/* # mode-switch actions tried */ u8 antenna;u8 valid_antenna;u8 is_green;u8 is_dup;u8 phymode;u8 ibss_sta_added; + +/* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ u32 supp_rates;u16 active_rate;u16 active_siso_rate;u16 active_mimo_rate;u16 active_rate_basic; +struct iwl4965_link_quality_cmd lq; -struct iwl4965_scale_tbl_info lq_info[LQ_SIZE ]; +struct iwl4965_scale_tbl_info lq_info[LQ_SIZE ];/* "active", "search" */ #ifdef CONFIG_MAC80211_DEBUGFS struct dentry *rs_sta_dbgfs_scale_table_file;struct dentry *rs_sta_dbgfs_stats_table_file;
@@ -142,6 +161,12 @@ static void rs_dbgfs_set_mcs(struct iwl4965_rate_scale_priv *rs_priv, struct iwl4965_rate *mcs, int index) {}#endif + +/* +* Expected throughput metrics for following rates: +* 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits +* "G" is the only table that supports CCK (the first 4 rates). +*/ static s32 expected_tpt_A[IWL_RATE_COUNT ] = {0 ,0 ,0 ,0 ,40 ,57 ,72 ,98 ,121 ,154 ,177 ,186 ,186 };
@@ -244,6 +269,13 @@ static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window) window->stamp =0 ; } +/** +* rs_collect_tx_data - Update the success/failure sliding window +* +* We keep a sliding window of the last 62 packets transmitted +* at this rate. window->data contains the bitmask of successful +* packets. +*/ static int rs_collect_tx_data (struct iwl4965_rate_scale_data *windows,int scale_index,s32 tpt,u32 status) {
@@ -255,10 +287,18 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,if (scale_index <0 || scale_index >=IWL_RATE_COUNT )return -EINVAL ; +/* Select data for current tx bit rate */ window = &(windows[scale_index]); +/* +* Keep track of only the latest 62 tx frame attempts in this rate's +* history window; anything older isn't really relevant any more. +* If we have filled up the sliding window, drop the oldest attempt; +* if the oldest attempt (highest bit in bitmap) shows "success", +* subtract "1" from the success counter (this is the main reason +* we keep these bitmaps!). +*/ if (window->counter >= win_size) { - window->counter = win_size -1 ; mask =1 ; mask = (mask << (win_size -1 ));
@@ -268,7 +308,11 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, } } +/* Increment frames-attempted counter */ window->counter = window->counter +1 ; + +/* Shift bitmap by one frame (throw away oldest history), +* OR in "1", and increment "success" if this frame was successful. */ mask = window->data; window->data = (mask <<1 );if (status !=0 ) {
@@ -276,6 +320,7 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, window->data |=0x1 ; } +/* Calculate current success ratio, avoid divide-by-0! */ if (window->counter >0 ) window->success_ratio =128 * (100 * window->success_counter) / window->counter;
@@ -284,17 +329,22 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, fail_count = window->counter - window->success_counter; +/* Calculate average throughput, if we have enough history. */ if ((fail_count >=IWL_RATE_MIN_FAILURE_TH ) || (window->success_counter >=IWL_RATE_MIN_SUCCESS_TH )) window->average_tpt = (window->success_ratio * tpt +64 ) /128 ;else window->average_tpt =IWL_INVALID_VALUE ; +/* Tag this window as having been updated */ window->stamp = jiffies;return 0 ; } +/* +* Fill uCode API rate_n_flags field, based on "search" or "active" table. +*/ static void rs_mcs_from_tbl (struct iwl4965_rate *mcs_rate,struct iwl4965_scale_tbl_info *tbl,int index,u8 use_green)
@@ -349,6 +399,10 @@ static void rs_mcs_from_tbl(struct iwl4965_rate *mcs_rate, } } +/* +* Interpret uCode API's rate_n_flags format, +* fill "search" or "active" tx mode table. +*/ static int rs_get_tbl_info_from_mcs (const struct iwl4965_rate *mcs_rate,int phymode,struct iwl4965_scale_tbl_info *tbl,int *rate_idx)
@@ -362,11 +416,12 @@ static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, *rate_idx =-1 ;return -EINVAL ; } - tbl->is_SGI =0 ; + tbl->is_SGI =0 ;/* default legacy setup */ tbl->is_fat =0 ; tbl->is_dup =0 ; - tbl->antenna_type =ANT_BOTH ; + tbl->antenna_type =ANT_BOTH ;/* default MIMO setup */ +/* legacy rate format */ if (!(mcs_rate->rate_n_flags &RATE_MCS_HT_MSK )) { ant_msk = (mcs_rate->rate_n_flags &RATE_MCS_ANT_AB_MSK );
@@ -386,6 +441,7 @@ static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, } *rate_idx = index; +/* HT rate format, SISO (might be 20 MHz legacy or 40 MHz fat width) */ }else if (iwl4965_rate_get_rate (mcs_rate->rate_n_flags) <=IWL_RATE_SISO_60M_PLCP ) { tbl->lq_type =LQ_SISO ;
@@ -410,6 +466,8 @@ static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, tbl->is_dup =1 ; *rate_idx = index; + +/* HT rate format, MIMO (might be 20 MHz legacy or 40 MHz fat width) */ }else { tbl->lq_type =LQ_MIMO ;if (mcs_rate->rate_n_flags &RATE_MCS_SGI_MSK )
@@ -563,8 +621,9 @@ static void rs_get_lower_rate(struct iwl4965_rate_scale_priv *lq_data,rs_get_supported_rates (lq_data,NULL , tbl->lq_type, &rate_mask); -/* mask with station rate restriction */ +/* Mask with station rate restriction */ if (is_legacy (tbl->lq_type)) { +/* supp_rates has no CCK bits in A mode */ if (lq_data->phymode == (u8 )MODE_IEEE80211A ) rate_mask = (u16)(rate_mask & (lq_data->supp_rates <<IWL_FIRST_OFDM_RATE ));
@@ -572,7 +631,7 @@ static void rs_get_lower_rate(struct iwl4965_rate_scale_priv *lq_data, rate_mask = (u16)(rate_mask & lq_data->supp_rates); } -/* if we did switched from HT to legacy check current rate */ +/* If we switched from HT to legacy, check current rate */ if (switch_to_legacy && (rate_mask & (1 << scale_index))) {rs_mcs_from_tbl (mcs_rate, tbl, scale_index, is_green);return ;
@@ -587,6 +646,9 @@ static void rs_get_lower_rate(struct iwl4965_rate_scale_priv *lq_data,rs_mcs_from_tbl (mcs_rate, tbl, scale_index, is_green); } +/* +* mac80211 sends us Tx status +*/ static void rs_tx_status(void *priv_rate, struct net_device *dev, struct sk_buff *skb,
@@ -640,11 +702,14 @@ static void rs_tx_status(void *priv_rate, table = &lq->lq; active_index = lq->active_tbl; +/* Get mac80211 antenna info */ lq->antenna = (lq->valid_antenna & local->hw.conf.antenna_sel_tx);if (!lq->antenna) lq->antenna = lq->valid_antenna; +/* Ignore mac80211 antenna info for now */ lq->antenna = lq->valid_antenna; + curr_tbl = &(lq->lq_info[active_index]); search_tbl = &(lq->lq_info[(1 - active_index)]); window = (struct iwl4965_rate_scale_data *)
@@ -663,6 +728,14 @@ static void rs_tx_status(void *priv_rate,return ; } +/* +* Ignore this Tx frame response if its initial rate doesn't match +* that of latest Link Quality command. There may be stragglers +* from a previous Link Quality command, but we're no longer interested +* in those; they're either from the "active" mode while we're trying +* to check "search" mode, or a prior "search" mode after we've moved +* to a new "search" mode (which might become the new "active" mode). +*/ if (retries && (tx_mcs.rate_n_flags !=le32_to_cpu (table->rs_table[0 ].rate_n_flags))) {
@@ -673,12 +746,17 @@ static void rs_tx_status(void *priv_rate,return ; } +/* Update frame history window with "failure" for each Tx retry. */ while (retries) { +/* Look up the rate and other info used for each tx attempt. +* Each tx attempt steps one entry deeper in the rate table. */ tx_mcs.rate_n_flags =le32_to_cpu (table->rs_table[index].rate_n_flags);rs_get_tbl_info_from_mcs (&tx_mcs, priv->phymode, &tbl_type, &rs_index); +/* If type matches "search" table, +* add failure to "search" history */ if ((tbl_type.lq_type == search_tbl->lq_type) && (tbl_type.antenna_type == search_tbl->antenna_type) && (tbl_type.is_SGI == search_tbl->is_SGI)) {
@@ -686,8 +764,10 @@ static void rs_tx_status(void *priv_rate, tpt = search_tbl->expected_tpt[rs_index]; else tpt =0 ; -rs_collect_tx_data (search_win, - rs_index, tpt,0 ); +rs_collect_tx_data (search_win, rs_index, tpt,0 ); + +/* Else if type matches "current/active" table, +* add failure to "current/active" history */ }else if ((tbl_type.lq_type == curr_tbl->lq_type) && (tbl_type.antenna_type == curr_tbl->antenna_type) && (tbl_type.is_SGI == curr_tbl->is_SGI)) {
@@ -697,6 +777,9 @@ static void rs_tx_status(void *priv_rate, tpt =0 ;rs_collect_tx_data (window, rs_index, tpt,0 ); } + +/* If not searching for a new mode, increment failed counter +* ... this helps determine when to start searching again */ if (lq->stay_in_tbl) lq->total_failed++; --retries;
@@ -704,6 +787,11 @@ static void rs_tx_status(void *priv_rate, } +/* +* Find (by rate) the history window to update with final Tx attempt; +* if Tx was successful first try, use original rate, +* else look up the rate that was, finally, successful. +*/ if (!tx_resp->retry_count) tx_mcs.rate_n_flags = tx_resp->control.tx_rate;else
@@ -713,11 +801,14 @@ static void rs_tx_status(void *priv_rate,rs_get_tbl_info_from_mcs (&tx_mcs, priv->phymode, &tbl_type, &rs_index); +/* Update frame history window with "success" if Tx got ACKed ... */ if (tx_resp->flags &IEEE80211_TX_STATUS_ACK ) status =1 ;else status =0 ; +/* If type matches "search" table, +* add final tx status to "search" history */ if ((tbl_type.lq_type == search_tbl->lq_type) && (tbl_type.antenna_type == search_tbl->antenna_type) && (tbl_type.is_SGI == search_tbl->is_SGI)) {
@@ -727,6 +818,9 @@ static void rs_tx_status(void *priv_rate, tpt =0 ;rs_collect_tx_data (search_win, rs_index, tpt, status); + +/* Else if type matches "current/active" table, +* add final tx status to "current/active" history */ }else if ((tbl_type.lq_type == curr_tbl->lq_type) && (tbl_type.antenna_type == curr_tbl->antenna_type) && (tbl_type.is_SGI == curr_tbl->is_SGI)) {
@@ -737,6 +831,8 @@ static void rs_tx_status(void *priv_rate,rs_collect_tx_data (window, rs_index, tpt, status); } +/* If not searching for new mode, increment success/failed counter +* ... these help determine when to start searching again */ if (lq->stay_in_tbl) {if (status) lq->total_success++;
@@ -744,6 +840,7 @@ static void rs_tx_status(void *priv_rate, lq->total_failed++; } +/* See if there's a better rate or modulation mode to try. */ rs_rate_scale_perform (priv, dev, hdr, sta);sta_info_put (sta);return ;
@@ -773,11 +870,19 @@ static u8 rs_is_other_ant_connected(u8 valid_antenna,return 0 ; } +/* +* Begin a period of staying with a selected modulation mode. +* Set "stay_in_tbl" flag to prevent any mode switches. +* Set frame tx success limits according to legacy vs. high-throughput, +* and reset overall (spanning all rates) tx success history statistics. +* These control how long we stay using same modulation mode before +* searching for a new mode. +*/ static void rs_set_stay_in_table (u8 is_legacy,struct iwl4965_rate_scale_priv *lq_data) {IWL_DEBUG_HT ("we are staying in the same table\n" ); - lq_data->stay_in_tbl =1 ; + lq_data->stay_in_tbl =1 ;/* only place this gets set */ if (is_legacy) { lq_data->table_count_limit =IWL_LEGACY_TABLE_COUNT ; lq_data->max_failure_limit =IWL_LEGACY_FAILURE_LIMIT ;
@@ -792,6 +897,9 @@ static void rs_set_stay_in_table(u8 is_legacy, lq_data->total_success =0 ; } +/* +* Find correct throughput table for given mode of modulation +*/ static void rs_get_expected_tpt_table (struct iwl4965_rate_scale_priv *lq_data,struct iwl4965_scale_tbl_info *tbl) {
@@ -826,17 +934,33 @@ static void rs_get_expected_tpt_table(struct iwl4965_rate_scale_priv *lq_data, }#ifdef CONFIG_IWL4965_HT +/* +* Find starting rate for new "search" high-throughput mode of modulation. +* Goal is to find lowest expected rate (under perfect conditions) that is +* above the current measured throughput of "active" mode, to give new mode +* a fair chance to prove itself without too many challenges. +* +* This gets called when transitioning to more aggressive modulation +* (i.e. legacy to SISO or MIMO, or SISO to MIMO), as well as less aggressive +* (i.e. MIMO to SISO). When moving to MIMO, bit rate will typically need +* to decrease to match "active" throughput. When moving from MIMO to SISO, +* bit rate will typically need to increase, but not if performance was bad. +*/ static s32 rs_get_best_rate (struct iwl4965_priv *priv,struct iwl4965_rate_scale_priv *lq_data, -struct iwl4965_scale_tbl_info *tbl, +struct iwl4965_scale_tbl_info *tbl,/* "search" */ u16 rate_mask,s8 index,s8 rate) { +/* "active" values */ struct iwl4965_scale_tbl_info *active_tbl = &(lq_data->lq_info[lq_data->active_tbl]); -s32 new_rate, high, low, start_hi;s32 active_sr = active_tbl->win[index].success_ratio; -s32 *tpt_tbl = tbl->expected_tpt;s32 active_tpt = active_tbl->expected_tpt[index]; + +/* expected "search" throughput */ +s32 *tpt_tbl = tbl->expected_tpt; + +s32 new_rate, high, low, start_hi;u16 high_low; new_rate = high = low = start_hi =IWL_RATE_INVALID ;
@@ -847,6 +971,21 @@ static s32 rs_get_best_rate(struct iwl4965_priv *priv, low = high_low &0xff ; high = (high_low >>8 ) &0xff ; +/* +* Lower the "search" bit rate, to give new "search" mode +* approximately the same throughput as "active" if: +* +* 1) "Active" mode has been working modestly well (but not +* great), and expected "search" throughput (under perfect +* conditions) at candidate rate is above the actual +* measured "active" throughput (but less than expected +* "active" throughput under perfect conditions). +* OR +* 2) "Active" mode has been working perfectly or very well +* and expected "search" throughput (under perfect +* conditions) at candidate rate is above expected +* "active" throughput (under perfect conditions). +*/ if ((((100 * tpt_tbl[rate]) > lq_data->last_tpt) && ((active_sr > IWL_RATE_DECREASE_TH) && (active_sr <= IWL_RATE_HIGH_TH) &&
@@ -854,21 +993,38 @@ static s32 rs_get_best_rate(struct iwl4965_priv *priv, ((active_sr >= IWL_RATE_SCALE_SWITCH) && (tpt_tbl[rate] > active_tpt))) { +/* (2nd or later pass) +* If we've already tried to raise the rate, and are +* now trying to lower it, use the higher rate. */ if (start_hi !=IWL_RATE_INVALID ) { new_rate = start_hi;break ; } + new_rate = rate; + +/* Loop again with lower rate */ if (low !=IWL_RATE_INVALID ) rate = low; + +/* Lower rate not available, use the original */ else break ; + +/* Else try to raise the "search" rate to match "active" */ } else { +/* (2nd or later pass) +* If we've already tried to lower the rate, and are +* now trying to raise it, use the lower rate. */ if (new_rate !=IWL_RATE_INVALID )break ; + +/* Loop again with higher rate */ else if (high !=IWL_RATE_INVALID ) { start_hi = high; rate = high; + +/* Higher rate not available, use the original */ }else { new_rate = rate;break ;
@@ -885,6 +1041,9 @@ static inline u8 rs_is_both_ant_supp(u8 valid_antenna)return (rs_is_ant_connected (valid_antenna,ANT_BOTH )); } +/* +* Set up search table for MIMO +*/ static int rs_switch_to_mimo(struct iwl4965_priv *priv, struct iwl4965_rate_scale_priv *lq_data, struct ieee80211_conf *conf,
@@ -908,6 +1067,7 @@ static int rs_switch_to_mimo(struct iwl4965_priv *priv,if (priv->current_ht_config.tx_mimo_ps_mode ==IWL_MIMO_PS_STATIC )return -1 ; +/* Need both Tx chains/antennas to support MIMO */ if (!rs_is_both_ant_supp (lq_data->antenna))return -1 ;
@@ -946,6 +1106,9 @@ static int rs_switch_to_mimo(struct iwl4965_priv *priv,#endif /*CONFIG_IWL4965_HT */ } +/* +* Set up search table for SISO +*/ static int rs_switch_to_siso(struct iwl4965_priv *priv, struct iwl4965_rate_scale_priv *lq_data, struct ieee80211_conf *conf,
@@ -1006,6 +1169,9 @@ static int rs_switch_to_siso(struct iwl4965_priv *priv,#endif /*CONFIG_IWL4965_HT */ } +/* +* Try to switch to new modulation mode from legacy +*/ static int rs_move_legacy_other(struct iwl4965_priv *priv, struct iwl4965_rate_scale_priv *lq_data, struct ieee80211_conf *conf,
@@ -1029,12 +1195,17 @@ static int rs_move_legacy_other(struct iwl4965_priv *priv, search_tbl->lq_type =LQ_NONE ; lq_data->action_counter++; + +/* Don't change antenna if success has been great */ if (window->success_ratio >=IWL_RS_GOOD_RATIO )break ; + +/* Don't change antenna if other one is not connected */ if (!rs_is_other_ant_connected (lq_data->antenna, tbl->antenna_type))break ; +/* Set up search table to try other antenna */ memcpy (search_tbl, tbl, sz); rs_toggle_antenna(&(search_tbl->current_rate),
@@ -1045,6 +1216,8 @@ static int rs_move_legacy_other(struct iwl4965_priv *priv,case IWL_LEGACY_SWITCH_SISO :IWL_DEBUG_HT ("LQ: Legacy switch to SISO\n" ); + +/* Set up search table to try SISO */ memcpy (search_tbl, tbl, sz); search_tbl->lq_type =LQ_SISO ; search_tbl->is_SGI =0 ;
@@ -1060,6 +1233,8 @@ static int rs_move_legacy_other(struct iwl4965_priv *priv,break ;case IWL_LEGACY_SWITCH_MIMO :IWL_DEBUG_HT ("LQ: Legacy switch MIMO\n" ); + +/* Set up search table to try MIMO */ memcpy (search_tbl, tbl, sz); search_tbl->lq_type =LQ_MIMO ; search_tbl->is_SGI =0 ;
@@ -1092,6 +1267,9 @@ static int rs_move_legacy_other(struct iwl4965_priv *priv, } +/* +* Try to switch to new modulation mode from SISO +*/ static int rs_move_siso_to_other(struct iwl4965_priv *priv, struct iwl4965_rate_scale_priv *lq_data, struct ieee80211_conf *conf,
@@ -1184,6 +1362,9 @@ static int rs_move_siso_to_other(struct iwl4965_priv *priv,return 0 ; } +/* +* Try to switch to new modulation mode from MIMO +*/ static int rs_move_mimo_to_other(struct iwl4965_priv *priv, struct iwl4965_rate_scale_priv *lq_data, struct ieee80211_conf *conf,
@@ -1206,6 +1387,8 @@ static int rs_move_mimo_to_other(struct iwl4965_priv *priv,case IWL_MIMO_SWITCH_ANTENNA_A :case IWL_MIMO_SWITCH_ANTENNA_B :IWL_DEBUG_HT ("LQ: MIMO SWITCH TO SISO\n" ); + +/* Set up new search table for SISO */ memcpy (search_tbl, tbl, sz); search_tbl->lq_type =LQ_SISO ; search_tbl->is_SGI =0 ;
@@ -1225,6 +1408,8 @@ static int rs_move_mimo_to_other(struct iwl4965_priv *priv,case IWL_MIMO_SWITCH_GI :IWL_DEBUG_HT ("LQ: MIMO SWITCH TO GI\n" ); + +/* Set up new search table for MIMO */ memcpy (search_tbl, tbl, sz); search_tbl->lq_type =LQ_MIMO ; search_tbl->antenna_type =ANT_BOTH ;
@@ -1234,6 +1419,13 @@ static int rs_move_mimo_to_other(struct iwl4965_priv *priv,else search_tbl->is_SGI =1 ; lq_data->search_better_tbl =1 ; + +/* +* If active table already uses the fastest possible +* modulation (dual stream with short guard interval), +* and it's working well, there's no need to look +* for a better type of modulation! +*/ if ((tbl->lq_type ==LQ_MIMO ) && (tbl->is_SGI)) {s32 tpt = lq_data->last_tpt /100 ;
@@ -1266,6 +1458,13 @@ static int rs_move_mimo_to_other(struct iwl4965_priv *priv, } +/* +* Check whether we should continue using same modulation mode, or +* begin search for a new mode, based on: +* 1) # tx successes or failures while using this mode +* 2) # times calling this function +* 3) elapsed time in this mode (not used, for now) +*/ static void rs_stay_in_table (struct iwl4965_rate_scale_priv *lq_data) {struct iwl4965_scale_tbl_info *tbl;
@@ -1277,15 +1476,27 @@ static void rs_stay_in_table(struct iwl4965_rate_scale_priv *lq_data) tbl = &(lq_data->lq_info[active_tbl]); +/* If we've been disallowing search, see if we should now allow it */ if (lq_data->stay_in_tbl) { +/* Elapsed time using current modulation mode */ if (lq_data->flush_timer) flush_interval_passed =time_after (jiffies, (unsigned long )(lq_data->flush_timer +IWL_RATE_SCALE_FLUSH_INTVL )); +/* For now, disable the elapsed time criterion */ flush_interval_passed =0 ; + +/* +* Check if we should allow search for new modulation mode. +* If many frames have failed or succeeded, or we've used +* this same modulation for a long time, allow search, and +* reset history stats that keep track of whether we should +* allow a new search. Also (below) reset all bitmaps and +* stats in active history. +*/ if ((lq_data->total_failed > lq_data->max_failure_limit) || (lq_data->total_success > lq_data->max_success_limit) || ((!lq_data->search_better_tbl) && (lq_data->flush_timer)
@@ -1294,10 +1505,19 @@ static void rs_stay_in_table(struct iwl4965_rate_scale_priv *lq_data) lq_data->total_failed, lq_data->total_success, flush_interval_passed); - lq_data->stay_in_tbl =0 ; + +/* Allow search for new mode */ + lq_data->stay_in_tbl =0 ;/* only place reset */ lq_data->total_failed =0 ; lq_data->total_success =0 ; lq_data->flush_timer =0 ; + +/* +* Else if we've used this modulation mode enough repetitions +* (regardless of elapsed time or success/failure), reset +* history bitmaps and rate-specific stats for all rates in +* active table. +*/ }else { lq_data->table_count++; if (lq_data->table_count >=
@@ -1311,6 +1531,9 @@ static void rs_stay_in_table(struct iwl4965_rate_scale_priv *lq_data) } } +/* If transitioning to allow "search", reset all history +* bitmaps and stats in active table (this will become the new +* "search" table). */ if (!lq_data->stay_in_tbl) {for (i =0 ; i <IWL_RATE_COUNT ; i++)rs_rate_scale_clear_window (&(tbl->win[i]));
@@ -1318,6 +1541,9 @@ static void rs_stay_in_table(struct iwl4965_rate_scale_priv *lq_data) } } +/* +* Do rate scaling and search for new modulation mode. +*/ static void rs_rate_scale_perform(struct iwl4965_priv *priv, struct net_device *dev, struct ieee80211_hdr *hdr,
@@ -1366,6 +1592,11 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, } lq_data = (struct iwl4965_rate_scale_priv *)sta->rate_ctrl_priv; +/* +* Select rate-scale / modulation-mode table to work with in +* the rest of this function: "search" if searching for better +* modulation mode, or "active" if doing rate scaling within a mode. +*/ if (!lq_data->search_better_tbl) active_tbl = lq_data->active_tbl;else
@@ -1374,11 +1605,13 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, tbl = &(lq_data->lq_info[active_tbl]); is_green = lq_data->is_green; +/* current tx rate */ index = sta->last_txrate;IWL_DEBUG_RATE ("Rate scale index %d for type %d\n" , index, tbl->lq_type); +/* rates available for this association, and for modulation mode */ rs_get_supported_rates (lq_data, hdr, tbl->lq_type, &rate_mask);
@@ -1387,6 +1620,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,/* mask with station rate restriction */ if (is_legacy (tbl->lq_type)) {if (lq_data->phymode == (u8 )MODE_IEEE80211A ) +/* supp_rates has no CCK bits in A mode */ rate_scale_index_msk = (u16) (rate_mask & (lq_data->supp_rates <<IWL_FIRST_OFDM_RATE ));else
@@ -1399,11 +1633,13 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,if (!rate_scale_index_msk) rate_scale_index_msk = rate_mask; +/* If current rate is no longer supported on current association, +* or user changed preferences for rates, find a new supported rate. */ if (index <0 || !((1 << index) & rate_scale_index_msk)) { index =IWL_INVALID_VALUE ; update_lq =1 ; -/* get the lowest available rate */ +/* get the highest available rate */ for (i =0 ; i <=IWL_RATE_COUNT ; i++) {if ((1 << i) & rate_scale_index_msk) index = i;
@@ -1415,11 +1651,19 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, } } +/* Get expected throughput table and history window for current rate */ if (!tbl->expected_tpt)rs_get_expected_tpt_table (lq_data, tbl); window = &(tbl->win[index]); +/* +* If there is not enough history to calculate actual average +* throughput, keep analyzing results of more tx frames, without +* changing rate or mode (bypass most of the rest of this function). +* Set up new rate table in uCode only if old rate is not supported +* in current association (use new rate found above). +*/ fail_count = window->counter - window->success_counter;if (((fail_count <IWL_RATE_MIN_FAILURE_TH ) && (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))
@@ -1427,8 +1671,15 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,IWL_DEBUG_RATE ("LQ: still below TH succ %d total %d " "for index %d\n" , window->success_counter, window->counter, index); + +/* Can't calculate this yet; not enough history */ window->average_tpt =IWL_INVALID_VALUE ; + +/* Should we stay with this modulation mode, +* or search for a new one? */ rs_stay_in_table (lq_data); + +/* Set up new rate table in uCode, if needed */ if (update_lq) {rs_mcs_from_tbl (&mcs_rate, tbl, index, is_green);rs_fill_link_cmd (lq_data, &mcs_rate, &lq_data->lq);
@@ -1436,13 +1687,19 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, } goto out; +/* Else we have enough samples; calculate estimate of +* actual average throughput */ }else window->average_tpt = ((window->success_ratio * tbl->expected_tpt[index] +64 ) /128 ); +/* If we are searching for better modulation mode, check success. */ if (lq_data->search_better_tbl) {int success_limit =IWL_RATE_SCALE_SWITCH ; +/* If good success, continue using the "search" mode; +* no need to send new link quality command, since we're +* continuing to use the setup that we've been trying. */ if ((window->success_ratio > success_limit) || (window->average_tpt > lq_data->last_tpt)) {if (!is_legacy (tbl->lq_type)) {
@@ -1454,55 +1711,78 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, lq_data->last_tpt); lq_data->enable_counter =1 ; } +/* Swap tables; "search" becomes "active" */ lq_data->active_tbl = active_tbl; current_tpt = window->average_tpt; + +/* Else poor success; go back to mode in "active" table */ }else { +/* Nullify "search" table */ tbl->lq_type =LQ_NONE ; + +/* Revert to "active" table */ active_tbl = lq_data->active_tbl; tbl = &(lq_data->lq_info[active_tbl]); +/* Revert to "active" rate and throughput info */ index =iwl4965_rate_index_from_plcp ( tbl->current_rate.rate_n_flags); + current_tpt = lq_data->last_tpt; +/* Need to set up a new rate table in uCode */ update_lq =1 ; - current_tpt = lq_data->last_tpt;IWL_DEBUG_HT ("XXY GO BACK TO OLD TABLE\n" ); } + +/* Either way, we've made a decision; modulation mode +* search is done, allow rate adjustment next time. */ lq_data->search_better_tbl =0 ; - done_search =1 ; + done_search =1 ;/* Don't switch modes below! */ goto lq_update; } +/* (Else) not in search of better modulation mode, try for better +* starting rate, while staying in this mode. */ high_low =rs_get_adjacent_rate (index, rate_scale_index_msk, tbl->lq_type); low = high_low &0xff ; high = (high_low >>8 ) &0xff ; +/* Collect measured throughputs for current and adjacent rates */ current_tpt = window->average_tpt; -if (low !=IWL_RATE_INVALID ) low_tpt = tbl->win[low].average_tpt; -if (high !=IWL_RATE_INVALID ) high_tpt = tbl->win[high].average_tpt; - +/* Assume rate increase */ scale_action =1 ; +/* Too many failures, decrease rate */ if ((window->success_ratio <=IWL_RATE_DECREASE_TH ) || (current_tpt ==0 )) {IWL_DEBUG_RATE ("decrease rate because of low success_ratio\n" ); scale_action =-1 ; + +/* No throughput measured yet for adjacent rates; try increase. */ }else if ((low_tpt ==IWL_INVALID_VALUE ) && (high_tpt ==IWL_INVALID_VALUE )) scale_action =1 ; + +/* Both adjacent throughputs are measured, but neither one has better +* throughput; we're using the best rate, don't change it! */ else if ((low_tpt !=IWL_INVALID_VALUE ) && (high_tpt !=IWL_INVALID_VALUE ) && (low_tpt < current_tpt) && (high_tpt < current_tpt)) scale_action =0 ; + +/* At least one adjacent rate's throughput is measured, +* and may have better performance. */ else { +/* Higher adjacent rate's throughput is measured */ if (high_tpt !=IWL_INVALID_VALUE ) { +/* Higher rate has better throughput */ if (high_tpt > current_tpt) scale_action =1 ;else {
@@ -1510,7 +1790,10 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, ("decrease rate because of high tpt\n" ); scale_action =-1 ; } + +/* Lower adjacent rate's throughput is measured */ }else if (low_tpt !=IWL_INVALID_VALUE ) { +/* Lower rate has better throughput */ if (low_tpt > current_tpt) {IWL_DEBUG_RATE ("decrease rate because of low tpt\n" );
@@ -1520,23 +1803,30 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, } } +/* Sanity check; asked for decrease, but success rate or throughput +* has been good at old rate. Don't change it. */ if (scale_action ==-1 ) {if ((low !=IWL_RATE_INVALID ) && ((window->success_ratio >IWL_RATE_HIGH_TH ) || (current_tpt > (100 * tbl->expected_tpt[low])))) scale_action =0 ; + +/* Sanity check; asked for increase, but success rate has not been great +* even at old rate, higher rate will be worse. Don't change it. */ }else if ((scale_action ==1 ) && (window->success_ratio <IWL_RATE_INCREASE_TH )) scale_action =0 ;switch (scale_action) {case -1 : +/* Decrease starting rate, update uCode's rate table */ if (low !=IWL_RATE_INVALID ) { update_lq =1 ; index = low; }break ;case 1 : +/* Increase starting rate, update uCode's rate table */ if (high !=IWL_RATE_INVALID ) { update_lq =1 ; index = high;
@@ -1544,6 +1834,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,break ;case 0 : +/* No change */ default :break ; }
@@ -1553,16 +1844,28 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, index, scale_action, low, high, tbl->lq_type); lq_update: +/* Replace uCode's rate table for the destination station. */ if (update_lq) {rs_mcs_from_tbl (&mcs_rate, tbl, index, is_green);rs_fill_link_cmd (lq_data, &mcs_rate, &lq_data->lq);rs_send_lq_cmd (priv, &lq_data->lq,CMD_ASYNC ); } + +/* Should we stay with this modulation mode, or search for a new one? */ rs_stay_in_table (lq_data); +/* +* Search for new modulation mode if we're: +* 1) Not changing rates right now +* 2) Not just finishing up a search +* 3) Allowing a new search +*/ if (!update_lq && !done_search && !lq_data->stay_in_tbl) { +/* Save current throughput to compare with "search" throughput*/ lq_data->last_tpt = current_tpt; +/* Select a new "search" modulation mode to try. +* If one is found, set up the new "search" table. */ if (is_legacy (tbl->lq_type))rs_move_legacy_other (priv, lq_data, conf, sta, index);else if (is_siso (tbl->lq_type))
@@ -1570,11 +1873,14 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,else rs_move_mimo_to_other (priv, lq_data, conf, sta, index); +/* If new "search" mode was selected, set up in uCode table */ if (lq_data->search_better_tbl) { +/* Access the "search" table, clear its history. */ tbl = &(lq_data->lq_info[(1 - lq_data->active_tbl)]);for (i =0 ; i <IWL_RATE_COUNT ; i++)rs_rate_scale_clear_window (&(tbl->win[i])); +/* Use new "search" start rate */ index =iwl4965_rate_index_from_plcp ( tbl->current_rate.rate_n_flags);
@@ -1584,8 +1890,13 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, &lq_data->lq);rs_send_lq_cmd (priv, &lq_data->lq,CMD_ASYNC ); } - tbl1 = &(lq_data->lq_info[lq_data->active_tbl]); +/* If the "active" (non-search) mode was legacy, +* and we've tried switching antennas, +* but we haven't been able to try HT modes (not available), +* stay with best antenna legacy modulation for a while +* before next round of mode comparisons. */ + tbl1 = &(lq_data->lq_info[lq_data->active_tbl]); if (is_legacy(tbl1->lq_type) && #ifdef CONFIG_IWL4965_HT (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) &&
@@ -1596,9 +1907,13 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,rs_set_stay_in_table (1 , lq_data); } +/* If we're in an HT mode, and all 3 mode switch actions +* have been tried and compared, stay in this best modulation +* mode for a while before next round of mode comparisons. */ if (lq_data->enable_counter && (lq_data->action_counter >=IWL_ACTION_LIMIT )) {#ifdef CONFIG_IWL4965_HT_AGG +/* If appropriate, set up aggregation! */ if ((lq_data->last_tpt >TID_AGG_TPT_THREHOLD ) && (priv->lq_mngr.agg_ctrl.auto_agg)) { priv->lq_mngr.agg_ctrl.tid_retry =
@@ -1609,6 +1924,14 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, lq_data->action_counter =0 ;rs_set_stay_in_table (0 , lq_data); } + +/* +* Else, don't search for a new modulation mode. +* Put new timestamp in stay-in-modulation-mode flush timer if: +* 1) Not changing rates right now +* 2) Not just finishing up a search +* 3) flush timer is empty +*/ }else {if ((!update_lq) && (!done_search) && (!lq_data->flush_timer)) lq_data->flush_timer = jiffies;
@@ -1834,15 +2157,14 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, priv->assoc_station_added =1 ; } +/* Find highest tx rate supported by hardware and destination station */ for (i =0 ; i < mode->num_rates; i++) {if ((sta->supp_rates &BIT (i)) && (mode->rates[i].flags &IEEE80211_RATE_SUPPORTED )) sta->txrate = i; } sta->last_txrate = sta->txrate; -/* For MODE_IEEE80211A mode cck rate are at end -* rate table -*/ +/* For MODE_IEEE80211A, cck rates are at end of rate table */ if (local->hw.conf.phymode ==MODE_IEEE80211A ) sta->last_txrate +=IWL_FIRST_OFDM_RATE ;
@@ -1855,12 +2177,18 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, crl->active_rate_basic = priv->active_rate_basic; crl->phymode = priv->phymode;#ifdef CONFIG_IWL4965_HT +/* +* active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), +* supp_rates[] does not; shift to convert format, force 9 MBits off. +*/ + crl->active_siso_rate = (priv->current_ht_config.supp_mcs_set[0 ] <<1 ); crl->active_siso_rate |= (priv->current_ht_config.supp_mcs_set[0 ] &0x1 ); crl->active_siso_rate &= ~((u16 )0x2 ); crl->active_siso_rate = crl->active_siso_rate <<IWL_FIRST_OFDM_RATE ; +/* Same here */ crl->active_mimo_rate = (priv->current_ht_config.supp_mcs_set[1 ] <<1 ); crl->active_mimo_rate |= (priv->current_ht_config.supp_mcs_set[1 ] &0x1 );
@@ -1891,11 +2219,14 @@ static void rs_fill_link_cmd(struct iwl4965_rate_scale_priv *lq_data,struct iwl4965_rate new_rate;struct iwl4965_scale_tbl_info tbl_type = {0 }; +/* Override starting rate (index 0) if needed for debug purposes */ rs_dbgfs_set_mcs (lq_data, tx_mcs, index); +/* Interpret rate_n_flags */ rs_get_tbl_info_from_mcs (tx_mcs, lq_data->phymode, &tbl_type, &rate_idx); +/* How many times should we repeat the initial rate? */ if (is_legacy (tbl_type.lq_type)) { ant_toggle_count =1 ; repeat_rate =IWL_NUMBER_TRY ;
@@ -1904,19 +2235,27 @@ static void rs_fill_link_cmd(struct iwl4965_rate_scale_priv *lq_data, lq_cmd->general_params.mimo_delimiter =is_mimo (tbl_type.lq_type) ?1 :0 ; + +/* Fill 1st table entry (index 0) */ lq_cmd->rs_table[index].rate_n_flags =cpu_to_le32 (tx_mcs->rate_n_flags); new_rate.rate_n_flags = tx_mcs->rate_n_flags;if (is_mimo (tbl_type.lq_type) || (tbl_type.antenna_type ==ANT_MAIN )) - lq_cmd->general_params.single_stream_ant_msk =1 ; + lq_cmd->general_params.single_stream_ant_msk + =LINK_QUAL_ANT_A_MSK ;else - lq_cmd->general_params.single_stream_ant_msk =2 ; + lq_cmd->general_params.single_stream_ant_msk + =LINK_QUAL_ANT_B_MSK ; index++; repeat_rate--; +/* Fill rest of rate table */ while (index <LINK_QUAL_MAX_RETRY_NUM ) { +/* Repeat initial/next rate. +* For legacy IWL_NUMBER_TRY == 1, this loop will not execute. +* For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */ while (repeat_rate >0 && (index <LINK_QUAL_MAX_RETRY_NUM )) {if (is_legacy (tbl_type.lq_type)) { if (ant_toggle_count <
@@ -1928,7 +2267,10 @@ static void rs_fill_link_cmd(struct iwl4965_rate_scale_priv *lq_data, } } +/* Override next rate if needed for debug purposes */ rs_dbgfs_set_mcs (lq_data, &new_rate, index); + +/* Fill next table entry */ lq_cmd->rs_table[index].rate_n_flags =cpu_to_le32 (new_rate.rate_n_flags); repeat_rate--;
@@ -1938,12 +2280,17 @@ static void rs_fill_link_cmd(struct iwl4965_rate_scale_priv *lq_data,rs_get_tbl_info_from_mcs (&new_rate, lq_data->phymode, &tbl_type, &rate_idx); +/* Indicate to uCode which entries might be MIMO. +* If initial rate was MIMO, this will finally end up +* as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */ if (is_mimo (tbl_type.lq_type)) lq_cmd->general_params.mimo_delimiter = index; +/* Get next rate */ rs_get_lower_rate (lq_data, &tbl_type, rate_idx, use_ht_possible, &new_rate); +/* How many times should we repeat the next rate? */ if (is_legacy (tbl_type.lq_type)) {if (ant_toggle_count <NUM_TRY_BEFORE_ANTENNA_TOGGLE ) ant_toggle_count++;
@@ -1955,9 +2302,14 @@ static void rs_fill_link_cmd(struct iwl4965_rate_scale_priv *lq_data, }else repeat_rate =IWL_HT_NUMBER_TRY ; +/* Don't allow HT rates after next pass. +* rs_get_lower_rate() will change type to LQ_A or LQ_G. */ use_ht_possible =0 ; +/* Override next rate if needed for debug purposes */ rs_dbgfs_set_mcs (lq_data, &new_rate, index); + +/* Fill next table entry */ lq_cmd->rs_table[index].rate_n_flags =cpu_to_le32 (new_rate.rate_n_flags);
@@ -2053,9 +2405,9 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,else rs_priv->dbg_fixed.rate_n_flags =0 ; - rs_priv->active_rate =0x0FFF ; - rs_priv->active_siso_rate =0x1FD0 ; - rs_priv->active_mimo_rate =0x1FD0 ; + rs_priv->active_rate =0x0FFF ;/* 1 - 54 MBits, includes CCK */ + rs_priv->active_siso_rate =0x1FD0 ;/* 6 - 60 MBits, no 9, no CCK */ + rs_priv->active_mimo_rate =0x1FD0 ;/* 6 - 60 MBits, no 9, no CCK */ IWL_DEBUG_RATE ("sta_id %d rate 0x%X\n" , rs_priv->lq.sta_id, rs_priv->dbg_fixed.rate_n_flags);
@@ -2256,7 +2608,7 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)/* Display the average rate of all samples taken. * -* NOTE: We multiple # of samples by 2 since the IEEE measurement +* NOTE: We multiply # of samples by 2 since the IEEE measurement * added from iwl4965_rates is actually 2X the rate */ if (samples) count += sprintf(&buf[count],
drivers/net/wireless/iwlwifi/iwl-4965-rs.h +29 -16
106 lines not on this page · raw message
drivers/net/wireless/iwlwifi/iwl-4965.h +1 -1
@@ -483,7 +483,7 @@ struct iwl_ht_info {u8 supported_chan_width;u16 tx_mimo_ps_mode;u8 is_green_field; -u8 sgf; +u8 sgf;/* HT_SHORT_GI_* short guard interval */ u8 max_amsdu_size;u8 ampdu_factor;u8 mpdu_density;
drivers/net/wireless/iwlwifi/iwl4965-base.c +3 -0
@@ -1504,6 +1504,7 @@ int iwl4965_rate_index_from_plcp(int plcp) {int i =0 ; +/* 4965 HT rate format */ if (plcp &RATE_MCS_HT_MSK ) { i = (plcp &0xff );
@@ -1517,6 +1518,8 @@ int iwl4965_rate_index_from_plcp(int plcp)if ((i >=IWL_FIRST_OFDM_RATE ) && (i <=IWL_LAST_OFDM_RATE ))return i; + +/* 4965 legacy rate format, search for match in table */ }else {for (i =0 ; i <ARRAY_SIZE (iwl4965_rates); i++)if (iwl4965_rates[i].plcp == (plcp &0xFF ))
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 5/34 iwlwifi: add comments to EEPROM stuff
From: Ben Cahill <[email protected]>
Add comments to EEPROM stuff.
--- drivers/net/wireless/iwlwifi/iwl-3945-hw.h | 94 +++++++++++-- drivers/net/wireless/iwlwifi/iwl-3945.c | 9 ++ drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 209 +++++++++++++++++++++++++--- drivers/net/wireless/iwlwifi/iwl-4965.c | 9 ++ 4 files changed, 285 insertions(+), 36 deletions(-)
drivers/net/wireless/iwlwifi/iwl-3945-hw.h +81 -13
@@ -85,24 +85,48 @@#define IWL_RSSI_OFFSET 95/* -* This file defines EEPROM related constants, enums, and inline functions. -* +* EEPROM related constants, enums, and structures. */ +/* +* EEPROM access time values: +* +* Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG, +* then clearing (with subsequent read/modify/write) CSR_EEPROM_REG bit +* CSR_EEPROM_REG_BIT_CMD (0x2). +* Driver then polls CSR_EEPROM_REG for CSR_EEPROM_REG_READ_VALID_MSK (0x1). +* When polling, wait 10 uSec between polling loops, up to a maximum 5000 uSec. +* Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG. +*/ #define IWL_EEPROM_ACCESS_TIMEOUT 5000/* uSec */ #define IWL_EEPROM_ACCESS_DELAY 10/* uSec */ +/* EEPROM field values */ #define ANTENNA_SWITCH_NORMAL 0#define ANTENNA_SWITCH_INVERSE 1 +/* +* Regulatory channel usage flags in EEPROM struct iwl_eeprom_channel.flags. +* +* IBSS and/or AP operation is allowed *only* on those channels with +* (VALID && IBSS && ACTIVE && !RADAR). This restriction is in place because +* RADAR detection is not supported by the 3945 driver, but is a +* requirement for establishing a new network for legal operation on channels +* requiring RADAR detection or restricting ACTIVE scanning. +* +* NOTE: "WIDE" flag indicates that 20 MHz channel is supported; +* 3945 does not support FAT 40 MHz-wide channels. +* +* NOTE: Using a channel inappropriately will result in a uCode error! +*/ enum {EEPROM_CHANNEL_VALID = (1 <<0 ),/* usable for this SKU/geo */ -EEPROM_CHANNEL_IBSS = (1 <<1 ),/* usable as an IBSS channel */ +EEPROM_CHANNEL_IBSS = (1 <<1 ),/* usable as an IBSS channel */ /* Bit 2 Reserved */ EEPROM_CHANNEL_ACTIVE = (1 <<3 ),/* active scanning allowed */ EEPROM_CHANNEL_RADAR = (1 <<4 ),/* radar detection required */ -EEPROM_CHANNEL_WIDE = (1 <<5 ), -EEPROM_CHANNEL_NARROW = (1 <<6 ), +EEPROM_CHANNEL_WIDE = (1 <<5 ),/* 20 MHz channel okay */ +EEPROM_CHANNEL_NARROW = (1 <<6 ),/* 10 MHz channel, not used */ EEPROM_CHANNEL_DFS = (1 <<7 ),/* dynamic freq selection candidate */ };
@@ -147,6 +171,7 @@ struct iwl3945_eeprom_channel {* long packets in normal operation to provide feedback as to proper output * level. * Data copied from EEPROM. +* DO NOT ALTER THIS STRUCTURE!!! */ struct iwl3945_eeprom_txpower_sample {u8 gain_index;/* index into power (gain) setup table ... */
@@ -163,11 +188,11 @@ struct iwl3945_eeprom_txpower_sample {* DO NOT ALTER THIS STRUCTURE!!! */ struct iwl3945_eeprom_txpower_group { -struct iwl3945_eeprom_txpower_sample samples[5 ];/* 5 power levels */ +struct iwl3945_eeprom_txpower_sample samples[5 ];/* 5 power levels */ s32 a, b, c, d, e;/* coefficients for voltage->power * formula (signed) */ s32 Fa, Fb, Fc, Fd, Fe;/* these modify coeffs based on -* frequency (signed) */ +* frequency (signed) */ s8 saturation_power;/* highest power possible by h/w in this * band */ u8 group_channel;/* "representative" channel # in this band */
@@ -189,6 +214,9 @@ struct iwl3945_eeprom_temperature_corr {u32 Te; } __attribute__ ((packed)); +/* +* EEPROM map +*/ struct iwl3945_eeprom {u8 reserved0[16 ];#define EEPROM_DEVICE_ID (2*0x08)/* 2 bytes */
@@ -229,29 +257,67 @@ struct iwl3945_eeprom {u8 reserved6[42 ];#define EEPROM_REGULATORY_SKU_ID (2*0x60)/* 4 bytes */ u8 sku_id[4 ];/* abs.ofs: 192 */ + +/* +* Per-channel regulatory data. +* +* Each channel that *might* be supported by 3945 or 4965 has a fixed location +* in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory +* txpower (MSB). +* +* Entries immediately below are for 20 MHz channel width. FAT (40 MHz) +* channels (only for 4965, not supported by 3945) appear later in the EEPROM. +* +* 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 +*/ #define EEPROM_REGULATORY_BAND_1 (2*0x62)/* 2 bytes */ u16 band_1_count;/* abs.ofs: 196 */ #define EEPROM_REGULATORY_BAND_1_CHANNELS (2*0x63)/* 28 bytes */ -struct iwl3945_eeprom_channel band_1_channels[14 ];/* abs.ofs: 196 */ +struct iwl3945_eeprom_channel band_1_channels[14 ];/* abs.ofs: 196 */ + +/* +* 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196, +* 5.0 GHz channels 7, 8, 11, 12, 16 +* (4915-5080MHz) (none of these is ever supported) +*/ #define EEPROM_REGULATORY_BAND_2 (2*0x71)/* 2 bytes */ u16 band_2_count;/* abs.ofs: 226 */ #define EEPROM_REGULATORY_BAND_2_CHANNELS (2*0x72)/* 26 bytes */ -struct iwl3945_eeprom_channel band_2_channels[13 ];/* abs.ofs: 228 */ +struct iwl3945_eeprom_channel band_2_channels[13 ];/* abs.ofs: 228 */ + +/* +* 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 +* (5170-5320MHz) +*/ #define EEPROM_REGULATORY_BAND_3 (2*0x7F)/* 2 bytes */ u16 band_3_count;/* abs.ofs: 254 */ #define EEPROM_REGULATORY_BAND_3_CHANNELS (2*0x80)/* 24 bytes */ -struct iwl3945_eeprom_channel band_3_channels[12 ];/* abs.ofs: 256 */ +struct iwl3945_eeprom_channel band_3_channels[12 ];/* abs.ofs: 256 */ + +/* +* 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 +* (5500-5700MHz) +*/ #define EEPROM_REGULATORY_BAND_4 (2*0x8C)/* 2 bytes */ u16 band_4_count;/* abs.ofs: 280 */ #define EEPROM_REGULATORY_BAND_4_CHANNELS (2*0x8D)/* 22 bytes */ -struct iwl3945_eeprom_channel band_4_channels[11 ];/* abs.ofs: 282 */ +struct iwl3945_eeprom_channel band_4_channels[11 ];/* abs.ofs: 282 */ + +/* +* 5.7 GHz channels 145, 149, 153, 157, 161, 165 +* (5725-5825MHz) +*/ #define EEPROM_REGULATORY_BAND_5 (2*0x98)/* 2 bytes */ u16 band_5_count;/* abs.ofs: 304 */ #define EEPROM_REGULATORY_BAND_5_CHANNELS (2*0x99)/* 12 bytes */ -struct iwl3945_eeprom_channel band_5_channels[6 ];/* abs.ofs: 306 */ +struct iwl3945_eeprom_channel band_5_channels[6 ];/* abs.ofs: 306 */ u8 reserved9[194 ]; + +/* +* 3945 Txpower calibration data. +*/ #define EEPROM_TXPOWER_CALIB_GROUP0 0x200#define EEPROM_TXPOWER_CALIB_GROUP1 0x240#define EEPROM_TXPOWER_CALIB_GROUP2 0x280
@@ -261,12 +327,14 @@ struct iwl3945_eeprom {struct iwl3945_eeprom_txpower_group groups[IWL_NUM_TX_CALIB_GROUPS ];/* abs.ofs: 512 */ #define EEPROM_CALIB_TEMPERATURE_CORRECT 0x340 -struct iwl3945_eeprom_temperature_corr corrections;/* abs.ofs: 832 */ +struct iwl3945_eeprom_temperature_corr corrections;/* abs.ofs: 832 */ u8 reserved16[172 ];/* fill out to full 1024 byte block */ } __attribute__ ((packed));#define IWL_EEPROM_IMAGE_SIZE 1024 +/* End of EEPROM */ +#include "iwl-3945-commands.h"
drivers/net/wireless/iwlwifi/iwl-3945.c +9 -0
@@ -2202,6 +2202,7 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv) &rate_cmd); } +/* Called when initializing driver */ int iwl3945_hw_set_hw_setting (struct iwl3945_priv *priv) { memset((void *)&priv->hw_setting, 0,
@@ -2285,6 +2286,14 @@ struct pci_device_id iwl3945_hw_card_ids[] = { {0} }; +/* +* Clear the OWNER_MSK, to establish driver (instead of uCode running on +* embedded controller) as EEPROM reader; each read is a series of pulses +* to/from the EEPROM chip, not a single event, so even reads could conflict +* if they weren't arbitrated by some ownership mechanism. Here, the driver +* simply claims ownership, which should be safe when this function is called +* (i.e. before loading uCode!). +*/ inline int iwl3945_eeprom_acquire_semaphore (struct iwl3945_priv *priv) {_iwl3945_clear_bit (priv,CSR_EEPROM_GP ,CSR_EEPROM_GP_IF_OWNER_MSK );
drivers/net/wireless/iwlwifi/iwl-4965-hw.h +186 -23
309 lines not on this page · raw message
drivers/net/wireless/iwlwifi/iwl-4965.c +9 -0
@@ -4717,14 +4717,23 @@ struct pci_device_id iwl4965_hw_card_ids[] = { {0} }; +/* +* The device's EEPROM semaphore prevents conflicts between driver and uCode +* when accessing the EEPROM; each access is a series of pulses to/from the +* EEPROM chip, not a single event, so even reads could conflict if they +* weren't arbitrated by the semaphore. +*/ int iwl4965_eeprom_acquire_semaphore (struct iwl4965_priv *priv) {u16 count;int rc;for (count =0 ; count <EEPROM_SEM_RETRY_LIMIT ; count++) { +/* Request semaphore */ iwl4965_set_bit (priv,CSR_HW_IF_CONFIG_REG ,CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM ); + +/* See if we got it */ rc = iwl4965_poll_bit(priv, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 6/34 iwl-4965-hw.h: clean up unused eeprom structures and definitions
From: Ben Cahill <[email protected]>
Clean up unused eeprom structures and definitions in iwl-4965-hw.h.
--- drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 58 +--------------------------- 1 files changed, 1 insertions(+), 57 deletions(-)
drivers/net/wireless/iwlwifi/iwl-4965-hw.h +1 -57
@@ -169,57 +169,6 @@ struct iwl4965_eeprom_channel {s8 max_power_avg;/* max power (dBm) on this chnl, limit 31 */ } __attribute__ ((packed)); -/* -* Mapping of a Tx power level, at factory calibration temperature, -* to a radio/DSP gain table index. -* One for each of 5 "sample" power levels in each band. -* v_det is measured at the factory, using the 3945's built-in power amplifier -* (PA) output voltage detector. This same detector is used during Tx of -* long packets in normal operation to provide feedback as to proper output -* level. -* Data copied from EEPROM. -*/ -struct iwl4965_eeprom_txpower_sample { -u8 gain_index;/* index into power (gain) setup table ... */ -s8 power;/* ... for this pwr level for this chnl group */ -u16 v_det;/* PA output voltage */ -} __attribute__ ((packed)); - -/* -* Mappings of Tx power levels -> nominal radio/DSP gain table indexes. -* One for each channel group (a.k.a. "band") (1 for BG, 4 for A). -* Tx power setup code interpolates between the 5 "sample" power levels -* to determine the nominal setup for a requested power level. -* Data copied from EEPROM. -* DO NOT ALTER THIS STRUCTURE!!! -*/ -struct iwl4965_eeprom_txpower_group { -struct iwl4965_eeprom_txpower_sample samples[5 ];/* 5 power levels */ -s32 a, b, c, d, e;/* coefficients for voltage->power -* formula (signed) */ -s32 Fa, Fb, Fc, Fd, Fe;/* these modify coeffs based on -* frequency (signed) */ -s8 saturation_power;/* highest power possible by h/w in this -* band */ -u8 group_channel;/* "representative" channel # in this band */ -s16 temperature;/* h/w temperature at factory calib this band -* (signed) */ -} __attribute__ ((packed)); - -/* -* Temperature-based Tx-power compensation data, not band-specific. -* These coefficients are use to modify a/b/c/d/e coeffs based on -* difference between current temperature and factory calib temperature. -* Data copied from EEPROM. -*/ -struct iwl4965_eeprom_temperature_corr { -u32 Ta; -u32 Tb; -u32 Tc; -u32 Td; -u32 Te; -} __attribute__ ((packed)); -/* 4965 has two radio transmitters (and 3 radio receivers) */ #define EEPROM_TX_POWER_TX_CHAINS (2)
@@ -230,8 +179,6 @@ struct iwl4965_eeprom_temperature_corr {* each of 3 target output levels */ #define EEPROM_TX_POWER_MEASUREMENTS (3) -#define EEPROM_TX_POWER_VERSION (2) -/* 4965 driver does not work with txpower calibration version < 5. * Look for this in calib_version member of struct iwl4965_eeprom. */ #define EEPROM_TX_POWER_VERSION_NEW (5)
@@ -461,10 +408,7 @@ struct iwl4965_eeprom {#define EEPROM_CALIB_VERSION_OFFSET (2*0xB6)/* 2 bytes */ u16 calib_version;/* abs.ofs: 364 */ u8 reserved13[2 ]; - -#define EEPROM_SATURATION_POWER_OFFSET (2*0xB8)/* 2 bytes */ -u16 satruation_power;/* abs.ofs: 368 */ -u8 reserved14[94 ]; +u8 reserved14[96 ];/* abs.ofs: 368 */ /* * 4965 Txpower calibration data.
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 7/34 iwlwifi: clean up and clarify some comments after 3945/4965 split
From: Ben Cahill <[email protected]>
Clean up and clarify some comments after 3945/4965 split.
--- drivers/net/wireless/iwlwifi/iwl-3945-rs.h | 11 ++- drivers/net/wireless/iwlwifi/iwl-4965-rs.h | 5 +- drivers/net/wireless/iwlwifi/iwl3945-base.c | 126 ++++++++------------- drivers/net/wireless/iwlwifi/iwl4965-base.c | 163 ++++++++++++--------------- 4 files changed, 132 insertions(+), 173 deletions(-)
drivers/net/wireless/iwlwifi/iwl-3945-rs.h +8 -3
@@ -28,8 +28,8 @@#define __iwl_3945_rs_h__struct iwl3945_rate_info { -u8 plcp; -u8 ieee; +u8 plcp;/* uCode API: IWL_RATE_6M_PLCP, etc. */ +u8 ieee;/* MAC header: IWL_RATE_6M_IEEE, etc. */ u8 prev_ieee;/* previous rate in IEEE speeds */ u8 next_ieee;/* next rate in IEEE speeds */ u8 prev_rs;/* previous rate used in rs algo */
@@ -38,9 +38,12 @@ struct iwl3945_rate_info {u8 next_rs_tgg;/* next rate used in TGG rs algo */ u8 table_rs_index;/* index in rate scale table cmd */ u8 prev_table_rs;/* prev in rate table cmd */ - }; +/* +* These serve as indexes into +* struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT]; +*/ enum {IWL_RATE_1M_INDEX =0 ,IWL_RATE_2M_INDEX ,
@@ -96,6 +99,7 @@ enum {#define IWL_RATE_5M_MASK (1<<IWL_RATE_5M_INDEX)#define IWL_RATE_11M_MASK (1<<IWL_RATE_11M_INDEX) +/* 3945 uCode API values for (legacy) bit rates, both OFDM and CCK */ enum {IWL_RATE_6M_PLCP =13 ,IWL_RATE_9M_PLCP =15 ,
@@ -111,6 +115,7 @@ enum { IWL_RATE_11M_PLCP = 110, }; +/* MAC header values for bit rates */ enum {IWL_RATE_6M_IEEE =12 ,IWL_RATE_9M_IEEE =18 ,
drivers/net/wireless/iwlwifi/iwl-4965-rs.h +4 -1
@@ -42,7 +42,10 @@ struct iwl4965_rate_info {u8 next_rs_tgg;/* next rate used in TGG rs algo */ }; -/* For driver (not uCode API) */ +/* +* These serve as indexes into +* struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT]; +*/ enum {IWL_RATE_1M_INDEX =0 ,IWL_RATE_2M_INDEX ,
drivers/net/wireless/iwlwifi/iwl3945-base.c +47 -79
321 lines not on this page · raw message
drivers/net/wireless/iwlwifi/iwl4965-base.c +73 -90
426 lines not on this page · raw message
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 8/34 iwlwifi: Move is_legacy() macro family from iwl-4965-hw.h to iwl-4965-rs.h
From: Ben Cahill <[email protected]>
Move is_legacy() macro family from iwl-4965-hw.h to iwl-4965-rs.h
These macros are for driver's rate scaling implementation, and are not related to hardware or uCode API values (moved from iwl-4965-hw.h).
--- drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 7 ------- drivers/net/wireless/iwlwifi/iwl-4965-rs.h | 7 +++++++ 2 files changed, 7 insertions(+), 7 deletions(-)
drivers/net/wireless/iwlwifi/iwl-4965-hw.h +0 -7
@@ -1036,13 +1036,6 @@ union iwl4965_tx_power_dual_stream {#define R_MCS_36M_DUAL_MSK 0x400#define R_MCS_48M_DUAL_MSK 0x800 -#define is_legacy (tbl) (((tbl) == LQ_G) || ((tbl) == LQ_A)) -#define is_siso (tbl) (((tbl) == LQ_SISO)) -#define is_mimo (tbl) (((tbl) == LQ_MIMO)) -#define is_Ht (tbl) (is_siso(tbl) || is_mimo(tbl)) -#define is_a_band (tbl) (((tbl) == LQ_A)) -#define is_g_and (tbl) (((tbl) == LQ_G)) -/* Flow Handler Definitions */ /**********************/
drivers/net/wireless/iwlwifi/iwl-4965-rs.h +7 -0
@@ -223,6 +223,13 @@ enum iwl4965_table_type { LQ_MAX, }; +#define is_legacy (tbl) (((tbl) == LQ_G) || ((tbl) == LQ_A)) +#define is_siso (tbl) (((tbl) == LQ_SISO)) +#define is_mimo (tbl) (((tbl) == LQ_MIMO)) +#define is_Ht (tbl) (is_siso(tbl) || is_mimo(tbl)) +#define is_a_band (tbl) (((tbl) == LQ_A)) +#define is_g_and (tbl) (((tbl) == LQ_G)) +/* 4965 has 2 antennas/chains for Tx (but 3 for Rx) */ enum iwl4965_antenna_type {ANT_NONE ,
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 9/34 iwlwifi: Add comments to some driver data structures
From: Ben Cahill <[email protected]>
Add comments to some driver data structures
Remove unused "sched_retry" member from struct iwl3945_tx_queue
--- drivers/net/wireless/iwlwifi/iwl-3945.h | 35 ++++++++++++++++++-- drivers/net/wireless/iwlwifi/iwl-4965.h | 53 ++++++++++++++++++++++++++++--- 2 files changed, 79 insertions(+), 9 deletions(-)
drivers/net/wireless/iwlwifi/iwl-3945.h +31 -4
@@ -131,6 +131,7 @@ struct iwl3945_queue {#define MAX_NUM_OF_TBS (20) +/* One for each TFD */ struct iwl3945_tx_info {struct ieee80211_tx_status status;struct sk_buff *skb[MAX_NUM_OF_TBS ];
@@ -138,10 +139,15 @@ struct iwl3945_tx_info {/** * struct iwl3945_tx_queue - Tx Queue for DMA -* @need_update: need to update read/write index -* @shed_retry: queue is HT AGG enabled +* @q: generic Rx/Tx queue descriptor +* @bd: base of circular buffer of TFDs +* @cmd: array of command/Tx buffers +* @dma_addr_cmd: physical address of cmd/tx buffer array +* @txb: array of per-TFD driver data +* @need_update: indicates need to update read/write index * -* Queue consists of circular buffer of BD's and required locking structures. +* A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame +* descriptors) and required locking structures. */ struct iwl3945_tx_queue {struct iwl3945_queue q;
@@ -150,7 +156,6 @@ struct iwl3945_tx_queue {dma_addr_t dma_addr_cmd;struct iwl3945_tx_info *txb;int need_update; -int sched_retry;int active; };
@@ -326,6 +331,13 @@ struct iwl3945_cmd_meta { } __attribute__ ((packed)); +/** +* struct iwl3945_cmd +* +* For allocation of the command and tx queues, this establishes the overall +* size of the largest command we send to uCode, except for a scan command +* (which is relatively huge; space is allocated separately). +*/ struct iwl3945_cmd {struct iwl3945_cmd_meta meta;struct iwl3945_cmd_header hdr;
@@ -523,6 +535,19 @@ struct iwl3945_ibss_seq {struct list_head list; }; +/** +* struct iwl4965_driver_hw_info +* @max_txq_num: Max # Tx queues supported +* @ac_queue_count: # Tx queues for EDCA Access Categories (AC) +* @tx_cmd_len: Size of Tx command (but not including frame itself) +* @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2) +* @rx_buffer_size: +* @max_rxq_log: Log-base-2 of max_rxq_size +* @max_stations: +* @bcast_sta_id: +* @shared_virt: Pointer to driver/uCode shared Tx Byte Counts and Rx status +* @shared_phys: Physical Pointer to Tx Byte Counts and Rx status +*/ struct iwl3945_driver_hw_info {u16 max_txq_num;u16 ac_queue_count;
@@ -860,6 +885,8 @@ struct iwl3945_priv {u16 last_seq_num;u16 last_frag_num;unsigned long last_packet_time; + +/* Hash table for finding stations in IBSS network */ struct list_head ibss_mac_hash[IWL_IBSS_MAC_HASH_SIZE ];/* eeprom */
drivers/net/wireless/iwlwifi/iwl-4965.h +48 -5
91 lines not on this page · raw message
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 10/34 iwlwifi: Document 4965 rate_n_flags bits
From: Ben Cahill <[email protected]>
Document 4965 rate_n_flags bits
--- drivers/net/wireless/iwlwifi/iwl-4965-commands.h | 98 +++++++++++++++++++--- drivers/net/wireless/iwlwifi/iwl-4965.h | 30 ++----- 2 files changed, 92 insertions(+), 36 deletions(-)
drivers/net/wireless/iwlwifi/iwl-4965-commands.h +85 -13
@@ -141,7 +141,8 @@ enum {/****************************************************************************** * (0) -* Header +* Commonly used structures and definitions: +* Command header, rate_n_flags * *****************************************************************************/
@@ -167,6 +168,89 @@ struct iwl4965_cmd_header {u8 data[0 ]; } __attribute__ ((packed)); +/** +* 4965 rate_n_flags bit fields +* +* rate_n_flags format is used in following 4965 commands: +* REPLY_4965_RX (response only) +* REPLY_TX (both command and response) +* REPLY_TX_LINK_QUALITY_CMD +* +* High-throughput (HT) rate format for bits 7:0 (bit 8 must be "1"): +* 2-0: 0) 6 Mbps +* 1) 12 Mbps +* 2) 18 Mbps +* 3) 24 Mbps +* 4) 36 Mbps +* 5) 48 Mbps +* 6) 54 Mbps +* 7) 60 Mbps +* +* 3: 0) Single stream (SISO) +* 1) Dual stream (MIMO) +* +* 5: Value of 0x20 in bits 7:0 indicates 6 Mbps FAT duplicate data +* +* Legacy OFDM rate format for bits 7:0 (bit 8 must be "0", bit 9 "0"): +* 3-0: 0xD) 6 Mbps +* 0xF) 9 Mbps +* 0x5) 12 Mbps +* 0x7) 18 Mbps +* 0x9) 24 Mbps +* 0xB) 36 Mbps +* 0x1) 48 Mbps +* 0x3) 54 Mbps +* +* Legacy CCK rate format for bits 7:0 (bit 8 must be "0", bit 9 "1"): +* 3-0: 10) 1 Mbps +* 20) 2 Mbps +* 55) 5.5 Mbps +* 110) 11 Mbps +*/ +#define RATE_MCS_CODE_MSK 0x7 +#define RATE_MCS_MIMO_POS 3 +#define RATE_MCS_MIMO_MSK 0x8 +#define RATE_MCS_HT_DUP_POS 5 +#define RATE_MCS_HT_DUP_MSK 0x20 + +/* (1) HT format, (0) legacy format in bits 7:0 */ +#define RATE_MCS_FLAGS_POS 8 +#define RATE_MCS_HT_POS 8 +#define RATE_MCS_HT_MSK 0x100 + +/* (1) CCK, (0) OFDM. HT (bit 8) must be "0" for this bit to be valid */ +#define RATE_MCS_CCK_POS 9 +#define RATE_MCS_CCK_MSK 0x200 + +/* (1) Use Green Field preamble */ +#define RATE_MCS_GF_POS 10 +#define RATE_MCS_GF_MSK 0x400 + +/* (1) Use 40Mhz FAT channel width, (0) use 20 MHz legacy channel width */ +#define RATE_MCS_FAT_POS 11 +#define RATE_MCS_FAT_MSK 0x800 + +/* (1) Duplicate data on both 20MHz channels. FAT (bit 11) must be set. */ +#define RATE_MCS_DUP_POS 12 +#define RATE_MCS_DUP_MSK 0x1000 + +/* (1) Short guard interval (0.4 usec), (0) normal GI (0.8 usec) */ +#define RATE_MCS_SGI_POS 13 +#define RATE_MCS_SGI_MSK 0x2000 + +/** +* rate_n_flags Tx antenna masks (4965 has 2 transmitters): +* bit14:15 01 B inactive, A active +* 10 B active, A inactive +* 11 Both active +*/ +#define RATE_MCS_ANT_A_POS 14 +#define RATE_MCS_ANT_B_POS 15 +#define RATE_MCS_ANT_A_MSK 0x4000 +#define RATE_MCS_ANT_B_MSK 0x8000 +#define RATE_MCS_ANT_AB_MSK 0xc000 + +/****************************************************************************** * (0a) * Alive and Error Commands & Responses:
@@ -452,18 +536,6 @@ struct iwl4965_qosparam_cmd {#define STA_MODIFY_DELBA_TID_MSK 0x10#define BUILD_RAxTID (sta_id, tid) (((sta_id) << 4) + (tid)) -/* -* Antenna masks: -* bit14:15 01 B inactive, A active -* 10 B active, A inactive -* 11 Both active -*/ -#define RATE_MCS_ANT_A_POS 14 -#define RATE_MCS_ANT_B_POS 15 -#define RATE_MCS_ANT_A_MSK 0x4000 -#define RATE_MCS_ANT_B_MSK 0x8000 -#define RATE_MCS_ANT_AB_MSK 0xc000 -struct iwl4965_keyinfo {__le16 key_flags;u8 tkip_rx_tsc_byte2;/* TSC[2] for key mix ph1 detection */
drivers/net/wireless/iwlwifi/iwl-4965.h +7 -23
@@ -885,6 +885,11 @@ struct iwl4965_traffic_load { }; #ifdef CONFIG_IWL4965_HT_AGG +/** + * struct iwl4965_agg_control + * @requested_ba: bit map of tids requesting aggregation/block-ack + * @granted_ba: bit map of tids granted aggregation/block-ack + */ struct iwl4965_agg_control { unsigned long next_retry; u32 wait_for_agg_status;
@@ -1056,29 +1061,8 @@ struct iwl4965_chain_noise_data {u8 radio_write; }; -/* IWL4965 */ -#define RATE_MCS_CODE_MSK 0x7 -#define RATE_MCS_MIMO_POS 3 -#define RATE_MCS_MIMO_MSK 0x8 -#define RATE_MCS_HT_DUP_POS 5 -#define RATE_MCS_HT_DUP_MSK 0x20 -#define RATE_MCS_FLAGS_POS 8 -#define RATE_MCS_HT_POS 8 -#define RATE_MCS_HT_MSK 0x100 -#define RATE_MCS_CCK_POS 9 -#define RATE_MCS_CCK_MSK 0x200 -#define RATE_MCS_GF_POS 10 -#define RATE_MCS_GF_MSK 0x400 - -#define RATE_MCS_FAT_POS 11 -#define RATE_MCS_FAT_MSK 0x800 -#define RATE_MCS_DUP_POS 12 -#define RATE_MCS_DUP_MSK 0x1000 -#define RATE_MCS_SGI_POS 13 -#define RATE_MCS_SGI_MSK 0x2000 - -#define EEPROM_SEM_TIMEOUT 10 -#define EEPROM_SEM_RETRY_LIMIT 1000 +#define EEPROM_SEM_TIMEOUT 10/* milliseconds */ +#define EEPROM_SEM_RETRY_LIMIT 1000/* number of attempts (not time) */ #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 11/34 iwlwifi: Document Rx calibration
From: Ben Cahill <[email protected]>
Document Rx calibration
--- drivers/net/wireless/iwlwifi/iwl-4965-commands.h | 267 +++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-4965.c | 1 + drivers/net/wireless/iwlwifi/iwl-4965.h | 18 -- 3 files changed, 261 insertions(+), 25 deletions(-)
drivers/net/wireless/iwlwifi/iwl-4965-commands.h +260 -7
@@ -1573,25 +1573,278 @@ struct iwl4965_missed_beacon_notif {__le32 num_recvd_beacons; } __attribute__ ((packed)); +/****************************************************************************** * (11) * Rx Calibration Commands: * +* With the uCode used for open source drivers, most Tx calibration (except +* for Tx Power) and most Rx calibration is done by uCode during the +* "initialize" phase of uCode boot. Driver must calibrate only: +* +* 1) Tx power (depends on temperature), described elsewhere +* 2) Receiver gain balance (optimize MIMO, and detect disconnected antennas) +* 3) Receiver sensitivity (to optimize signal detection) +* *****************************************************************************/ -#define PHY_CALIBRATE_DIFF_GAIN_CMD (7) -#define HD_TABLE_SIZE (11) +/** +* SENSITIVITY_CMD = 0xa8 (command, has simple generic response) +* +* This command sets up the Rx signal detector for a sensitivity level that +* is high enough to lock onto all signals within the associated network, +* but low enough to ignore signals that are below a certain threshold, so as +* not to have too many "false alarms". False alarms are signals that the +* Rx DSP tries to lock onto, but then discards after determining that they +* are noise. +* +* The optimum number of false alarms is between 5 and 50 per 200 TUs +* (200 * 1024 uSecs, i.e. 204.8 milliseconds) of actual Rx time (i.e. +* time listening, not transmitting). Driver must adjust sensitivity so that +* the ratio of actual false alarms to actual Rx time falls within this range. +* +* While associated, uCode delivers STATISTICS_NOTIFICATIONs after each +* received beacon. These provide information to the driver to analyze the +* sensitivity. Don't analyze statistics that come in from scanning, or any +* other non-associated-network source. Pertinent statistics include: +* +* From "general" statistics (struct statistics_rx_non_phy): +* +* (beacon_energy_[abc] & 0x0FF00) >> 8 (unsigned, higher value is lower level) +* Measure of energy of desired signal. Used for establishing a level +* below which the device does not detect signals. +* +* (beacon_silence_rssi_[abc] & 0x0FF00) >> 8 (unsigned, units in dB) +* Measure of background noise in silent period after beacon. +* +* channel_load +* uSecs of actual Rx time during beacon period (varies according to +* how much time was spent transmitting). +* +* From "cck" and "ofdm" statistics (struct statistics_rx_phy), separately: +* +* false_alarm_cnt +* Signal locks abandoned early (before phy-level header). +* +* plcp_err +* Signal locks abandoned late (during phy-level header). +* +* NOTE: Both false_alarm_cnt and plcp_err increment monotonically from +* beacon to beacon, i.e. each value is an accumulation of all errors +* before and including the latest beacon. Values will wrap around to 0 +* after counting up to 2^32 - 1. Driver must differentiate vs. +* previous beacon's values to determine # false alarms in the current +* beacon period. +* +* Total number of false alarms = false_alarms + plcp_errs +* +* For OFDM, adjust the following table entries in struct iwl_sensitivity_cmd +* (notice that the start points for OFDM are at or close to settings for +* maximum sensitivity): +* +* START / MIN / MAX +* HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX 90 / 85 / 120 +* HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX 170 / 170 / 210 +* HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX 105 / 105 / 140 +* HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX 220 / 220 / 270 +* +* If actual rate of OFDM false alarms (+ plcp_errors) is too high +* (greater than 50 for each 204.8 msecs listening), reduce sensitivity +* by *adding* 1 to all 4 of the table entries above, up to the max for +* each entry. Conversely, if false alarm rate is too low (less than 5 +* for each 204.8 msecs listening), *subtract* 1 from each entry to +* increase sensitivity. +* +* For CCK sensitivity, keep track of the following: +* +* 1). 20-beacon history of maximum background noise, indicated by +* (beacon_silence_rssi_[abc] & 0x0FF00), units in dB, across the +* 3 receivers. For any given beacon, the "silence reference" is +* the maximum of last 60 samples (20 beacons * 3 receivers). +* +* 2). 10-beacon history of strongest signal level, as indicated +* by (beacon_energy_[abc] & 0x0FF00) >> 8, across the 3 receivers, +* i.e. the strength of the signal through the best receiver at the +* moment. These measurements are "upside down", with lower values +* for stronger signals, so max energy will be *minimum* value. +* +* Then for any given beacon, the driver must determine the *weakest* +* of the strongest signals; this is the minimum level that needs to be +* successfully detected, when using the best receiver at the moment. +* "Max cck energy" is the maximum (higher value means lower energy!) +* of the last 10 minima. Once this is determined, driver must add +* a little margin by adding "6" to it. +* +* 3). Number of consecutive beacon periods with too few false alarms. +* Reset this to 0 at the first beacon period that falls within the +* "good" range (5 to 50 false alarms per 204.8 milliseconds rx). +* +* Then, adjust the following CCK table entries in struct iwl_sensitivity_cmd +* (notice that the start points for CCK are at maximum sensitivity): +* +* START / MIN / MAX +* HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX 125 / 125 / 200 +* HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX 200 / 200 / 400 +* HD_MIN_ENERGY_CCK_DET_INDEX 100 / 0 / 100 +* +* If actual rate of CCK false alarms (+ plcp_errors) is too high +* (greater than 50 for each 204.8 msecs listening), method for reducing +* sensitivity is: +* +* 1) *Add* 3 to value in HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX, +* up to max 400. +* +* 2) If current value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX is < 160, +* sensitivity has been reduced a significant amount; bring it up to +* a moderate 161. Otherwise, *add* 3, up to max 200. +* +* 3) a) If current value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX is > 160, +* sensitivity has been reduced only a moderate or small amount; +* *subtract* 2 from value in HD_MIN_ENERGY_CCK_DET_INDEX, +* down to min 0. Otherwise (if gain has been significantly reduced), +* don't change the HD_MIN_ENERGY_CCK_DET_INDEX value. +* +* b) Save a snapshot of the "silence reference". +* +* If actual rate of CCK false alarms (+ plcp_errors) is too low +* (less than 5 for each 204.8 msecs listening), method for increasing +* sensitivity is used only if: +* +* 1a) Previous beacon did not have too many false alarms +* 1b) AND difference between previous "silence reference" and current +* "silence reference" (prev - current) is 2 or more, +* OR 2) 100 or more consecutive beacon periods have had rate of +* less than 5 false alarms per 204.8 milliseconds rx time. +* +* Method for increasing sensitivity: +* +* 1) *Subtract* 3 from value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX, +* down to min 125. +* +* 2) *Subtract* 3 from value in HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX, +* down to min 200. +* +* 3) *Add* 2 to value in HD_MIN_ENERGY_CCK_DET_INDEX, up to max 100. +* +* If actual rate of CCK false alarms (+ plcp_errors) is within good range +* (between 5 and 50 for each 204.8 msecs listening): +* +* 1) Save a snapshot of the silence reference. +* +* 2) If previous beacon had too many CCK false alarms (+ plcp_errors), +* give some extra margin to energy threshold by *subtracting* 8 +* from value in HD_MIN_ENERGY_CCK_DET_INDEX. +* +* For all cases (too few, too many, good range), make sure that the CCK +* detection threshold (energy) is below the energy level for robust +* detection over the past 10 beacon periods, the "Max cck energy". +* Lower values mean higher energy; this means making sure that the value +* in HD_MIN_ENERGY_CCK_DET_INDEX is at or *above* "Max cck energy". +* +* Driver should set the following entries to fixed values: +* +* HD_MIN_ENERGY_OFDM_DET_INDEX 100 +* HD_BARKER_CORR_TH_ADD_MIN_INDEX 190 +* HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX 390 +* HD_OFDM_ENERGY_TH_IN_INDEX 62 +*/ + +/* +* Table entries in SENSITIVITY_CMD (struct iwl4965_sensitivity_cmd) +*/ +#define HD_TABLE_SIZE (11)/* number of entries */ +#define HD_MIN_ENERGY_CCK_DET_INDEX (0)/* table indexes */ +#define HD_MIN_ENERGY_OFDM_DET_INDEX (1) +#define HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX (2) +#define HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX (3) +#define HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX (4) +#define HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX (5) +#define HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX (6) +#define HD_BARKER_CORR_TH_ADD_MIN_INDEX (7) +#define HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX (8) +#define HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX (9) +#define HD_OFDM_ENERGY_TH_IN_INDEX (10) + +/* Control field in struct iwl4965_sensitivity_cmd */ +#define SENSITIVITY_CMD_CONTROL_DEFAULT_TABLE __constant_cpu_to_le16(0) +#define SENSITIVITY_CMD_CONTROL_WORK_TABLE __constant_cpu_to_le16(1) +/** +* struct iwl4965_sensitivity_cmd +* @control: (1) updates working table, (0) updates default table +* @table: energy threshold values, use HD_* as index into table +* +* Always use "1" in "control" to update uCode's working table and DSP. +*/ struct iwl4965_sensitivity_cmd { -__le16 control; -__le16 table[HD_TABLE_SIZE ]; +__le16 control;/* always use "1" */ +__le16 table[HD_TABLE_SIZE ];/* use HD_* as index */ } __attribute__ ((packed)); + +/** +* REPLY_PHY_CALIBRATION_CMD = 0xb0 (command, has simple generic response) +* +* This command sets the relative gains of 4965's 3 radio receiver chains. +* +* After the first association, driver should accumulate signal and noise +* statistics from the STATISTICS_NOTIFICATIONs that follow the first 20 +* beacons from the associated network (don't collect statistics that come +* in from scanning, or any other non-network source). +* +* DISCONNECTED ANTENNA: +* +* Driver should determine which antennas are actually connected, by comparing +* average beacon signal levels for the 3 Rx chains. Accumulate (add) the +* following values over 20 beacons, one accumulator for each of the chains +* a/b/c, from struct statistics_rx_non_phy: +* +* beacon_rssi_[abc] & 0x0FF (unsigned, units in dB) +* +* Find the strongest signal from among a/b/c. Compare the other two to the +* strongest. If any signal is more than 15 dB (times 20, unless you +* divide the accumulated values by 20) below the strongest, the driver +* considers that antenna to be disconnected, and should not try to use that +* antenna/chain for Rx or Tx. If both A and B seem to be disconnected, +* driver should declare the stronger one as connected, and attempt to use it +* (A and B are the only 2 Tx chains!). +* +* +* RX BALANCE: +* +* Driver should balance the 3 receivers (but just the ones that are connected +* to antennas, see above) for gain, by comparing the average signal levels +* detected during the silence after each beacon (background noise). +* Accumulate (add) the following values over 20 beacons, one accumulator for +* each of the chains a/b/c, from struct statistics_rx_non_phy: +* +* beacon_silence_rssi_[abc] & 0x0FF (unsigned, units in dB) +* +* Find the weakest background noise level from among a/b/c. This Rx chain +* will be the reference, with 0 gain adjustment. Attenuate other channels by +* finding noise difference: +* +* (accum_noise[i] - accum_noise[reference]) / 30 +* +* The "30" adjusts the dB in the 20 accumulated samples to units of 1.5 dB. +* For use in diff_gain_[abc] fields of struct iwl_calibration_cmd, the +* driver should limit the difference results to a range of 0-3 (0-4.5 dB), +* and set bit 2 to indicate "reduce gain". The value for the reference +* (weakest) chain should be "0". +* +* diff_gain_[abc] bit fields: +* 2: (1) reduce gain, (0) increase gain +* 1-0: amount of gain, units of 1.5 dB +*/ + +/* "Differential Gain" opcode used in REPLY_PHY_CALIBRATION_CMD. */ +#define PHY_CALIBRATE_DIFF_GAIN_CMD (7) +struct iwl4965_calibration_cmd { -u8 opCode; -u8 flags; +u8 opCode;/* PHY_CALIBRATE_DIFF_GAIN_CMD (7) */ +u8 flags;/* not used */ __le16 reserved; -s8 diff_gain_a; +s8 diff_gain_a;/* see above */ s8 diff_gain_b;s8 diff_gain_c;u8 reserved1;
drivers/net/wireless/iwlwifi/iwl-4965.c +1 -0
@@ -1074,6 +1074,7 @@ static int iwl4965_sensitivity_write(struct iwl4965_priv *priv, u8 flags) data->auto_corr_cck, data->auto_corr_cck_mrc, data->nrg_th_cck); +/* Update uCode's "work" table, and copy it to DSP */ cmd.control =SENSITIVITY_CMD_CONTROL_WORK_TABLE ;if (flags &CMD_ASYNC )
drivers/net/wireless/iwlwifi/iwl-4965.h +0 -18
@@ -926,22 +926,6 @@ struct iwl4965_lq_mngr {#define CAL_NUM_OF_BEACONS 20#define MAXIMUM_ALLOWED_PATHLOSS 15 -/* Param table within SENSITIVITY_CMD */ -#define HD_MIN_ENERGY_CCK_DET_INDEX (0) -#define HD_MIN_ENERGY_OFDM_DET_INDEX (1) -#define HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX (2) -#define HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX (3) -#define HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX (4) -#define HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX (5) -#define HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX (6) -#define HD_BARKER_CORR_TH_ADD_MIN_INDEX (7) -#define HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX (8) -#define HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX (9) -#define HD_OFDM_ENERGY_TH_IN_INDEX (10) - -#define SENSITIVITY_CMD_CONTROL_DEFAULT_TABLE __constant_cpu_to_le16(0) -#define SENSITIVITY_CMD_CONTROL_WORK_TABLE __constant_cpu_to_le16(1) -#define CHAIN_NOISE_MAX_DELTA_GAIN_CODE 3#define MAX_FA_OFDM 50
@@ -969,8 +953,6 @@ struct iwl4965_lq_mngr {#define AUTO_CORR_STEP_CCK 3#define AUTO_CORR_MAX_TH_CCK 160 -#define NRG_ALG 0 -#define AUTO_CORR_ALG 1#define NRG_DIFF 2#define NRG_STEP_CCK 2#define NRG_MARGIN 8
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 12/34 iwlwifi: Partially clean-up, add comments to iwl-*-hw.h
From: Zhu Yi <[email protected]>
Resend. Replace mail subject due to ML restriction for capital Triple-X in subject.
On Thu, 2007-11-29 at 11:09 +0800, Zhu Yi wrote:
From: Ben Cahill <[email protected]>
Partially clean-up, add comments to iwl-XXXX-hw.h
--- drivers/net/wireless/iwlwifi/iwl-3945-hw.h | 66 ++++++++++++++++------- drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 78 ++++++++++++++++++---------- 2 files changed, 97 insertions(+), 47 deletions(-)
drivers/net/wireless/iwlwifi/iwl-3945-hw.h +46 -20
@@ -64,10 +64,11 @@#ifndef __iwl_3945_hw__#define __iwl_3945_hw__ -/* uCode queue management definitions */ +/* +* uCode queue management definitions ... +* Queue #4 is the command queue for 3945 and 4965. +*/ #define IWL_CMD_QUEUE_NUM 4 -#define IWL_CMD_FIFO_NUM 4 -#define IWL_BACK_QUEUE_FIRST_ID 7/* Tx rates */ #define IWL_CCK_RATES 4
@@ -314,7 +315,6 @@ struct iwl3945_eeprom {u8 reserved9[194 ]; -/* * 3945 Txpower calibration data. */
@@ -355,7 +355,18 @@ struct iwl3945_eeprom {#define CSR_GPIO_IN (CSR_BASE+0x018)/* read external chip pins */ #define CSR_RESET (CSR_BASE+0x020)/* busmaster enable, NMI, etc*/ #define CSR_GP_CNTRL (CSR_BASE+0x024) + +/* +* Hardware revision info +* Bit fields: +* 31-8: Reserved +* 7-4: Type of device: 0x0 = 4965, 0xd = 3945 +* 3-2: Revision step: 0 = A, 1 = B, 2 = C, 3 = D +* 1-0: "Dash" value, as in A-1, etc. +*/ #define CSR_HW_REV (CSR_BASE+0x028) + +/* EEPROM reads */ #define CSR_EEPROM_REG (CSR_BASE+0x02c)#define CSR_EEPROM_GP (CSR_BASE+0x030)#define CSR_GP_UCODE (CSR_BASE+0x044)
@@ -363,13 +374,13 @@ struct iwl3945_eeprom {#define CSR_UCODE_DRV_GP1_SET (CSR_BASE+0x058)#define CSR_UCODE_DRV_GP1_CLR (CSR_BASE+0x05c)#define CSR_UCODE_DRV_GP2 (CSR_BASE+0x060) -#define CSR_LED_REG (CSR_BASE+0x094) -#define CSR_DRAM_INT_TBL_CTL (CSR_BASE+0x0A0)#define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100) + +/* Analog phase-lock-loop configuration (3945 only) +* Set bit 24. */ #define CSR_ANA_PLL_CFG (CSR_BASE+0x20c) -#define CSR_HW_REV_WA_REG (CSR_BASE+0x22C) -/* HW I/F configuration */ +/* Bits for CSR_HW_IF_CONFIG_REG */ #define CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MB (0x00000100)#define CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MM (0x00000200)#define CSR_HW_IF_CONFIG_REG_BIT_SKU_MRC (0x00000400)
@@ -468,31 +479,46 @@ struct iwl3945_eeprom {/* CSR_ANA_PLL_CFG */ #define CSR_ANA_PLL_CFG_SH (0x00880300) -#define CSR_LED_REG_TRUN_ON (0x00000078) -#define CSR_LED_REG_TRUN_OFF (0x00000038) -#define CSR_LED_BSM_CTRL_MSK (0xFFFFFFDF) - -/* DRAM_INT_TBL_CTRL */ -#define CSR_DRAM_INT_TBL_CTRL_EN (1<<31) -#define CSR_DRAM_INT_TBL_CTRL_WRAP_CHK (1<<27) -/*=== HBUS (Host-side Bus) ===*/ #define HBUS_BASE (0x400) +/* +* Registers for accessing device's internal SRAM memory (e.g. SCD SRAM +* structures, error log, event log, verifying uCode load). +* First write to address register, then read from or write to data register +* to complete the job. Once the address register is set up, accesses to +* data registers auto-increment the address by one dword. +* Bit usage for address registers (read or write): +* 0-31: memory address within device +*/ #define HBUS_TARG_MEM_RADDR (HBUS_BASE+0x00c)#define HBUS_TARG_MEM_WADDR (HBUS_BASE+0x010)#define HBUS_TARG_MEM_WDAT (HBUS_BASE+0x018)#define HBUS_TARG_MEM_RDAT (HBUS_BASE+0x01c) + +/* +* Registers for accessing device's internal peripheral registers +* (e.g. SCD, BSM, etc.). First write to address register, +* then read from or write to data register to complete the job. +* Bit usage for address registers (read or write): +* 0-15: register address (offset) within device +* 24-25: (# bytes - 1) to read or write (e.g. 3 for dword) +*/ #define HBUS_TARG_PRPH_WADDR (HBUS_BASE+0x044)#define HBUS_TARG_PRPH_RADDR (HBUS_BASE+0x048)#define HBUS_TARG_PRPH_WDAT (HBUS_BASE+0x04c)#define HBUS_TARG_PRPH_RDAT (HBUS_BASE+0x050) -#define HBUS_TARG_WRPTR (HBUS_BASE+0x060) - -#define HBUS_TARG_MBX_C (HBUS_BASE+0x030) +/* +* Per-Tx-queue write pointer (index, really!) (3945 and 4965). +* Indicates index to next TFD that driver will fill (1 past latest filled). +* Bit usage: +* 0-7: queue write index +* 11-8: queue selector +*/ +#define HBUS_TARG_WRPTR (HBUS_BASE+0x060) -/* SCD (Scheduler) */ +/* SCD (3945 Tx Frame Scheduler) */ #define SCD_BASE (CSR_BASE + 0x2E00)#define SCD_MODE_REG (SCD_BASE + 0x000)
drivers/net/wireless/iwlwifi/iwl-4965-hw.h +51 -27
119 lines not on this page · raw message
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 13/34 iwlwifi: clean up some unused definitions in iwl-4965.h and iwl-3945.h
From: Ben Cahill <[email protected]>
Clean up some unused definitions in iwl-4965.h and iwl-3945.h
Move STA_FLG_ definitions to iwl-4965-commands.h
--- drivers/net/wireless/iwlwifi/iwl-3945.h | 21 ----------------- drivers/net/wireless/iwlwifi/iwl-4965-commands.h | 8 ++++++ drivers/net/wireless/iwlwifi/iwl-4965.h | 26 ---------------------- 3 files changed, 8 insertions(+), 47 deletions(-)
drivers/net/wireless/iwlwifi/iwl-3945.h +0 -21
@@ -192,14 +192,6 @@ struct iwl3945_scan_power_info {s8 requested_power;/* scan pwr (dBm) requested for chnl/rate */ }; -/* Channel unlock period is 15 seconds. If no beacon or probe response -* has been received within 15 seconds on a locked channel then the channel -* remains locked. */ -#define TX_UNLOCK_PERIOD 15 - -/* CSA lock period is 15 seconds. If a CSA has been received on a channel in -* the last 15 seconds, the channel is locked */ -#define CSA_LOCK_PERIOD 15/* * One for each channel, holds all channel setup data * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant
@@ -562,19 +554,6 @@ struct iwl3945_driver_hw_info {dma_addr_t shared_phys; }; - -#define STA_FLG_RTS_MIMO_PROT_MSK __constant_cpu_to_le32(1 << 17) -#define STA_FLG_AGG_MPDU_8US_MSK __constant_cpu_to_le32(1 << 18) -#define STA_FLG_MAX_AGG_SIZE_POS (19) -#define STA_FLG_MAX_AGG_SIZE_MSK __constant_cpu_to_le32(3 << 19) -#define STA_FLG_FAT_EN_MSK __constant_cpu_to_le32(1 << 21) -#define STA_FLG_MIMO_DIS_MSK __constant_cpu_to_le32(1 << 22) -#define STA_FLG_AGG_MPDU_DENSITY_POS (23) -#define STA_FLG_AGG_MPDU_DENSITY_MSK __constant_cpu_to_le32(7 << 23) -#define HT_SHORT_GI_20MHZ_ONLY (1 << 0) -#define HT_SHORT_GI_40MHZ_ONLY (1 << 1) - -#define IWL_RX_HDR (x) ((struct iwl3945_rx_frame_hdr *)(\ x->u.rx_frame.stats.payload + \ x->u.rx_frame.stats.phy_count))
drivers/net/wireless/iwlwifi/iwl-4965-commands.h +8 -0
@@ -515,6 +515,14 @@ struct iwl4965_qosparam_cmd {#define IWL_INVALID_STATION 255#define STA_FLG_PWR_SAVE_MSK __constant_cpu_to_le32(1<<8); +#define STA_FLG_RTS_MIMO_PROT_MSK __constant_cpu_to_le32(1 << 17) +#define STA_FLG_AGG_MPDU_8US_MSK __constant_cpu_to_le32(1 << 18) +#define STA_FLG_MAX_AGG_SIZE_POS (19) +#define STA_FLG_MAX_AGG_SIZE_MSK __constant_cpu_to_le32(3 << 19) +#define STA_FLG_FAT_EN_MSK __constant_cpu_to_le32(1 << 21) +#define STA_FLG_MIMO_DIS_MSK __constant_cpu_to_le32(1 << 22) +#define STA_FLG_AGG_MPDU_DENSITY_POS (23) +#define STA_FLG_AGG_MPDU_DENSITY_MSK __constant_cpu_to_le32(7 << 23)#define STA_CONTROL_MODIFY_MSK 0x01
drivers/net/wireless/iwlwifi/iwl-4965.h +0 -26
@@ -193,14 +193,6 @@ struct iwl4965_scan_power_info {s8 requested_power;/* scan pwr (dBm) requested for chnl/rate */ }; -/* Channel unlock period is 15 seconds. If no beacon or probe response -* has been received within 15 seconds on a locked channel then the channel -* remains locked. */ -#define TX_UNLOCK_PERIOD 15 - -/* CSA lock period is 15 seconds. If a CSA has been received on a channel in -* the last 15 seconds, the channel is locked */ -#define CSA_LOCK_PERIOD 15/* * One for each channel, holds all channel setup data * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant
@@ -622,15 +614,6 @@ struct iwl4965_driver_hw_info {dma_addr_t shared_phys; }; - -#define STA_FLG_RTS_MIMO_PROT_MSK __constant_cpu_to_le32(1 << 17) -#define STA_FLG_AGG_MPDU_8US_MSK __constant_cpu_to_le32(1 << 18) -#define STA_FLG_MAX_AGG_SIZE_POS (19) -#define STA_FLG_MAX_AGG_SIZE_MSK __constant_cpu_to_le32(3 << 19) -#define STA_FLG_FAT_EN_MSK __constant_cpu_to_le32(1 << 21) -#define STA_FLG_MIMO_DIS_MSK __constant_cpu_to_le32(1 << 22) -#define STA_FLG_AGG_MPDU_DENSITY_POS (23) -#define STA_FLG_AGG_MPDU_DENSITY_MSK __constant_cpu_to_le32(7 << 23)#define HT_SHORT_GI_20MHZ_ONLY (1 << 0)#define HT_SHORT_GI_40MHZ_ONLY (1 << 1)
@@ -862,17 +845,8 @@ struct iwl4965_kw {#define NRG_NUM_PREV_STAT_L 20#define NUM_RX_CHAINS (3) -#define TX_POWER_IWL_ILLEGAL_VDET -100000#define TX_POWER_IWL_ILLEGAL_VOLTAGE -10000 -#define TX_POWER_IWL_CLOSED_LOOP_MIN_POWER 18 -#define TX_POWER_IWL_CLOSED_LOOP_MAX_POWER 34 -#define TX_POWER_IWL_VDET_SLOPE_BELOW_NOMINAL 17 -#define TX_POWER_IWL_VDET_SLOPE_ABOVE_NOMINAL 20 -#define TX_POWER_IWL_NOMINAL_POWER 26 -#define TX_POWER_IWL_CLOSED_LOOP_ITERATION_LIMIT 1#define TX_POWER_IWL_VOLTAGE_CODES_PER_03V 7 -#define TX_POWER_IWL_DEGREES_PER_VDET_CODE 11 -#define IWL_TX_POWER_MAX_NUM_PA_MEASUREMENTS 1#define IWL_TX_POWER_CCK_COMPENSATION_B_STEP (9)#define IWL_TX_POWER_CCK_COMPENSATION_C_STEP (5)
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 14/34 iwlwifi: add comments, mostly on Tx queues
From: Cahill, Ben M <[email protected]>
Add comments, mostly on Tx queues
--- drivers/net/wireless/iwlwifi/iwl-4965.c | 252 +++++++++++++++++++++++---- drivers/net/wireless/iwlwifi/iwl4965-base.c | 18 ++- 2 files changed, 231 insertions(+), 39 deletions(-)
drivers/net/wireless/iwlwifi/iwl-4965.c +216 -36
@@ -144,7 +144,7 @@ int iwl4965_hw_rxq_stop(struct iwl4965_priv *priv)return rc; } -/* stop HW */ +/* stop Rx DMA */ iwl4965_write_direct32 (priv,FH_MEM_RCSR_CHNL0_CONFIG_REG ,0 ); rc =iwl4965_poll_direct_bit (priv,FH_MEM_RSSR_RX_STATUS_REG , (1 <<24 ),1000 );
@@ -240,17 +240,22 @@ static int iwl4965_rx_init(struct iwl4965_priv *priv, struct iwl4965_rx_queue *relse rb_size =FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K ; -/* stop HW */ +/* Stop Rx DMA */ iwl4965_write_direct32 (priv,FH_MEM_RCSR_CHNL0_CONFIG_REG ,0 ); +/* Reset driver's Rx queue write index */ iwl4965_write_direct32 (priv,FH_RSCSR_CHNL0_RBDCB_WPTR_REG ,0 ); + +/* Tell device where to find RBD circular buffer in DRAM */ iwl4965_write_direct32 (priv,FH_RSCSR_CHNL0_RBDCB_BASE_REG , rxq->dma_addr >>8 ); +/* Tell device where in DRAM to update its Rx status */ iwl4965_write_direct32 (priv,FH_RSCSR_CHNL0_STTS_WPTR_REG , (priv->hw_setting.shared_phys + offsetof(struct iwl4965_shared , val0)) >>4 ); +/* Enable Rx DMA, enable host interrupt, Rx buffer size 4k, 256 RBDs */ iwl4965_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
@@ -269,6 +274,7 @@ static int iwl4965_rx_init(struct iwl4965_priv *priv, struct iwl4965_rx_queue *rreturn 0 ; } +/* Tell 4965 where to find the "keep warm" buffer */ static int iwl4965_kw_init (struct iwl4965_priv *priv) {unsigned long flags;
@@ -303,6 +309,11 @@ static int iwl4965_kw_alloc(struct iwl4965_priv *priv)#define CHECK_AND_PRINT (x) ((eeprom_ch->flags & EEPROM_CHANNEL_##x) \ ? # x " " : "") +/** +* iwl4965_set_fat_chan_info - Copy fat channel info into driver's priv. +* +* Does not set up a command, or touch hardware. +*/ int iwl4965_set_fat_chan_info (struct iwl4965_priv *priv,int phymode,u16 channel,const struct iwl4965_eeprom_channel *eeprom_ch,u8 fat_extension_channel)
@@ -343,6 +354,9 @@ int iwl4965_set_fat_chan_info(struct iwl4965_priv *priv, int phymode, u16 channereturn 0 ; } +/** +* iwl4965_kw_free - Free the "keep warm" buffer +*/ static void iwl4965_kw_free (struct iwl4965_priv *priv) {struct pci_dev *dev = priv->pci_dev;
@@ -369,9 +383,10 @@ static int iwl4965_txq_ctx_reset(struct iwl4965_priv *priv)iwl4965_kw_free (priv); +/* Free all tx/cmd queues and keep-warm buffer */ iwl4965_hw_txq_ctx_free (priv); -/* Tx CMD queue */ +/* Alloc keep-warm buffer */ rc =iwl4965_kw_alloc (priv);if (rc) {IWL_ERROR ("Keep Warm allocation failed" );
@@ -387,17 +402,20 @@ static int iwl4965_txq_ctx_reset(struct iwl4965_priv *priv) goto error_reset; } +/* Turn off all Tx DMA channels */ iwl4965_write_prph (priv,KDR_SCD_TXFACT ,0 );iwl4965_release_nic_access (priv);spin_unlock_irqrestore (&priv->lock, flags); +/* Tell 4965 where to find the keep-warm buffer */ rc =iwl4965_kw_init (priv);if (rc) {IWL_ERROR ("kw_init failed\n" ); goto error_reset; } -/* Tx queue(s) */ +/* Alloc and init all (default 16) Tx queues, +* including the command queue (#4) */ for (txq_id =0 ; txq_id < priv->hw_setting.max_txq_num; txq_id++) { slots_num = (txq_id ==IWL_CMD_QUEUE_NUM ) ?TFD_CMD_SLOTS :TFD_TX_CMD_SLOTS ;
@@ -551,6 +569,8 @@ int iwl4965_hw_nic_init(struct iwl4965_priv *priv)iwl4965_rx_queue_update_write_ptr (priv, rxq);spin_unlock_irqrestore (&priv->lock, flags); + +/* Allocate and init all Tx and Command queues */ rc =iwl4965_txq_ctx_reset (priv);if (rc)return rc;
@@ -599,13 +619,16 @@ int iwl4965_hw_nic_stop_master(struct iwl4965_priv *priv)return rc; } +/** +* iwl4965_hw_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory +*/ void iwl4965_hw_txq_ctx_stop (struct iwl4965_priv *priv) {int txq_id;unsigned long flags; -/* reset TFD queues */ +/* Stop each Tx DMA channel, and wait for it to be idle */ for (txq_id =0 ; txq_id < priv->hw_setting.max_txq_num; txq_id++) {spin_lock_irqsave (&priv->lock, flags);if (iwl4965_grab_nic_access (priv)) {
@@ -623,6 +646,7 @@ void iwl4965_hw_txq_ctx_stop(struct iwl4965_priv *priv)spin_unlock_irqrestore (&priv->lock, flags); } +/* Deallocate memory for all Tx queues */ iwl4965_hw_txq_ctx_free (priv); }
@@ -1592,16 +1616,23 @@ static void iwl4965_set_wr_ptrs(struct iwl4965_priv *priv, int txq_id, u32 indexiwl4965_write_prph (priv,KDR_SCD_QUEUE_RDPTR (txq_id), index); } -/* -* Acquire priv->lock before calling this function ! +/** +* iwl4965_tx_queue_set_status - (optionally) start Tx/Cmd queue +* @tx_fifo_id: Tx DMA/FIFO channel (range 0-7) that the queue will feed +* @scd_retry: (1) Indicates queue will be used in aggregation mode +* +* NOTE: Acquire priv->lock before calling this function ! */ static void iwl4965_tx_queue_set_status (struct iwl4965_priv *priv,struct iwl4965_tx_queue *txq,int tx_fifo_id,int scd_retry) {int txq_id = txq->q.id; + +/* Find out whether to activate Tx queue */ int active =test_bit (txq_id, &priv->txq_ctx_active_msk)?1 :0 ; +/* Set up and activate */ iwl4965_write_prph(priv, KDR_SCD_QUEUE_STATUS_BITS(txq_id), (active << SCD_QUEUE_STTS_REG_POS_ACTIVE) | (tx_fifo_id << SCD_QUEUE_STTS_REG_POS_TXF) |
@@ -1612,7 +1643,7 @@ static void iwl4965_tx_queue_set_status(struct iwl4965_priv *priv, txq->sched_retry = scd_retry;IWL_DEBUG_INFO ("%s %s Queue %d on AC %d\n" , - active ?"Activete" :"Deactivate" , + active ?"Activate" :"Deactivate" , scd_retry ?"BA" :"AC" , txq_id, tx_fifo_id); }
@@ -1660,6 +1691,7 @@ int iwl4965_alive_notify(struct iwl4965_priv *priv)return rc; } +/* Clear 4965's internal Tx Scheduler data base */ priv->scd_base_addr =iwl4965_read_prph (priv,KDR_SCD_SRAM_BASE_ADDR ); a = priv->scd_base_addr +SCD_CONTEXT_DATA_OFFSET ;for (; a < priv->scd_base_addr +SCD_TX_STTS_BITMAP_OFFSET ; a +=4 )
@@ -1669,20 +1701,29 @@ int iwl4965_alive_notify(struct iwl4965_priv *priv)for (; a <sizeof (u16) * priv->hw_setting.max_txq_num; a +=4 )iwl4965_write_targ_mem (priv, a,0 ); +/* Tel 4965 where to find Tx byte count tables */ iwl4965_write_prph (priv,KDR_SCD_DRAM_BASE_ADDR , (priv->hw_setting.shared_phys + offsetof(struct iwl4965_shared , queues_byte_cnt_tbls)) >>10 ); + +/* Disable chain mode for all queues */ iwl4965_write_prph (priv,KDR_SCD_QUEUECHAIN_SEL ,0 ); -/* initiate the queues */ +/* Initialize each Tx queue (including the command queue) */ for (i =0 ; i < priv->hw_setting.max_txq_num; i++) { + +/* TFD circular buffer read/write indexes */ iwl4965_write_prph (priv,KDR_SCD_QUEUE_RDPTR (i),0 );iwl4965_write_direct32 (priv,HBUS_TARG_WRPTR ,0 | (i <<8 )); + +/* Max Tx Window size for Scheduler-ACK mode */ iwl4965_write_targ_mem (priv, priv->scd_base_addr +SCD_CONTEXT_QUEUE_OFFSET (i), (SCD_WIN_SIZE <<SCD_QUEUE_CTX_REG1_WIN_SIZE_POS ) &SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK ); + +/* Frame limit */ iwl4965_write_targ_mem(priv, priv->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(i) + sizeof(u32),
@@ -1694,11 +1735,13 @@ int iwl4965_alive_notify(struct iwl4965_priv *priv)iwl4965_write_prph (priv,KDR_SCD_INTERRUPT_MASK , (1 << priv->hw_setting.max_txq_num) -1 ); +/* Activate all Tx DMA/FIFO channels */ iwl4965_write_prph (priv,KDR_SCD_TXFACT ,SCD_TXFACT_REG_TXFIFO_MASK (0 ,7 ));iwl4965_set_wr_ptrs (priv,IWL_CMD_QUEUE_NUM ,0 ); -/* map qos queues to fifos one-to-one */ + +/* Map each Tx/cmd queue to its corresponding fifo */ for (i =0 ; i <ARRAY_SIZE (default_queue_to_tx_fifo); i++) {int ac = default_queue_to_tx_fifo[i];iwl4965_txq_ctx_activate (priv, i);
@@ -1711,8 +1754,14 @@ int iwl4965_alive_notify(struct iwl4965_priv *priv)return 0 ; } +/** +* iwl4965_hw_set_hw_setting +* +* Called when initializing driver +*/ int iwl4965_hw_set_hw_setting (struct iwl4965_priv *priv) { +/* Allocate area for Tx byte count tables and Rx queue status */ priv->hw_setting.shared_virt = pci_alloc_consistent(priv->pci_dev, sizeof(struct iwl4965_shared),
@@ -1751,13 +1800,15 @@ void iwl4965_hw_txq_ctx_free(struct iwl4965_priv *priv)for (txq_id =0 ; txq_id < priv->hw_setting.max_txq_num; txq_id++)iwl4965_tx_queue_free (priv, &priv->txq[txq_id]); +/* Keep-warm buffer */ iwl4965_kw_free (priv); }/** -* iwl4965_hw_txq_free_tfd - Free one TFD, those at index [txq->q.read_ptr] +* iwl4965_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] * -* Does NOT advance any indexes +* Does NOT advance any TFD circular buffer read/write indexes +* Does NOT free the TFD itself (which is within circular buffer) */ int iwl4965_hw_txq_free_tfd (struct iwl4965_priv *priv,struct iwl4965_tx_queue *txq) {
@@ -1768,12 +1819,11 @@ int iwl4965_hw_txq_free_tfd(struct iwl4965_priv *priv, struct iwl4965_tx_queue *int counter =0 ;int index, is_odd; -/* classify bd */ +/* Host command buffers stay mapped in memory, nothing to clean */ if (txq->q.id ==IWL_CMD_QUEUE_NUM ) -/* nothing to cleanup after for host commands */ return 0 ; -/* sanity check */ +/* Sanity check on number of chunks */ counter =IWL_GET_BITS (*bd, num_tbs);if (counter >MAX_NUM_OF_TBS ) {IWL_ERROR ("Too many chunks: %i\n" , counter);
@@ -1781,8 +1831,8 @@ int iwl4965_hw_txq_free_tfd(struct iwl4965_priv *priv, struct iwl4965_tx_queue *return 0 ; } -/* unmap chunks if any */ - +/* Unmap chunks, if any. +* TFD info for odd chunks is different format than for even chunks. */ for (i =0 ; i < counter; i++) { index = i /2 ; is_odd = i &0x1 ;
@@ -1802,6 +1852,7 @@ int iwl4965_hw_txq_free_tfd(struct iwl4965_priv *priv, struct iwl4965_tx_queue *IWL_GET_BITS (bd->pa[index], tb1_len), PCI_DMA_TODEVICE); +/* Free SKB, if any, for this chunk */ if (txq->txb[txq->q.read_ptr].skb[i]) {struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[i];
@@ -1836,6 +1887,17 @@ static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res)return 1 ; } +/** +* iwl4965_get_voltage_compensation - Power supply voltage comp for txpower +* +* Determines power supply voltage compensation for txpower calculations. +* Returns number of 1/2-dB steps to subtract from gain table index, +* to compensate for difference between power supply voltage during +* factory measurements, vs. current power supply voltage. +* +* Voltage indication is higher for lower voltage. +* Lower voltage requires more gain (lower gain table index). +*/ static s32 iwl4965_get_voltage_compensation (s32 eeprom_voltage,s32 current_voltage) {
@@ -1923,6 +1985,14 @@ static s32 iwl4965_interpolate_value(s32 x, s32 x1, s32 y1, s32 x2, s32 y2) } } +/** +* iwl4965_interpolate_chan - Interpolate factory measurements for one channel +* +* Interpolates factory measurements from the two sample channels within a +* sub-band, to apply to channel of interest. Interpolation is proportional to +* differences in channel frequencies, which is proportional to differences +* in channel number. +*/ static int iwl4965_interpolate_chan (struct iwl4965_priv *priv,u32 channel,struct iwl4965_eeprom_calib_ch_info *chan_info) {
@@ -2691,6 +2761,13 @@ unsigned int iwl4965_hw_get_beacon_cmd(struct iwl4965_priv *priv,return (sizeof (*tx_beacon_cmd) + frame_size); } +/* +* Tell 4965 where to find circular buffer of Tx Frame Descriptors for +* given Tx queue, and enable the DMA channel used for that queue. +* +* 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA +* channels supported in hardware. +*/ int iwl4965_hw_tx_queue_init (struct iwl4965_priv *priv,struct iwl4965_tx_queue *txq) {int rc;
@@ -2704,8 +2781,11 @@ int iwl4965_hw_tx_queue_init(struct iwl4965_priv *priv, struct iwl4965_tx_queuereturn rc; } +/* Circular buffer (TFD queue in DRAM) physical base address */ iwl4965_write_direct32 (priv,FH_MEM_CBBC_QUEUE (txq_id), txq->q.dma_addr >>8 ); + +/* Enable DMA channel, using same id as for TFD queue */ iwl4965_write_direct32( priv, IWL_FH_TCSR_CHNL_TX_CONFIG_REG(txq_id), IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
@@ -2728,6 +2808,7 @@ int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl4965_priv *priv, void *ptr,struct iwl4965_tfd_frame *tfd = ptr;u32 num_tbs =IWL_GET_BITS (*tfd, num_tbs); +/* Each TFD can point to a maximum 20 Tx buffers */ if ((num_tbs >=MAX_NUM_OF_TBS ) || (num_tbs <0 )) {IWL_ERROR ("Error can not send more than %d chunks\n" ,MAX_NUM_OF_TBS );
@@ -2769,6 +2850,9 @@ static void iwl4965_hw_card_show_info(struct iwl4965_priv *priv)#define IWL_TX_CRC_SIZE 4#define IWL_TX_DELIMITER_SIZE 4 +/** +* iwl4965_tx_queue_update_wr_ptr - Set up entry in Tx byte-count array +*/ int iwl4965_tx_queue_update_wr_ptr (struct iwl4965_priv *priv,struct iwl4965_tx_queue *txq,u16 byte_cnt) {
@@ -2781,9 +2865,11 @@ int iwl4965_tx_queue_update_wr_ptr(struct iwl4965_priv *priv, len = byte_cnt +IWL_TX_CRC_SIZE +IWL_TX_DELIMITER_SIZE ; +/* Set up byte count within first 256 entries */ IWL_SET_BITS16 (shared_data->queues_byte_cnt_tbls[txq_id]. tfd_offset[txq->q.write_ptr], byte_cnt, len); +/* If within first 64 entries, duplicate at end */ if (txq->q.write_ptr <IWL4965_MAX_WIN_SIZE ) IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id]. tfd_offset[IWL4965_QUEUE_SIZE + txq->q.write_ptr],
@@ -2792,8 +2878,12 @@ int iwl4965_tx_queue_update_wr_ptr(struct iwl4965_priv *priv,return 0 ; } -/* Set up Rx receiver/antenna/chain usage in "staging" RXON image. -* This should not be used for scan command ... it puts data in wrong place. */ +/** +* iwl4965_set_rxon_chain - Set up Rx chain usage in "staging" RXON image +* +* Selects how many and which Rx receivers/antennas/chains to use. +* This should not be used for scan command ... it puts data in wrong place. +*/ void iwl4965_set_rxon_chain (struct iwl4965_priv *priv) {u8 is_single =is_single_stream (priv);
@@ -2941,6 +3031,9 @@ enum HT_STATUS { BA_STATUS_ACTIVE, }; +/** +* iwl4964_tl_ba_avail - Find out if an unused aggregation queue is available +*/ static u8 iwl4964_tl_ba_avail (struct iwl4965_priv *priv) {int i;
@@ -2949,6 +3042,8 @@ static u8 iwl4964_tl_ba_avail(struct iwl4965_priv *priv)u16 msk; lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr); + +/* Find out how many agg queues are in use */ for (i =0 ; i <TID_MAX_LOAD_COUNT ; i++) { msk =1 << i; if ((lq->agg_ctrl.granted_ba & msk) ||
@@ -3090,6 +3185,9 @@ void iwl4965_turn_off_agg(struct iwl4965_priv *priv, u8 tid) } } +/** +* iwl4965_ba_status - Update driver's link quality mgr with tid's HT status +*/ static void iwl4965_ba_status (struct iwl4965_priv *priv,u8 tid,enum HT_STATUS status) {
@@ -3311,11 +3409,12 @@ int iwl4965_get_temperature(const struct iwl4965_priv *priv) }/* -* Temperature is only 23 bits so sign extend out to 32 +* Temperature is only 23 bits, so sign extend out to 32. * * NOTE If we haven't received a statistics notification yet * with an updated temperature, use R4 provided to us in the -* ALIVE response. */ +* "initialize" ALIVE response. +*/ if (!test_bit (STATUS_TEMPERATURE , &priv->status)) vt =sign_extend (R4 ,23 );else
@@ -4039,6 +4138,11 @@ static void iwl4965_rx_missed_beacon_notif(struct iwl4965_priv *priv, #ifdef CONFIG_IWL4965_HT #ifdef CONFIG_IWL4965_HT_AGG +/** + * iwl4965_set_tx_status - Update driver's record of one Tx frame's status + * + * This will get sent to mac80211. + */ static void iwl4965_set_tx_status(struct iwl4965_priv *priv, int txq_id, int idx, u32 status, u32 retry_count, u32 rate) {
@@ -4051,11 +4155,15 @@ static void iwl4965_set_tx_status(struct iwl4965_priv *priv, int txq_id, int idx } +/** +* iwl4965_sta_modify_enable_tid_tx - Enable Tx for this TID in station table +*/ static void iwl4965_sta_modify_enable_tid_tx (struct iwl4965_priv *priv,int sta_id,int tid) {unsigned long flags; +/* Remove "disable" flag, to enable Tx for this TID */ spin_lock_irqsave (&priv->sta_lock, flags); priv->stations[sta_id].sta.sta.modify_mask =STA_MODIFY_TID_DISABLE_TX ; priv->stations[sta_id].sta.tid_disable_tx &=cpu_to_le16 (~(1 << tid));
@@ -4066,6 +4174,12 @@ static void iwl4965_sta_modify_enable_tid_tx(struct iwl4965_priv *priv, } +/** +* iwl4965_tx_status_reply_compressed_ba - Update tx status from block-ack +* +* Go through block-ack's bitmap of ACK'd frames, update driver's record of +* ACK vs. not. This gets sent to mac80211, then to rate scaling algo. +*/ static int iwl4965_tx_status_reply_compressed_ba (struct iwl4965_priv *priv,struct iwl4965_ht_agg *agg, struct iwl4965_compressed_ba_resp*
@@ -4082,13 +4196,17 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl4965_priv *priv,IWL_ERROR ("Received BA when not expected\n" );return -EINVAL ; } + +/* Mark that the expected block-ack response arrived */ agg->wait_for_ba =0 ;IWL_DEBUG_TX_REPLY ("BA %d %d\n" , agg->start_idx, ba_resp->ba_seq_ctl); + +/* Calculate shift to align block-ack bits with our Tx window bits */ sh = agg->start_idx -SEQ_TO_INDEX (ba_seq_ctl>>4 );if (sh <0 )/* tbw something is wrong with indices */ sh +=0x100 ; -/* don't use 64 bits for now */ +/* don't use 64-bit values for now */ bitmap0 = resp_bitmap0 >> sh; bitmap1 = resp_bitmap1 >> sh; bitmap0 |= (resp_bitmap1 & ((1 <<sh)|((1 <<sh)-1 ))) << (32 - sh);
@@ -4099,10 +4217,12 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl4965_priv *priv, }/* check for success or failure according to the -* transmitted bitmap and back bitmap */ +* transmitted bitmap and block-ack bitmap */ bitmap0 &= agg->bitmap0; bitmap1 &= agg->bitmap1; +/* For each frame attempted in aggregation, +* update driver's record of tx frame's status. */ for (i =0 ; i < agg->frame_count ; i++) {int idx = (agg->start_idx + i) &0xff ; ack = bitmap0 & (1 << i);
@@ -4118,11 +4238,22 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl4965_priv *priv,return 0 ; } +/** +* iwl4965_queue_dec_wrap - Decrement queue index, wrap back to end if needed +* @index -- current index +* @n_bd -- total number of entries in queue (s/b power of 2) +*/ static inline int iwl4965_queue_dec_wrap (int index,int n_bd) {return (index ==0 ) ? n_bd -1 : index -1 ; } +/** +* iwl4965_rx_reply_compressed_ba - Handler for REPLY_COMPRESSED_BA +* +* Handles block-acknowledge notification from device, which reports success +* of frames sent via aggregation. +*/ static void iwl4965_rx_reply_compressed_ba (struct iwl4965_priv *priv,struct iwl4965_rx_mem_buffer *rxb) {
@@ -4131,7 +4262,12 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl4965_priv *priv,int index;struct iwl4965_tx_queue *txq =NULL ;struct iwl4965_ht_agg *agg; + +/* "flow" corresponds to Tx queue */ u16 ba_resp_scd_flow =le16_to_cpu (ba_resp->scd_flow); + +/* "ssn" is start of block-ack Tx window, corresponds to index +* (in Tx queue's circular buffer) of first TFD/frame in window */ u16 ba_resp_scd_ssn =le16_to_cpu (ba_resp->scd_ssn);if (ba_resp_scd_flow >=ARRAY_SIZE (priv->txq)) {
@@ -4141,6 +4277,8 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl4965_priv *priv, txq = &priv->txq[ba_resp_scd_flow]; agg = &priv->stations[ba_resp->sta_id].tid[ba_resp->tid].agg; + +/* Find index just before block-ack window */ index =iwl4965_queue_dec_wrap (ba_resp_scd_ssn &0xff , txq->q.n_bd);/* TODO: Need to get this copy more safely - now good for debug */
@@ -4166,22 +4304,35 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl4965_priv *priv,agg->bitmap0); } */ + +/* Update driver's record of ACK vs. not for each frame in window */ iwl4965_tx_status_reply_compressed_ba (priv, agg, ba_resp); -/* releases all the TFDs until the SSN */ + +/* Release all TFDs before the SSN, i.e. all TFDs in front of +* block-ack window (we assume that they've been successfully +* transmitted ... if not, it's too late anyway). */ if (txq->q.read_ptr != (ba_resp_scd_ssn &0xff ))iwl4965_tx_queue_reclaim (priv, ba_resp_scd_flow, index); } +/** +* iwl4965_tx_queue_stop_scheduler - Stop queue, but keep configuration +*/ static void iwl4965_tx_queue_stop_scheduler (struct iwl4965_priv *priv,u16 txq_id) { +/* Simply stop the queue, but don't change any configuration; +* the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ iwl4965_write_prph (priv,KDR_SCD_QUEUE_STATUS_BITS (txq_id), (0 <<SCD_QUEUE_STTS_REG_POS_ACTIVE )| (1 <<SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN )); } +/** +* iwl4965_tx_queue_set_q2ratid - Map unique receiver/tid combination to a queue +*/ static int iwl4965_tx_queue_set_q2ratid (struct iwl4965_priv *priv,u16 ra_tid,u16 txq_id) {
@@ -4207,7 +4358,10 @@ static int iwl4965_tx_queue_set_q2ratid(struct iwl4965_priv *priv, u16 ra_tid, }/** -* txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID +* iwl4965_tx_queue_agg_enable - Set up & enable aggregation for selected queue +* +* NOTE: txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID, +* i.e. it must be one of the higher queues used for aggregation */ static int iwl4965_tx_queue_agg_enable(struct iwl4965_priv *priv, int txq_id, int tx_fifo, int sta_id, int tid,
@@ -4223,6 +4377,7 @@ static int iwl4965_tx_queue_agg_enable(struct iwl4965_priv *priv, int txq_id, ra_tid =BUILD_RAxTID (sta_id, tid); +/* Modify device's station table to Tx this TID */ iwl4965_sta_modify_enable_tid_tx (priv, sta_id, tid);spin_lock_irqsave (&priv->lock, flags);
@@ -4232,19 +4387,22 @@ static int iwl4965_tx_queue_agg_enable(struct iwl4965_priv *priv, int txq_id,return rc; } +/* Stop this Tx queue before configuring it */ iwl4965_tx_queue_stop_scheduler (priv, txq_id); +/* Map receiver-address / traffic-ID to this queue */ iwl4965_tx_queue_set_q2ratid (priv, ra_tid, txq_id); - +/* Set this queue as a chain-building queue */ iwl4965_set_bits_prph (priv,KDR_SCD_QUEUECHAIN_SEL , (1 <<txq_id)); +/* Place first TFD at index corresponding to start sequence number. +* Assumes that ssn_idx is valid (!= 0xFFF) */ priv->txq[txq_id].q.read_ptr = (ssn_idx &0xff ); priv->txq[txq_id].q.write_ptr = (ssn_idx &0xff ); - -/* supposes that ssn_idx is valid (!= 0xFFF) */ iwl4965_set_wr_ptrs (priv, txq_id, ssn_idx); +/* Set up Tx window size and frame limit for this queue */ iwl4965_write_targ_mem(priv, priv->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(txq_id), (SCD_WIN_SIZE << SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) &
@@ -4257,6 +4415,7 @@ static int iwl4965_tx_queue_agg_enable(struct iwl4965_priv *priv, int txq_id,iwl4965_set_bits_prph (priv,KDR_SCD_INTERRUPT_MASK , (1 << txq_id)); +/* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ iwl4965_tx_queue_set_status (priv, &priv->txq[txq_id], tx_fifo,1 );iwl4965_release_nic_access (priv);
@@ -4312,14 +4471,16 @@ static int iwl4965_tx_queue_agg_disable(struct iwl4965_priv *priv, u16 txq_id,/** * iwl4965_add_station - Initialize a station's hardware rate table * -* The uCode contains a table of fallback rates and retries per rate +* The uCode's station table contains a table of fallback rates * for automatic fallback during transmission. * -* NOTE: This initializes the table for a single retry per data rate -* which is not optimal. Setting up an intelligent retry per rate -* requires feedback from transmission, which isn't exposed through -* rc80211_simple which is what this driver is currently using. +* NOTE: This sets up a default set of values. These will be replaced later +* if the driver's iwl-4965-rs rate scaling algorithm is used, instead of +* rc80211_simple. * +* NOTE: Run REPLY_ADD_STA command to set up station table entry, before +* calling this function (which runs REPLY_TX_LINK_QUALITY_CMD, +* which requires station table entry to exist). */ void iwl4965_add_station (struct iwl4965_priv *priv,const u8 *addr,int is_ap) {
@@ -4329,8 +4490,8 @@ void iwl4965_add_station(struct iwl4965_priv *priv, const u8 *addr, int is_ap) };u16 rate_flags; -/* Set up the rate scaling to start at 54M and fallback -* all the way to 1M in IEEE order and then spin on IEEE */ +/* Set up the rate scaling to start at selected rate, fall back +* all the way down to 1M in IEEE order, and then spin on 1M */ if (is_ap) r =IWL_RATE_54M_INDEX ;else if (priv->phymode ==MODE_IEEE80211A )
@@ -4343,8 +4504,10 @@ void iwl4965_add_station(struct iwl4965_priv *priv, const u8 *addr, int is_ap)if (r >=IWL_FIRST_CCK_RATE && r <=IWL_LAST_CCK_RATE ) rate_flags |=RATE_MCS_CCK_MSK ; +/* Use Tx antenna B only */ rate_flags |=RATE_MCS_ANT_B_MSK ; rate_flags &= ~RATE_MCS_ANT_A_MSK ; + link_cmd.rs_table[i].rate_n_flags =iwl4965_hw_set_rate_n_flags (iwl4965_rates[r].plcp, rate_flags); r =iwl4965_get_prev_ieee_rate (r);
@@ -4412,6 +4575,7 @@ void iwl4965_set_rxon_ht(struct iwl4965_priv *priv, struct iwl_ht_info *ht_info)if (!ht_info->is_ht)return ; +/* Set up channel bandwidth: 20 MHz only, or 20/40 mixed if fat ok */ if (iwl4965_is_fat_tx_allowed (priv,NULL )) rxon->flags |=RXON_FLG_CHANNEL_MODE_MIXED_MSK ;else
@@ -4426,7 +4590,7 @@ void iwl4965_set_rxon_ht(struct iwl4965_priv *priv, struct iwl_ht_info *ht_info)return ; } -/* Note: control channel is oposit to extension channel */ +/* Note: control channel is opposite of extension channel */ switch (ht_info->extension_chan_offset) {case IWL_EXT_CHANNEL_OFFSET_ABOVE : rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK );
@@ -4544,6 +4708,12 @@ static const u16 default_tid_to_tx_fifo[] = { IWL_TX_FIFO_AC3 }; +/* +* Find first available (lowest unused) Tx Queue, mark it "active". +* Called only when finding queue for aggregation. +* Should never return anything < 7, because they should already +* be in use as EDCA AC (0-3), Command (4), HCCA (5, 6). +*/ static int iwl4965_txq_ctx_activate_free (struct iwl4965_priv *priv) {int txq_id;
@@ -4567,6 +4737,7 @@ int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, u8 *da, u16 tid,struct iwl4965_tid_data *tid_data;DECLARE_MAC_BUF (mac); +/* Determine Tx DMA/FIFO channel for this Traffic ID */ if (likely (tid <ARRAY_SIZE (default_tid_to_tx_fifo))) tx_fifo = default_tid_to_tx_fifo[tid];else
@@ -4575,22 +4746,31 @@ int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, u8 *da, u16 tid,IWL_WARNING ("iwl-AGG iwl4965_mac_ht_tx_agg_start on da=%s" " tid=%d\n" ,print_mac (mac, da), tid); +/* Get index into station table */ sta_id =iwl4965_hw_find_station (priv, da);if (sta_id ==IWL_INVALID_STATION )return -ENXIO ; +/* Find available Tx queue for aggregation */ txq_id =iwl4965_txq_ctx_activate_free (priv);if (txq_id ==-1 )return -ENXIO ;spin_lock_irqsave (&priv->sta_lock, flags); tid_data = &priv->stations[sta_id].tid[tid]; + +/* Get starting sequence number for 1st frame in block ack window. +* We'll use least signif byte as 1st frame's index into Tx queue. */ ssn =SEQ_TO_SN (tid_data->seq_number); tid_data->agg.txq_id = txq_id;spin_unlock_irqrestore (&priv->sta_lock, flags); *start_seq_num = ssn; + +/* Update driver's link quality manager */ iwl4965_ba_status (priv, tid,BA_STATUS_ACTIVE ); + +/* Set up and enable aggregation for selected Tx queue and FIFO */ return iwl4965_tx_queue_agg_enable (priv, txq_id, tx_fifo, sta_id, tid, ssn); }
drivers/net/wireless/iwlwifi/iwl4965-base.c +15 -3
@@ -306,6 +306,9 @@ static int iwl4965_tx_queue_alloc(struct iwl4965_priv *priv,return -ENOMEM ; } +/** +* iwl4965_tx_queue_init - Allocate and initialize one tx/cmd queue +*/ int iwl4965_tx_queue_init (struct iwl4965_priv *priv,struct iwl4965_tx_queue *txq,int slots_num,u32 txq_id) {
@@ -313,9 +316,14 @@ int iwl4965_tx_queue_init(struct iwl4965_priv *priv,int len;int rc =0 ; -/* allocate command space + one big command for scan since scan -* command is very huge the system will not have two scan at the -* same time */ +/* +* Alloc buffer array for commands (Tx or other types of commands). +* For the command queue (#4), allocate command space + one big +* command for scan, since scan command is very huge; the system will +* not have two scans at the same time, so only one is needed. +* For normal Tx queues (all other queues), no super-size command +* space is needed. +*/ len =sizeof (struct iwl4965_cmd ) * slots_num;if (txq_id ==IWL_CMD_QUEUE_NUM ) len +=IWL_MAX_SCAN_SIZE ;
@@ -323,6 +331,7 @@ int iwl4965_tx_queue_init(struct iwl4965_priv *priv,if (!txq->cmd)return -ENOMEM ; +/* Alloc driver data array and TFD circular buffer */ rc =iwl4965_tx_queue_alloc (priv, txq, txq_id);if (rc) {pci_free_consistent (dev, len, txq->cmd, txq->dma_addr_cmd);
@@ -334,8 +343,11 @@ int iwl4965_tx_queue_init(struct iwl4965_priv *priv,/* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise * iwl4965_queue_inc_wrap and iwl4965_queue_dec_wrap are broken. */ BUILD_BUG_ON (TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX -1 )); + +/* Initialize queue's high/low-water marks, and head/tail indexes */ iwl4965_queue_init (priv, &txq->q,TFD_QUEUE_SIZE_MAX , slots_num, txq_id); +/* Tell device where to find queue */ iwl4965_hw_tx_queue_init (priv, txq);return 0 ;
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 15/34 iwlwifi: add comments to iwl*-base.c
From: Zhu Yi <[email protected]>
Resend. Replace mail subject due to ML restriction for capital Triple-X in subject.
On Thu, 2007-11-29 at 11:09 +0800, Zhu Yi wrote:
From: Cahill, Ben M <[email protected]>
Add comments to iwlXXXX-base.c
--- drivers/net/wireless/iwlwifi/iwl3945-base.c | 215 ++++++++++++++++++++++----- drivers/net/wireless/iwlwifi/iwl4965-base.c | 209 ++++++++++++++++++++++---- 2 files changed, 354 insertions(+), 70 deletions(-)
drivers/net/wireless/iwlwifi/iwl3945-base.c +177 -38
@@ -63,13 +63,13 @@ static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv,******************************************************************************/ /* module parameters */ -static int iwl3945_param_disable_hw_scan; -static int iwl3945_param_debug; -static int iwl3945_param_disable;/* def: enable radio */ +static int iwl3945_param_disable_hw_scan;/* def: 0 = use 3945's h/w scan */ +static int iwl3945_param_debug;/* def: 0 = minimal debug log messages */ +static int iwl3945_param_disable;/* def: 0 = enable radio */ static int iwl3945_param_antenna;/* def: 0 = both antennas (use diversity) */ -int iwl3945_param_hwcrypto;/* def: using software encryption */ -static int iwl3945_param_qos_enable =1 ; -int iwl3945_param_queues_num =IWL_MAX_NUM_QUEUES ; +int iwl3945_param_hwcrypto;/* def: 0 = use software encryption */ +static int iwl3945_param_qos_enable =1 ;/* def: 1 = use quality of service */ +int iwl3945_param_queues_num =IWL_MAX_NUM_QUEUES ;/* def: 8 Tx queues */ /* * module name, copyright, version, etc.
@@ -184,17 +184,24 @@ static void iwl3945_print_hex_dump(int level, void *p, u32 len)* * Theory of operation * -* A queue is a circular buffers with 'Read' and 'Write' pointers. -* 2 empty entries always kept in the buffer to protect from overflow. +* A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer +* of buffer descriptors, each of which points to one or more data buffers for +* the device to read from or fill. Driver and device exchange status of each +* queue via "read" and "write" pointers. Driver keeps minimum of 2 empty +* entries in each circular buffer, to protect against confusing empty and full +* queue states. +* +* The device reads or writes the data in the queues via the device's several +* DMA/FIFO channels. Each queue is mapped to a single DMA channel. * * For Tx queue, there are low mark and high mark limits. If, after queuing * the packet for Tx, free space become < low mark, Tx queue stopped. When * reclaiming packets (on 'tx done IRQ), if free space become > high mark, * Tx queue resumed. * -* The IWL operates with six queues, one receive queue in the device's -* sram, one transmit queue for sending commands to the device firmware, -* and four transmit queues for data. +* The 3945 operates with six queues: One receive queue, one transmit queue +* (#4) for sending commands to the device firmware, and four transmit queues +* (#0-3) for data tx via EDCA. An additional 2 HCCA queues are unused. ***************************************************/ static int iwl3945_queue_space (const struct iwl3945_queue *q)
@@ -213,13 +220,21 @@ static int iwl3945_queue_space(const struct iwl3945_queue *q)return s; } -/* XXX: n_bd must be power-of-two size */ +/** +* iwl3945_queue_inc_wrap - increment queue index, wrap back to beginning +* @index -- current index +* @n_bd -- total number of entries in queue (must be power of 2) +*/ static inline int iwl3945_queue_inc_wrap (int index,int n_bd) {return ++index & (n_bd -1 ); } -/* XXX: n_bd must be power-of-two size */ +/** +* iwl3945_queue_dec_wrap - increment queue index, wrap back to end +* @index -- current index +* @n_bd -- total number of entries in queue (must be power of 2) +*/ static inline int iwl3945_queue_dec_wrap (int index,int n_bd) {return --index & (n_bd -1 );
@@ -234,12 +249,17 @@ static inline int x2_queue_used(const struct iwl3945_queue *q, int i)static inline u8 get_cmd_index (struct iwl3945_queue *q,u32 index,int is_huge) { +/* This is for scan command, the big buffer at end of command array */ if (is_huge) -return q->n_window; +return q->n_window;/* must be power of 2 */ +/* Otherwise, use normal size buffers */ return index & (q->n_window -1 ); } +/** +* iwl3945_queue_init - Initialize queue's high/low-water and read/write indexes +*/ static int iwl3945_queue_init (struct iwl3945_priv *priv,struct iwl3945_queue *q,int count,int slots_num,u32 id) {
@@ -268,11 +288,16 @@ static int iwl3945_queue_init(struct iwl3945_priv *priv, struct iwl3945_queue *qreturn 0 ; } +/** +* iwl3945_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue +*/ static int iwl3945_tx_queue_alloc (struct iwl3945_priv *priv,struct iwl3945_tx_queue *txq,u32 id) {struct pci_dev *dev = priv->pci_dev; +/* Driver private data, only for Tx (not command) queues, +* not shared with device. */ if (id !=IWL_CMD_QUEUE_NUM ) { txq->txb =kmalloc (sizeof (txq->txb[0 ]) *TFD_QUEUE_SIZE_MAX ,GFP_KERNEL );
@@ -284,6 +309,8 @@ static int iwl3945_tx_queue_alloc(struct iwl3945_priv *priv, }else txq->txb =NULL ; +/* Circular buffer of transmit frame descriptors (TFDs), +* shared with device */ txq->bd =pci_alloc_consistent (dev,sizeof (txq->bd[0 ]) *TFD_QUEUE_SIZE_MAX , &txq->q.dma_addr);
@@ -306,6 +333,9 @@ static int iwl3945_tx_queue_alloc(struct iwl3945_priv *priv,return -ENOMEM ; } +/** +* iwl3945_tx_queue_init - Allocate and initialize one tx/cmd queue +*/ int iwl3945_tx_queue_init (struct iwl3945_priv *priv,struct iwl3945_tx_queue *txq,int slots_num,u32 txq_id) {
@@ -313,9 +343,14 @@ int iwl3945_tx_queue_init(struct iwl3945_priv *priv,int len;int rc =0 ; -/* allocate command space + one big command for scan since scan -* command is very huge the system will not have two scan at the -* same time */ +/* +* Alloc buffer array for commands (Tx or other types of commands). +* For the command queue (#4), allocate command space + one big +* command for scan, since scan command is very huge; the system will +* not have two scans at the same time, so only one is needed. +* For data Tx queues (all other queues), no super-size command +* space is needed. +*/ len =sizeof (struct iwl3945_cmd ) * slots_num;if (txq_id ==IWL_CMD_QUEUE_NUM ) len +=IWL_MAX_SCAN_SIZE ;
@@ -323,6 +358,7 @@ int iwl3945_tx_queue_init(struct iwl3945_priv *priv,if (!txq->cmd)return -ENOMEM ; +/* Alloc driver data array and TFD circular buffer */ rc =iwl3945_tx_queue_alloc (priv, txq, txq_id);if (rc) {pci_free_consistent (dev, len, txq->cmd, txq->dma_addr_cmd);
@@ -334,8 +370,11 @@ int iwl3945_tx_queue_init(struct iwl3945_priv *priv,/* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise * iwl3945_queue_inc_wrap and iwl3945_queue_dec_wrap are broken. */ BUILD_BUG_ON (TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX -1 )); + +/* Initialize queue high/low-water, head/tail indexes */ iwl3945_queue_init (priv, &txq->q,TFD_QUEUE_SIZE_MAX , slots_num, txq_id); +/* Tell device where to find queue, enable DMA channel. */ iwl3945_hw_tx_queue_init (priv, txq);return 0 ;
@@ -346,8 +385,8 @@ int iwl3945_tx_queue_init(struct iwl3945_priv *priv,* @txq: Transmit queue to deallocate. * * Empty queue by removing and destroying all BD's. -* Free all buffers. txq itself is not freed. -* +* Free all buffers. +* 0-fill, but do not free "txq" descriptor structure. */ void iwl3945_tx_queue_free (struct iwl3945_priv *priv,struct iwl3945_tx_queue *txq) {
@@ -367,19 +406,21 @@ void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *tif (q->id ==IWL_CMD_QUEUE_NUM ) len +=IWL_MAX_SCAN_SIZE ; +/* De-alloc array of command/tx buffers */ pci_free_consistent (dev, len, txq->cmd, txq->dma_addr_cmd); -/* free buffers belonging to queue itself */ +/* De-alloc circular buffer of TFDs */ if (txq->q.n_bd)pci_free_consistent (dev,sizeof (struct iwl3945_tfd_frame ) * txq->q.n_bd, txq->bd, txq->q.dma_addr); +/* De-alloc array of per-TFD driver data */ if (txq->txb) {kfree (txq->txb); txq->txb =NULL ; } -/* 0 fill whole structure */ +/* 0-fill queue descriptor structure */ memset (txq,0 ,sizeof (*txq)); }
@@ -392,6 +433,11 @@ const u8 iwl3945_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF/**************************************************************/ #if 0 /* temporary disable till we add real remove station */ +/** +* iwl3945_remove_station - Remove driver's knowledge of station. +* +* NOTE: This does not remove station from device's station table. +*/ static u8 iwl3945_remove_station (struct iwl3945_priv *priv,const u8 *addr,int is_ap) {int index =IWL_INVALID_STATION ;
@@ -428,6 +474,12 @@ out: return 0; }#endif + +/** +* iwl3945_clear_stations_table - Clear the driver's station table +* +* NOTE: This does not clear or otherwise alter the device's station table. +*/ static void iwl3945_clear_stations_table (struct iwl3945_priv *priv) {unsigned long flags;
@@ -440,7 +492,9 @@ static void iwl3945_clear_stations_table(struct iwl3945_priv *priv)spin_unlock_irqrestore (&priv->sta_lock, flags); } - +/** +* iwl3945_add_station - Add station to station tables in driver and device +*/ u8 iwl3945_add_station (struct iwl3945_priv *priv,const u8 *addr,int is_ap,u8 flags) {int i;
@@ -486,6 +540,7 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8 station->used =1 ; priv->num_stations++; +/* Set up the REPLY_ADD_STA command to send to device */ memset (&station->sta,0 ,sizeof (struct iwl3945_addsta_cmd ));memcpy (station->sta.sta.addr, addr,ETH_ALEN ); station->sta.mode =0 ;
@@ -504,6 +559,8 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8le16_to_cpu (station->sta.rate_n_flags);spin_unlock_irqrestore (&priv->sta_lock, flags_spin); + +/* Add station to device's station table */ iwl3945_send_add_station (priv, &station->sta, flags);return index;
@@ -673,6 +730,8 @@ static int iwl3945_enqueue_hcmd(struct iwl3945_priv *priv, struct iwl3945_host_c fix_size, q->write_ptr, idx, IWL_CMD_QUEUE_NUM); txq->need_update =1 ; + +/* Increment and update queue's write index */ q->write_ptr =iwl3945_queue_inc_wrap (q->write_ptr, q->n_bd); ret =iwl3945_tx_queue_update_write_ptr (priv, txq);
@@ -1511,7 +1570,7 @@ static void get_eeprom_mac(struct iwl3945_priv *priv, u8 *mac)/** * iwl3945_eeprom_init - read EEPROM contents * -* Load the EEPROM from adapter into priv->eeprom +* Load the EEPROM contents from adapter into priv->eeprom * * NOTE: This routine uses the non-debug IO access functions. */
@@ -1536,6 +1595,7 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv)return -ENOENT ; } +/* Make sure driver (instead of uCode) is allowed to read EEPROM */ rc =iwl3945_eeprom_acquire_semaphore (priv);if (rc <0 ) {IWL_ERROR ("Failed to acquire EEPROM semaphore.\n" );
@@ -2631,21 +2691,23 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv, cmd->cmd.tx.next_frame_len =0 ; } +/** +* iwl3945_get_sta_id - Find station's index within station table +*/ static int iwl3945_get_sta_id (struct iwl3945_priv *priv,struct ieee80211_hdr *hdr) {int sta_id;u16 fc =le16_to_cpu (hdr->frame_control); -/* If this frame is broadcast or not data then use the broadcast -* station id */ +/* If this frame is broadcast or management, use broadcast station id */ if (((fc &IEEE80211_FCTL_FTYPE ) !=IEEE80211_FTYPE_DATA ) ||is_multicast_ether_addr (hdr->addr1))return priv->hw_setting.bcast_sta_id;switch (priv->iw_mode) { -/* If this frame is part of a BSS network (we're a station), then -* we use the AP's station id */ +/* If we are a client station in a BSS network, use the special +* AP station entry (that's the only station we communicate with) */ case IEEE80211_IF_TYPE_STA :return IWL_AP_ID ;
@@ -2656,11 +2718,12 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *hreturn sta_id;return priv->hw_setting.bcast_sta_id; -/* If this frame is part of a IBSS network, then we use the -* target specific station id */ +/* If this frame is going out to an IBSS network, find the station, +* or create a new station table entry */ case IEEE80211_IF_TYPE_IBSS : {DECLARE_MAC_BUF (mac); +/* Create new station table entry */ sta_id =iwl3945_hw_find_station (priv, hdr->addr1);if (sta_id !=IWL_INVALID_STATION )return sta_id;
@@ -2746,6 +2809,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,spin_unlock_irqrestore (&priv->lock, flags); hdr_len =ieee80211_get_hdrlen (fc); + +/* Find (or create) index into station table for destination station */ sta_id =iwl3945_get_sta_id (priv, hdr);if (sta_id ==IWL_INVALID_STATION ) {DECLARE_MAC_BUF (mac);
@@ -2767,30 +2832,52 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, __constant_cpu_to_le16(IEEE80211_SCTL_FRAG)); seq_number +=0x10 ; } + +/* Descriptor for chosen Tx queue */ txq = &priv->txq[txq_id]; q = &txq->q;spin_lock_irqsave (&priv->lock, flags); +/* Set up first empty TFD within this queue's circular TFD buffer */ tfd = &txq->bd[q->write_ptr];memset (tfd,0 ,sizeof (*tfd)); control_flags = (u32 *) tfd; idx =get_cmd_index (q, q->write_ptr,0 ); +/* Set up driver data for this TFD */ memset (&(txq->txb[q->write_ptr]),0 ,sizeof (struct iwl3945_tx_info )); txq->txb[q->write_ptr].skb[0 ] = skb;memcpy (&(txq->txb[q->write_ptr].status.control), ctl,sizeof (struct ieee80211_tx_control )); + +/* Init first empty entry in queue's array of Tx/cmd buffers */ out_cmd = &txq->cmd[idx];memset (&out_cmd->hdr,0 ,sizeof (out_cmd->hdr));memset (&out_cmd->cmd.tx,0 ,sizeof (out_cmd->cmd.tx)); + +/* +* Set up the Tx-command (not MAC!) header. +* Store the chosen Tx queue and TFD index within the sequence field; +* after Tx, uCode's Tx response will return this value so driver can +* locate the frame within the tx queue and do post-tx processing. +*/ out_cmd->hdr.cmd =REPLY_TX ; out_cmd->hdr.sequence =cpu_to_le16 ((u16)(QUEUE_TO_SEQ (txq_id) |INDEX_TO_SEQ (q->write_ptr))); -/* copy frags header */ + +/* Copy MAC header from skb into command buffer */ memcpy (out_cmd->cmd.tx.hdr, hdr, hdr_len); -/* hdr = (struct ieee80211_hdr *)out_cmd->cmd.tx.hdr; */ +/* +* Use the first empty entry in this queue's command buffer array +* to contain the Tx command and MAC header concatenated together +* (payload data will be in another buffer). +* Size of this varies, due to varying MAC header length. +* If end is not dword aligned, we'll have 2 extra bytes at the end +* of the MAC header (device reads on dword boundaries). +* We'll tell device about this padding later. +*/ len = priv->hw_setting.tx_cmd_len +sizeof (struct iwl3945_cmd_header ) + hdr_len;
@@ -2802,15 +2889,20 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,else len_org =0 ; +/* Physical address of this Tx command's header (not MAC header!), +* within command buffer array. */ txcmd_phys = txq->dma_addr_cmd +sizeof (struct iwl3945_cmd ) * idx + offsetof(struct iwl3945_cmd , hdr); +/* Add buffer containing Tx command and MAC(!) header to TFD's +* first entry */ iwl3945_hw_txq_attach_buf_to_tfd (priv, tfd, txcmd_phys, len);if (!(ctl->flags &IEEE80211_TXCTL_DO_NOT_ENCRYPT ))iwl3945_build_tx_cmd_hwcrypto (priv, ctl, out_cmd, skb,0 ); -/* 802.11 null functions have no payload... */ +/* Set up TFD's 2nd entry to point directly to remainder of skb, +* if any (802.11 null frames have no payload). */ len = skb->len - hdr_len;if (len) { phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
@@ -2818,13 +2910,16 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,iwl3945_hw_txq_attach_buf_to_tfd (priv, tfd, phys_addr, len); } -/* If there is no payload, then only one TFD is used */ if (!len) +/* If there is no payload, then we use only one Tx buffer */ *control_flags =TFD_CTL_COUNT_SET (1 );else +/* Else use 2 buffers. +* Tell 3945 about any padding after MAC header */ *control_flags =TFD_CTL_COUNT_SET (2 ) |TFD_CTL_PAD_SET (U32_PAD (len)); +/* Total # bytes to be transmitted */ len = (u16 )skb->len; out_cmd->cmd.tx.len =cpu_to_le16 (len);
@@ -2854,6 +2949,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,iwl3945_print_hex_dump (IWL_DL_TX , (u8 *)out_cmd->cmd.tx.hdr,ieee80211_get_hdrlen (fc)); +/* Tell device the write index *just past* this latest filled TFD */ q->write_ptr =iwl3945_queue_inc_wrap (q->write_ptr, q->n_bd); rc =iwl3945_tx_queue_update_write_ptr (priv, txq);spin_unlock_irqrestore (&priv->lock, flags);
@@ -3329,11 +3425,11 @@ static void iwl3945_txstatus_to_ieee(struct iwl3945_priv *priv, }/** -* iwl3945_tx_queue_reclaim - Reclaim Tx queue entries no more used by NIC. +* iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd * -* When FW advances 'R' index, all entries between old and -* new 'R' index need to be reclaimed. As result, some free space -* forms. If there is enough free space (> low mark), wake Tx queue. +* When FW advances 'R' index, all entries between old and new 'R' index +* need to be reclaimed. As result, some free space forms. If there is +* enough free space (> low mark), wake the stack that feeds us. */ static int iwl3945_tx_queue_reclaim (struct iwl3945_priv *priv,int txq_id,int index) {
@@ -3382,6 +3478,9 @@ static int iwl3945_is_tx_success(u32 status)* Generic RX handler implementations * ******************************************************************************/ +/** +* iwl3945_rx_reply_tx - Handle Tx response +*/ static void iwl3945_rx_reply_tx (struct iwl3945_priv *priv,struct iwl3945_rx_mem_buffer *rxb) {
@@ -3917,6 +4016,7 @@ int iwl3945_rx_queue_update_write_ptr(struct iwl3945_priv *priv, struct iwl3945_if (q->need_update ==0 ) goto exit_unlock; +/* If power-saving is in use, make sure device is awake */ if (test_bit (STATUS_POWER_PMI , &priv->status)) { reg =iwl3945_read32 (priv,CSR_UCODE_DRV_GP1 );
@@ -3930,10 +4030,14 @@ int iwl3945_rx_queue_update_write_ptr(struct iwl3945_priv *priv, struct iwl3945_if (rc) goto exit_unlock; +/* Device expects a multiple of 8 */ iwl3945_write_direct32 (priv,FH_RSCSR_CHNL0_WPTR , q->write & ~0x7 );iwl3945_release_nic_access (priv); + +/* Else device is assumed to be awake */ }else +/* Device expects a multiple of 8 */ iwl3945_write32 (priv,FH_RSCSR_CHNL0_WPTR , q->write & ~0x7 );
@@ -3975,9 +4079,12 @@ static int iwl3945_rx_queue_restock(struct iwl3945_priv *priv)spin_lock_irqsave (&rxq->lock, flags); write = rxq->write & ~0x7 ;while ((iwl3945_rx_queue_space (rxq) >0 ) && (rxq->free_count)) { +/* Get next free Rx buffer, remove from free list */ element = rxq->rx_free.next; rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list);list_del (element); + +/* Point to Rx buffer via next RBD in circular buffer */ rxq->bd[rxq->write] =iwl3945_dma_addr2rbd_ptr (priv, rxb->dma_addr); rxq->queue[rxq->write] = rxb; rxq->write = (rxq->write +1 ) &RX_QUEUE_MASK ;
@@ -3990,7 +4097,8 @@ static int iwl3945_rx_queue_restock(struct iwl3945_priv *priv)queue_work (priv->workqueue, &priv->rx_replenish); -/* If we've added more space for the firmware to place data, tell it */ +/* If we've added more space for the firmware to place data, tell it. +* Increment device's write pointer in multiples of 8. */ if ((write != (rxq->write & ~0x7 )) || (abs (rxq->write - rxq->read) >7 )) {spin_lock_irqsave (&rxq->lock, flags);
@@ -4023,6 +4131,8 @@ void iwl3945_rx_replenish(void *data)while (!list_empty (&rxq->rx_used)) { element = rxq->rx_used.next; rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list); + +/* Alloc a new receive buffer */ rxb->skb =alloc_skb (IWL_RX_BUF_SIZE , __GFP_NOWARN |GFP_ATOMIC );if (!rxb->skb) {
@@ -4036,6 +4146,8 @@ void iwl3945_rx_replenish(void *data) } priv->alloc_rxb_skb++;list_del (element); + +/* Get physical address of RB/SKB */ rxb->dma_addr =pci_map_single (priv->pci_dev, rxb->skb->data,IWL_RX_BUF_SIZE ,PCI_DMA_FROMDEVICE );
@@ -4080,12 +4192,16 @@ int iwl3945_rx_queue_alloc(struct iwl3945_priv *priv)spin_lock_init (&rxq->lock);INIT_LIST_HEAD (&rxq->rx_free);INIT_LIST_HEAD (&rxq->rx_used); + +/* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ rxq->bd =pci_alloc_consistent (dev,4 *RX_QUEUE_SIZE , &rxq->dma_addr);if (!rxq->bd)return -ENOMEM ; +/* Fill the rx_used queue with _all_ of the Rx buffers */ for (i =0 ; i <RX_FREE_BUFFERS +RX_QUEUE_SIZE ; i++)list_add_tail (&rxq->pool[i].list, &rxq->rx_used); +/* Set us so that we have processed and used all buffers, but have * not restocked the Rx queue with fresh buffers */ rxq->read = rxq->write =0 ;
@@ -4217,6 +4333,8 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)int reclaim;unsigned long flags; +/* uCode's read index (stored in shared DRAM) indicates the last Rx +* buffer that the driver may process (last buffer filled by ucode). */ r =iwl3945_hw_get_rx_read (priv); i = rxq->read;
@@ -4297,6 +4415,9 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)iwl3945_rx_queue_restock (priv); } +/** +* iwl3945_tx_queue_update_write_ptr - Send new write index to hardware +*/ static int iwl3945_tx_queue_update_write_ptr (struct iwl3945_priv *priv,struct iwl3945_tx_queue *txq) {
@@ -4924,6 +5045,11 @@ static void iwl3945_init_band_reference(const struct iwl3945_priv *priv, int ban } } +/** +* iwl3945_get_channel_info - Find driver's private channel info +* +* Based on band and channel number. +*/ const struct iwl3945_channel_info *iwl3945_get_channel_info (const struct iwl3945_priv *priv,int phymode,u16 channel) {
@@ -4951,6 +5077,9 @@ const struct iwl3945_channel_info *iwl3945_get_channel_info(const struct iwl3945#define CHECK_AND_PRINT (x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \ ? # x " " : "") +/** +* iwl3945_init_channel_map - Set up driver's info for all possible channels +*/ static int iwl3945_init_channel_map (struct iwl3945_priv *priv) {int eeprom_ch_count =0 ;
@@ -5060,6 +5189,7 @@ static int iwl3945_init_channel_map(struct iwl3945_priv *priv) } } +/* Set up txpower settings in driver for all channels */ if (iwl3945_txpower_set_from_eeprom (priv))return -EIO ;
@@ -8303,6 +8433,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *estruct ieee80211_hw *hw;int i; +/* Disabling hardware scan means that mac80211 will perform scans +* "the hard way", rather than using device's scan. */ if (iwl3945_param_disable_hw_scan) {IWL_DEBUG_INFO ("Disabling hw_scan\n" ); iwl3945_hw_ops.hw_scan =NULL ;
@@ -8333,6 +8465,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e priv->hw = hw; priv->pci_dev = pdev; + +/* Select antenna (may be helpful if only one antenna is connected) */ priv->antenna = (enum iwl3945_antenna )iwl3945_param_antenna;#ifdef CONFIG_IWL3945_DEBUG iwl3945_debug_level = iwl3945_param_debug;
@@ -8354,6 +8488,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e/* Tell mac80211 our Tx characteristics */ hw->flags =IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE ; +/* 4 EDCA QOS priorities */ hw->queues =4 ;spin_lock_init (&priv->lock);
@@ -8374,6 +8509,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *epci_set_master (pdev); +/* Clear the driver's (not device's) station table */ iwl3945_clear_stations_table (priv); priv->data_retry_limit =-1 ;
@@ -8393,9 +8529,11 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e err =pci_request_regions (pdev,DRV_NAME );if (err) goto out_pci_disable_device; +/* We disable the RETRY_TIMEOUT register (0x41) to keep * PCI Tx retries from interfering with C3 CPU state */ pci_write_config_byte (pdev,0x41 ,0x00 ); + priv->hw_base =pci_iomap (pdev,0 ,0 );if (!priv->hw_base) { err = -ENODEV ;
@@ -8408,6 +8546,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e/* Initialize module parameter values here */ +/* Disable radio (SW RF KILL) via parameter when loading driver */ if (iwl3945_param_disable) {set_bit (STATUS_RF_KILL_SW , &priv->status);IWL_DEBUG_INFO ("Radio disabled.\n" );
drivers/net/wireless/iwlwifi/iwl4965-base.c +177 -32
630 lines not on this page · raw message
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 16/34 iwlwifi: Clean up unused definitions in iwl-3945-hw.h
From: Ben Cahill <[email protected]>
Clean up unused definitions in iwl-3945-hw.h
--- drivers/net/wireless/iwlwifi/iwl-3945-hw.h | 130 +--------------------------- 1 files changed, 1 insertions(+), 129 deletions(-)
drivers/net/wireless/iwlwifi/iwl-3945-hw.h +1 -129
@@ -102,10 +102,6 @@#define IWL_EEPROM_ACCESS_TIMEOUT 5000/* uSec */ #define IWL_EEPROM_ACCESS_DELAY 10/* uSec */ -/* EEPROM field values */ -#define ANTENNA_SWITCH_NORMAL 0 -#define ANTENNA_SWITCH_INVERSE 1 -/* * Regulatory channel usage flags in EEPROM struct iwl_eeprom_channel.flags. *
@@ -127,31 +123,10 @@ enum {EEPROM_CHANNEL_ACTIVE = (1 <<3 ),/* active scanning allowed */ EEPROM_CHANNEL_RADAR = (1 <<4 ),/* radar detection required */ EEPROM_CHANNEL_WIDE = (1 <<5 ),/* 20 MHz channel okay */ -EEPROM_CHANNEL_NARROW = (1 <<6 ),/* 10 MHz channel, not used */ +EEPROM_CHANNEL_NARROW = (1 <<6 ),/* 10 MHz channel (not used) */ EEPROM_CHANNEL_DFS = (1 << 7), /* dynamic freq selection candidate */ }; -/* EEPROM field lengths */ -#define EEPROM_BOARD_PBA_NUMBER_LENGTH 11 - -/* EEPROM field lengths */ -#define EEPROM_BOARD_PBA_NUMBER_LENGTH 11 -#define EEPROM_REGULATORY_SKU_ID_LENGTH 4 -#define EEPROM_REGULATORY_BAND1_CHANNELS_LENGTH 14 -#define EEPROM_REGULATORY_BAND2_CHANNELS_LENGTH 13 -#define EEPROM_REGULATORY_BAND3_CHANNELS_LENGTH 12 -#define EEPROM_REGULATORY_BAND4_CHANNELS_LENGTH 11 -#define EEPROM_REGULATORY_BAND5_CHANNELS_LENGTH 6 - -#define EEPROM_REGULATORY_CHANNELS_LENGTH ( \ - EEPROM_REGULATORY_BAND1_CHANNELS_LENGTH + \ - EEPROM_REGULATORY_BAND2_CHANNELS_LENGTH + \ - EEPROM_REGULATORY_BAND3_CHANNELS_LENGTH + \ - EEPROM_REGULATORY_BAND4_CHANNELS_LENGTH + \ - EEPROM_REGULATORY_BAND5_CHANNELS_LENGTH) - -#define EEPROM_REGULATORY_NUMBER_OF_BANDS 5 -/* SKU Capabilities */ #define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE (1 << 0)#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE (1 << 1)
@@ -646,15 +621,7 @@ struct iwl3945_eeprom {/* spectrum and channel data structures */ #define IWL_NUM_SCAN_RATES (2) -#define IWL_SCAN_FLAG_24GHZ (1<<0) -#define IWL_SCAN_FLAG_52GHZ (1<<1) -#define IWL_SCAN_FLAG_ACTIVE (1<<2) -#define IWL_SCAN_FLAG_DIRECT (1<<3) - -#define IWL_MAX_CMD_SIZE 1024 -#define IWL_DEFAULT_TX_RETRY 15 -#define IWL_MAX_TX_RETRY 16/*********************************************/
@@ -665,101 +632,6 @@ struct iwl3945_eeprom {#define RX_QUEUE_MASK 255#define RX_QUEUE_SIZE_LOG 8 -/* QoS definitions */ - -#define CW_MIN_OFDM 15 -#define CW_MAX_OFDM 1023 -#define CW_MIN_CCK 31 -#define CW_MAX_CCK 1023 - -#define QOS_TX0_CW_MIN_OFDM CW_MIN_OFDM -#define QOS_TX1_CW_MIN_OFDM CW_MIN_OFDM -#define QOS_TX2_CW_MIN_OFDM ((CW_MIN_OFDM + 1) / 2 - 1) -#define QOS_TX3_CW_MIN_OFDM ((CW_MIN_OFDM + 1) / 4 - 1) - -#define QOS_TX0_CW_MIN_CCK CW_MIN_CCK -#define QOS_TX1_CW_MIN_CCK CW_MIN_CCK -#define QOS_TX2_CW_MIN_CCK ((CW_MIN_CCK + 1) / 2 - 1) -#define QOS_TX3_CW_MIN_CCK ((CW_MIN_CCK + 1) / 4 - 1) - -#define QOS_TX0_CW_MAX_OFDM CW_MAX_OFDM -#define QOS_TX1_CW_MAX_OFDM CW_MAX_OFDM -#define QOS_TX2_CW_MAX_OFDM CW_MIN_OFDM -#define QOS_TX3_CW_MAX_OFDM ((CW_MIN_OFDM + 1) / 2 - 1) - -#define QOS_TX0_CW_MAX_CCK CW_MAX_CCK -#define QOS_TX1_CW_MAX_CCK CW_MAX_CCK -#define QOS_TX2_CW_MAX_CCK CW_MIN_CCK -#define QOS_TX3_CW_MAX_CCK ((CW_MIN_CCK + 1) / 2 - 1) - -#define QOS_TX0_AIFS 3 -#define QOS_TX1_AIFS 7 -#define QOS_TX2_AIFS 2 -#define QOS_TX3_AIFS 2 - -#define QOS_TX0_ACM 0 -#define QOS_TX1_ACM 0 -#define QOS_TX2_ACM 0 -#define QOS_TX3_ACM 0 - -#define QOS_TX0_TXOP_LIMIT_CCK 0 -#define QOS_TX1_TXOP_LIMIT_CCK 0 -#define QOS_TX2_TXOP_LIMIT_CCK 6016 -#define QOS_TX3_TXOP_LIMIT_CCK 3264 - -#define QOS_TX0_TXOP_LIMIT_OFDM 0 -#define QOS_TX1_TXOP_LIMIT_OFDM 0 -#define QOS_TX2_TXOP_LIMIT_OFDM 3008 -#define QOS_TX3_TXOP_LIMIT_OFDM 1504 - -#define DEF_TX0_CW_MIN_OFDM CW_MIN_OFDM -#define DEF_TX1_CW_MIN_OFDM CW_MIN_OFDM -#define DEF_TX2_CW_MIN_OFDM CW_MIN_OFDM -#define DEF_TX3_CW_MIN_OFDM CW_MIN_OFDM - -#define DEF_TX0_CW_MIN_CCK CW_MIN_CCK -#define DEF_TX1_CW_MIN_CCK CW_MIN_CCK -#define DEF_TX2_CW_MIN_CCK CW_MIN_CCK -#define DEF_TX3_CW_MIN_CCK CW_MIN_CCK - -#define DEF_TX0_CW_MAX_OFDM CW_MAX_OFDM -#define DEF_TX1_CW_MAX_OFDM CW_MAX_OFDM -#define DEF_TX2_CW_MAX_OFDM CW_MAX_OFDM -#define DEF_TX3_CW_MAX_OFDM CW_MAX_OFDM - -#define DEF_TX0_CW_MAX_CCK CW_MAX_CCK -#define DEF_TX1_CW_MAX_CCK CW_MAX_CCK -#define DEF_TX2_CW_MAX_CCK CW_MAX_CCK -#define DEF_TX3_CW_MAX_CCK CW_MAX_CCK - -#define DEF_TX0_AIFS (2) -#define DEF_TX1_AIFS (2) -#define DEF_TX2_AIFS (2) -#define DEF_TX3_AIFS (2) - -#define DEF_TX0_ACM 0 -#define DEF_TX1_ACM 0 -#define DEF_TX2_ACM 0 -#define DEF_TX3_ACM 0 - -#define DEF_TX0_TXOP_LIMIT_CCK 0 -#define DEF_TX1_TXOP_LIMIT_CCK 0 -#define DEF_TX2_TXOP_LIMIT_CCK 0 -#define DEF_TX3_TXOP_LIMIT_CCK 0 - -#define DEF_TX0_TXOP_LIMIT_OFDM 0 -#define DEF_TX1_TXOP_LIMIT_OFDM 0 -#define DEF_TX2_TXOP_LIMIT_OFDM 0 -#define DEF_TX3_TXOP_LIMIT_OFDM 0 - -#define QOS_QOS_SETS 3 -#define QOS_PARAM_SET_ACTIVE 0 -#define QOS_PARAM_SET_DEF_CCK 1 -#define QOS_PARAM_SET_DEF_OFDM 2 - -#define CTRL_QOS_NO_ACK (0x0020) -#define DCT_FLAG_EXT_QOS_ENABLED (0x10) -#define U32_PAD (n) ((4-(n))&0x3)/*
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 17/34 iwlwifi: clean up unused definitions in iwl-4965-hw.h
From: Ben Cahill <[email protected]>
Clean up unused definitions in iwl-4965-hw.h
--- drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 389 +--------------------------- 1 files changed, 3 insertions(+), 386 deletions(-)
drivers/net/wireless/iwlwifi/iwl-4965-hw.h +3 -386
@@ -106,10 +106,6 @@#define IWL_EEPROM_ACCESS_TIMEOUT 5000/* uSec */ #define IWL_EEPROM_ACCESS_DELAY 10/* uSec */ -/* EEPROM field values */ -#define ANTENNA_SWITCH_NORMAL 0 -#define ANTENNA_SWITCH_INVERSE 1 -/* * Regulatory channel usage flags in EEPROM struct iwl4965_eeprom_channel.flags. *
@@ -133,39 +129,13 @@ enum {EEPROM_CHANNEL_ACTIVE = (1 <<3 ),/* active scanning allowed */ EEPROM_CHANNEL_RADAR = (1 <<4 ),/* radar detection required */ EEPROM_CHANNEL_WIDE = (1 <<5 ),/* 20 MHz channel okay */ -EEPROM_CHANNEL_NARROW = (1 <<6 ),/* 10 MHz channel, not used */ +EEPROM_CHANNEL_NARROW = (1 <<6 ),/* 10 MHz channel (not used) */ EEPROM_CHANNEL_DFS = (1 << 7), /* dynamic freq selection candidate */ }; -/* EEPROM field lengths */ -#define EEPROM_BOARD_PBA_NUMBER_LENGTH 11 - -/* EEPROM field lengths */ -#define EEPROM_BOARD_PBA_NUMBER_LENGTH 11 -#define EEPROM_REGULATORY_SKU_ID_LENGTH 4 -#define EEPROM_REGULATORY_BAND1_CHANNELS_LENGTH 14 -#define EEPROM_REGULATORY_BAND2_CHANNELS_LENGTH 13 -#define EEPROM_REGULATORY_BAND3_CHANNELS_LENGTH 12 -#define EEPROM_REGULATORY_BAND4_CHANNELS_LENGTH 11 -#define EEPROM_REGULATORY_BAND5_CHANNELS_LENGTH 6 - -#define EEPROM_REGULATORY_BAND_24_FAT_CHANNELS_LENGTH 7 -#define EEPROM_REGULATORY_BAND_52_FAT_CHANNELS_LENGTH 11 -#define EEPROM_REGULATORY_CHANNELS_LENGTH ( \ - EEPROM_REGULATORY_BAND1_CHANNELS_LENGTH + \ - EEPROM_REGULATORY_BAND2_CHANNELS_LENGTH + \ - EEPROM_REGULATORY_BAND3_CHANNELS_LENGTH + \ - EEPROM_REGULATORY_BAND4_CHANNELS_LENGTH + \ - EEPROM_REGULATORY_BAND5_CHANNELS_LENGTH + \ - EEPROM_REGULATORY_BAND_24_FAT_CHANNELS_LENGTH + \ - EEPROM_REGULATORY_BAND_52_FAT_CHANNELS_LENGTH) - -#define EEPROM_REGULATORY_NUMBER_OF_BANDS 5 -/* SKU Capabilities */ #define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE (1 << 0)#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE (1 << 1) -#define EEPROM_SKU_CAP_OP_MODE_MRC (1 << 7)/* *regulatory* channel data format in eeprom, one for each channel. * There are separate entries for FAT (40 MHz) vs. normal (20 MHz) channels. */
@@ -479,13 +449,6 @@ struct iwl4965_eeprom {*/ #define CSR_HW_REV_WA_REG (CSR_BASE+0x22C) -/* HW I/F configuration */ -#define CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MB (0x00000100) -#define CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MM (0x00000200) -#define CSR_HW_IF_CONFIG_REG_BIT_SKU_MRC (0x00000400) -#define CSR_HW_IF_CONFIG_REG_BIT_BOARD_TYPE (0x00000800) -#define CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A (0x00000000) -#define CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B (0x00001000)#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000)/* interrupt flags in INTA, set by uCode or hardware (e.g. dma),
@@ -514,20 +477,16 @@ struct iwl4965_eeprom {/* interrupt flags in FH (flow handler) (PCI busmaster DMA) */ #define CSR_FH_INT_BIT_ERR (1<<31)/* Error */ #define CSR_FH_INT_BIT_HI_PRIOR (1<<30)/* High priority Rx, bypass coalescing */ -#define CSR_FH_INT_BIT_RX_CHNL2 (1<<18)/* Rx channel 2 (3945 only) */ #define CSR_FH_INT_BIT_RX_CHNL1 (1<<17)/* Rx channel 1 */ #define CSR_FH_INT_BIT_RX_CHNL0 (1<<16)/* Rx channel 0 */ -#define CSR_FH_INT_BIT_TX_CHNL6 (1<<6)/* Tx channel 6 (3945 only) */ #define CSR_FH_INT_BIT_TX_CHNL1 (1<<1)/* Tx channel 1 */ #define CSR_FH_INT_BIT_TX_CHNL0 (1<<0)/* Tx channel 0 */ #define CSR_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \ - CSR_FH_INT_BIT_RX_CHNL2 | \ CSR_FH_INT_BIT_RX_CHNL1 | \ CSR_FH_INT_BIT_RX_CHNL0) -#define CSR_FH_INT_TX_MASK (CSR_FH_INT_BIT_TX_CHNL6 | \ - CSR_FH_INT_BIT_TX_CHNL1 | \ +#define CSR_FH_INT_TX_MASK (CSR_FH_INT_BIT_TX_CHNL1 | \ CSR_FH_INT_BIT_TX_CHNL0 )
@@ -619,30 +578,6 @@ struct iwl4965_eeprom {/*=== FH (data Flow Handler) ===*/ #define FH_BASE (0x800) -#define FH_CBCC_TABLE (FH_BASE+0x140) -#define FH_TFDB_TABLE (FH_BASE+0x180) -#define FH_RCSR_TABLE (FH_BASE+0x400) -#define FH_RSSR_TABLE (FH_BASE+0x4c0) -#define FH_TCSR_TABLE (FH_BASE+0x500) -#define FH_TSSR_TABLE (FH_BASE+0x680) - -/* TFDB (Transmit Frame Buffer Descriptor) */ -#define FH_TFDB (_channel, buf) \ - (FH_TFDB_TABLE+((_channel)*2+(buf))*0x28) -#define ALM_FH_TFDB_CHNL_BUF_CTRL_REG (_channel) \ - (FH_TFDB_TABLE + 0x50 * _channel) -/* CBCC _channel is [0,2] */ -#define FH_CBCC (_channel) (FH_CBCC_TABLE+(_channel)*0x8) -#define FH_CBCC_CTRL (_channel) (FH_CBCC(_channel)+0x00) -#define FH_CBCC_BASE (_channel) (FH_CBCC(_channel)+0x04) - -/* RCSR _channel is [0,2] */ -#define FH_RCSR (_channel) (FH_RCSR_TABLE+(_channel)*0x40) -#define FH_RCSR_CONFIG (_channel) (FH_RCSR(_channel)+0x00) -#define FH_RCSR_RBD_BASE (_channel) (FH_RCSR(_channel)+0x04) -#define FH_RCSR_WPTR (_channel) (FH_RCSR(_channel)+0x20) -#define FH_RCSR_RPTR_ADDR (_channel) (FH_RCSR(_channel)+0x24) -#define FH_RSCSR_CHNL0_WPTR (FH_RSCSR_CHNL0_RBDCB_WPTR_REG)/* RSSR */
@@ -663,202 +598,19 @@ struct iwl4965_eeprom {#define RTC_INST_LOWER_BOUND (0x000000)#define RTC_DATA_LOWER_BOUND (0x800000) - -/* DBM */ - -#define ALM_FH_SRVC_CHNL (6) - -#define ALM_FH_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE (20) -#define ALM_FH_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH (4) - -#define ALM_FH_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN (0x08000000) - -#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE (0x80000000) - -#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE (0x20000000) - -#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 (0x01000000) - -#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST (0x00001000) - -#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH (0x00000000) - -#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF (0x00000000) -#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER (0x00000001) - -#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL (0x00000000) -#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL (0x00000008) - -#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD (0x00200000) - -#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT (0x00000000) - -#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE (0x00000000) -#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE (0x80000000) - -#define ALM_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID (0x00004000) - -#define ALM_FH_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR (0x00000001) - -#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON (0xFF000000) -#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON (0x00FF0000) - -#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B (0x00000400) - -#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON (0x00000100) -#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON (0x00000080) - -#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH (0x00000020) -#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH (0x00000005) - -#define ALM_TB_MAX_BYTES_COUNT (0xFFF0) - -#define ALM_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY (_channel) \ - ((1LU << _channel) << 24) -#define ALM_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ (_channel) \ - ((1LU << _channel) << 16) - -#define ALM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE (_channel) \ - (ALM_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_channel) | \ - ALM_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_channel)) -#define PCI_CFG_REV_ID_BIT_BASIC_SKU (0x40)/* bit 6 */ -#define PCI_CFG_REV_ID_BIT_RTP (0x80)/* bit 7 */ -#define HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED (0x00000004) -#define TFD_QUEUE_MIN 0 -#define TFD_QUEUE_MAX 6#define TFD_QUEUE_SIZE_MAX (256)/* spectrum and channel data structures */ #define IWL_NUM_SCAN_RATES (2) -#define IWL_SCAN_FLAG_24GHZ (1<<0) -#define IWL_SCAN_FLAG_52GHZ (1<<1) -#define IWL_SCAN_FLAG_ACTIVE (1<<2) -#define IWL_SCAN_FLAG_DIRECT (1<<3) - -#define IWL_MAX_CMD_SIZE 1024 -#define IWL_DEFAULT_TX_RETRY 15 -#define IWL_MAX_TX_RETRY 16 - -/*********************************************/ - -#define RFD_SIZE 4 -#define NUM_TFD_CHUNKS 4#define RX_QUEUE_SIZE 256#define RX_QUEUE_MASK 255#define RX_QUEUE_SIZE_LOG 8 -/* QoS definitions */ - -#define CW_MIN_OFDM 15 -#define CW_MAX_OFDM 1023 -#define CW_MIN_CCK 31 -#define CW_MAX_CCK 1023 - -#define QOS_TX0_CW_MIN_OFDM CW_MIN_OFDM -#define QOS_TX1_CW_MIN_OFDM CW_MIN_OFDM -#define QOS_TX2_CW_MIN_OFDM ((CW_MIN_OFDM + 1) / 2 - 1) -#define QOS_TX3_CW_MIN_OFDM ((CW_MIN_OFDM + 1) / 4 - 1) - -#define QOS_TX0_CW_MIN_CCK CW_MIN_CCK -#define QOS_TX1_CW_MIN_CCK CW_MIN_CCK -#define QOS_TX2_CW_MIN_CCK ((CW_MIN_CCK + 1) / 2 - 1) -#define QOS_TX3_CW_MIN_CCK ((CW_MIN_CCK + 1) / 4 - 1) - -#define QOS_TX0_CW_MAX_OFDM CW_MAX_OFDM -#define QOS_TX1_CW_MAX_OFDM CW_MAX_OFDM -#define QOS_TX2_CW_MAX_OFDM CW_MIN_OFDM -#define QOS_TX3_CW_MAX_OFDM ((CW_MIN_OFDM + 1) / 2 - 1) - -#define QOS_TX0_CW_MAX_CCK CW_MAX_CCK -#define QOS_TX1_CW_MAX_CCK CW_MAX_CCK -#define QOS_TX2_CW_MAX_CCK CW_MIN_CCK -#define QOS_TX3_CW_MAX_CCK ((CW_MIN_CCK + 1) / 2 - 1) - -#define QOS_TX0_AIFS 3 -#define QOS_TX1_AIFS 7 -#define QOS_TX2_AIFS 2 -#define QOS_TX3_AIFS 2 - -#define QOS_TX0_ACM 0 -#define QOS_TX1_ACM 0 -#define QOS_TX2_ACM 0 -#define QOS_TX3_ACM 0 - -#define QOS_TX0_TXOP_LIMIT_CCK 0 -#define QOS_TX1_TXOP_LIMIT_CCK 0 -#define QOS_TX2_TXOP_LIMIT_CCK 6016 -#define QOS_TX3_TXOP_LIMIT_CCK 3264 - -#define QOS_TX0_TXOP_LIMIT_OFDM 0 -#define QOS_TX1_TXOP_LIMIT_OFDM 0 -#define QOS_TX2_TXOP_LIMIT_OFDM 3008 -#define QOS_TX3_TXOP_LIMIT_OFDM 1504 - -#define DEF_TX0_CW_MIN_OFDM CW_MIN_OFDM -#define DEF_TX1_CW_MIN_OFDM CW_MIN_OFDM -#define DEF_TX2_CW_MIN_OFDM CW_MIN_OFDM -#define DEF_TX3_CW_MIN_OFDM CW_MIN_OFDM - -#define DEF_TX0_CW_MIN_CCK CW_MIN_CCK -#define DEF_TX1_CW_MIN_CCK CW_MIN_CCK -#define DEF_TX2_CW_MIN_CCK CW_MIN_CCK -#define DEF_TX3_CW_MIN_CCK CW_MIN_CCK - -#define DEF_TX0_CW_MAX_OFDM CW_MAX_OFDM -#define DEF_TX1_CW_MAX_OFDM CW_MAX_OFDM -#define DEF_TX2_CW_MAX_OFDM CW_MAX_OFDM -#define DEF_TX3_CW_MAX_OFDM CW_MAX_OFDM - -#define DEF_TX0_CW_MAX_CCK CW_MAX_CCK -#define DEF_TX1_CW_MAX_CCK CW_MAX_CCK -#define DEF_TX2_CW_MAX_CCK CW_MAX_CCK -#define DEF_TX3_CW_MAX_CCK CW_MAX_CCK - -#define DEF_TX0_AIFS (2) -#define DEF_TX1_AIFS (2) -#define DEF_TX2_AIFS (2) -#define DEF_TX3_AIFS (2) - -#define DEF_TX0_ACM 0 -#define DEF_TX1_ACM 0 -#define DEF_TX2_ACM 0 -#define DEF_TX3_ACM 0 - -#define DEF_TX0_TXOP_LIMIT_CCK 0 -#define DEF_TX1_TXOP_LIMIT_CCK 0 -#define DEF_TX2_TXOP_LIMIT_CCK 0 -#define DEF_TX3_TXOP_LIMIT_CCK 0 - -#define DEF_TX0_TXOP_LIMIT_OFDM 0 -#define DEF_TX1_TXOP_LIMIT_OFDM 0 -#define DEF_TX2_TXOP_LIMIT_OFDM 0 -#define DEF_TX3_TXOP_LIMIT_OFDM 0 - -#define QOS_QOS_SETS 3 -#define QOS_PARAM_SET_ACTIVE 0 -#define QOS_PARAM_SET_DEF_CCK 1 -#define QOS_PARAM_SET_DEF_OFDM 2 - -#define CTRL_QOS_NO_ACK (0x0020) -#define DCT_FLAG_EXT_QOS_ENABLED (0x10) - -#define U32_PAD (n) ((4-(n))&0x3) - -/* -* Generic queue structure -* -* Contains common data for Rx and Tx queues -*/ -#define TFD_CTL_COUNT_SET (n) (n<<24) -#define TFD_CTL_COUNT_GET (ctl) ((ctl>>24) & 7) -#define TFD_CTL_PAD_SET (n) (n<<28) -#define TFD_CTL_PAD_GET (ctl) (ctl>>28) -#define TFD_TX_CMD_SLOTS 256#define TFD_CMD_SLOTS 32
@@ -917,28 +669,13 @@ enum { (((t) <IWL_TX_POWER_TEMPERATURE_MIN ) || \ ((t) > IWL_TX_POWER_TEMPERATURE_MAX)) -#define IWL_TX_POWER_ILLEGAL_TEMPERATURE (300) - -#define IWL_TX_POWER_TEMPERATURE_DIFFERENCE (2) -#define IWL_TX_POWER_MIMO_REGULATORY_COMPENSATION (6)#define IWL_TX_POWER_TARGET_POWER_MIN (0)/* 0 dBm = 1 milliwatt */ #define IWL_TX_POWER_TARGET_POWER_MAX (16)/* 16 dBm */ -/* timeout equivalent to 3 minutes */ -#define IWL_TX_POWER_TIMELIMIT_NOCALIB 1800000000 - -#define IWL_TX_POWER_CCK_COMPENSATION (9) -#define MIN_TX_GAIN_INDEX (0)#define MIN_TX_GAIN_INDEX_52GHZ_EXT (-9) -#define MAX_TX_GAIN_INDEX_52GHZ (98) -#define MIN_TX_GAIN_52GHZ (98) -#define MAX_TX_GAIN_INDEX_24GHZ (98) -#define MIN_TX_GAIN_24GHZ (98) -#define MAX_TX_GAIN (0) -#define MAX_TX_GAIN_52GHZ_EXT (-9)#define IWL_TX_POWER_DEFAULT_REGULATORY_24 (34)#define IWL_TX_POWER_DEFAULT_REGULATORY_52 (34)
@@ -949,48 +686,6 @@ enum {#define IWL_TX_POWER_SATURATION_MIN (20)#define IWL_TX_POWER_SATURATION_MAX (50) -/* dv *0.4 = dt; so that 5 degrees temperature diff equals -* 12.5 in voltage diff */ -#define IWL_TX_TEMPERATURE_UPDATE_LIMIT 9 - -#define IWL_INVALID_CHANNEL (0xffffffff) -#define IWL_TX_POWER_REGITRY_BIT (2) - -#define MIN_IWL_TX_POWER_CALIB_DUR (100) -#define IWL_CCK_FROM_OFDM_POWER_DIFF (-5) -#define IWL_CCK_FROM_OFDM_INDEX_DIFF (9) - -/* Number of entries in the gain table */ -#define POWER_GAIN_NUM_ENTRIES 78 -#define TX_POW_MAX_SESSION_NUM 5 -/* timeout equivalent to 3 minutes */ -#define TX_IWL_TIMELIMIT_NOCALIB 1800000000 - -/* Kedron TX_CALIB_STATES */ -#define IWL_TX_CALIB_STATE_SEND_TX 0x00000001 -#define IWL_TX_CALIB_WAIT_TX_RESPONSE 0x00000002 -#define IWL_TX_CALIB_ENABLED 0x00000004 -#define IWL_TX_CALIB_XVT_ON 0x00000008 -#define IWL_TX_CALIB_TEMPERATURE_CORRECT 0x00000010 -#define IWL_TX_CALIB_WORKING_WITH_XVT 0x00000020 -#define IWL_TX_CALIB_XVT_PERIODICAL 0x00000040 - -#define NUM_IWL_TX_CALIB_SETTINS 5/* Number of tx correction groups */ - -#define IWL_MIN_POWER_IN_VP_TABLE 1/* 0.5dBm multiplied by 2 */ -#define IWL_MAX_POWER_IN_VP_TABLE 40/* 20dBm - multiplied by 2 (because -* entries are for each 0.5dBm) */ -#define IWL_STEP_IN_VP_TABLE 1/* 0.5dB - multiplied by 2 */ -#define IWL_NUM_POINTS_IN_VPTABLE \ - (1 + IWL_MAX_POWER_IN_VP_TABLE - IWL_MIN_POWER_IN_VP_TABLE) - -#define MIN_TX_GAIN_INDEX (0) -#define MAX_TX_GAIN_INDEX_52GHZ (98) -#define MIN_TX_GAIN_52GHZ (98) -#define MAX_TX_GAIN_INDEX_24GHZ (98) -#define MIN_TX_GAIN_24GHZ (98) -#define MAX_TX_GAIN (0) -/* First and last channels of all groups */ #define CALIB_IWL_TX_ATTEN_GR1_FCH 34#define CALIB_IWL_TX_ATTEN_GR1_LCH 43
@@ -1003,7 +698,6 @@ enum {#define CALIB_IWL_TX_ATTEN_GR5_FCH 1#define CALIB_IWL_TX_ATTEN_GR5_LCH 20 -union iwl4965_tx_power_dual_stream {struct {u8 radio_tx_gain[2 ];
@@ -1043,23 +737,6 @@ union iwl4965_tx_power_dual_stream {#define RXON_RX_CHAIN_MIMO_FORCE_POS (14) -#define MCS_DUP_6M_PLCP 0x20 - -/* OFDM HT rate masks */ -/* ***************************************** */ -#define R_MCS_6M_MSK 0x1 -#define R_MCS_12M_MSK 0x2 -#define R_MCS_18M_MSK 0x4 -#define R_MCS_24M_MSK 0x8 -#define R_MCS_36M_MSK 0x10 -#define R_MCS_48M_MSK 0x20 -#define R_MCS_54M_MSK 0x40 -#define R_MCS_60M_MSK 0x80 -#define R_MCS_12M_DUAL_MSK 0x100 -#define R_MCS_24M_DUAL_MSK 0x200 -#define R_MCS_36M_DUAL_MSK 0x400 -#define R_MCS_48M_DUAL_MSK 0x800 -/* Flow Handler Definitions */ /**********************/
@@ -1107,7 +784,6 @@ union iwl4965_tx_power_dual_stream {#define IWL_FH_TCSR_LOWER_BOUND (IWL_FH_REGS_LOWER_BOUND + 0xD00)#define IWL_FH_TCSR_UPPER_BOUND (IWL_FH_REGS_LOWER_BOUND + 0xE60) -#define IWL_FH_TCSR_CHNL_NUM (7)#define IWL_FH_TCSR_CHNL_TX_CONFIG_REG (_chnl) \ (IWL_FH_TCSR_LOWER_BOUND + 0x20 * _chnl)
@@ -1116,23 +792,8 @@ union iwl4965_tx_power_dual_stream {#define IWL_FH_TSSR_LOWER_BOUND (IWL_FH_REGS_LOWER_BOUND + 0xEA0)#define IWL_FH_TSSR_UPPER_BOUND (IWL_FH_REGS_LOWER_BOUND + 0xEC0) -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG (IWL_FH_TSSR_LOWER_BOUND + 0x008)#define IWL_FH_TSSR_TX_STATUS_REG (IWL_FH_TSSR_LOWER_BOUND + 0x010) -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON (0xFF000000) -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON (0x00FF0000) - -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_64B (0x00000000) -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B (0x00000400) -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_256B (0x00000800) -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_512B (0x00000C00) - -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON (0x00000100) -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON (0x00000080) - -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH (0x00000020) -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH (0x00000005) -#define IWL_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY (_chnl) \ ((1 << (_chnl)) << 24)#define IWL_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ (_chnl) \
@@ -1143,49 +804,17 @@ union iwl4965_tx_power_dual_stream { IWL_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_chnl))/* TCSR: tx_config register values */ -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF (0x00000000) -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER (0x00000001) -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_ARC (0x00000002) - -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL (0x00000000)#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL (0x00000008) -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_NOINT (0x00000000) -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD (0x00100000) -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD (0x00200000) - -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT (0x00000000) -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_ENDTFD (0x00400000) -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_IFTFD (0x00800000) - -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE (0x00000000) -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE_EOF (0x40000000)#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE (0x80000000) -#define IWL_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_EMPTY (0x00000000) -#define IWL_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_WAIT (0x00002000) -#define IWL_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID (0x00000003) - -#define IWL_FH_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR (0x00000001) - -#define IWL_FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM (20) -#define IWL_FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX (12) -/* RCSR: channel 0 rx_config register defines */ -#define FH_RCSR_CHNL0_RX_CONFIG_DMA_CHNL_EN_MASK (0xC0000000)/* bits 30-31 */ -#define FH_RCSR_CHNL0_RX_CONFIG_RBDBC_SIZE_MASK (0x00F00000)/* bits 20-23 */ -#define FH_RCSR_CHNL0_RX_CONFIG_RB_SIZE_MASK (0x00030000)/* bits 16-17 */ -#define FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MASK (0x00008000)/* bit 15 */ -#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_MASK (0x00001000)/* bit 12 */ -#define FH_RCSR_CHNL0_RX_CONFIG_RB_TIMEOUT_MASK (0x00000FF0)/* bit 4-11 */ #define FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT (20)#define FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_BITSHIFT (4)#define RX_RB_TIMEOUT (0x10)/* RCSR: rx_config register values */ -#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_VAL (0x00000000) -#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_EOF_VAL (0x40000000)#define FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL (0x80000000)#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K (0x00000000)
@@ -1194,7 +823,6 @@ union iwl4965_tx_power_dual_stream {#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_16K (0x00030000)/* RCSR channel 0 config register values */ -#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_NO_INT_VAL (0x00000000)#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL (0x00001000)/* RSCSR: defs used in normal mode */
@@ -1214,12 +842,6 @@ union iwl4965_tx_power_dual_stream {#define SCD_TXFACT_REG_TXFIFO_MASK (lo, hi) \ ((1<<(hi))|((1<<(hi))-(1<<(lo)))) - -#define SCD_MODE_REG_BIT_SEARCH_MODE (1<<0) -#define SCD_MODE_REG_BIT_SBYP_MODE (1<<1) - -#define SCD_TXFIFO_POS_TID (0) -#define SCD_TXFIFO_POS_RA (4)#define SCD_QUEUE_STTS_REG_POS_ACTIVE (0)#define SCD_QUEUE_STTS_REG_POS_TXF (1)#define SCD_QUEUE_STTS_REG_POS_WSL (5)
@@ -1227,14 +849,9 @@ union iwl4965_tx_power_dual_stream {#define SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (10)#define SCD_QUEUE_STTS_REG_MSK (0x0007FC00) -#define SCD_QUEUE_RA_TID_MAP_RATID_MSK (0x01FF) -#define SCD_QUEUE_CTX_REG1_WIN_SIZE_POS (0)#define SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK (0x0000007F) -#define SCD_QUEUE_CTX_REG1_CREDIT_POS (8) -#define SCD_QUEUE_CTX_REG1_CREDIT_MSK (0x00FFFF00) -#define SCD_QUEUE_CTX_REG1_SUPER_CREDIT_POS (24) -#define SCD_QUEUE_CTX_REG1_SUPER_CREDIT_MSK (0xFF000000) +#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16)#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000)
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 18/34 iwlwifi: move uCode API definitions to iwl-4965-commands.h
From: Ben Cahill <[email protected]>
Move uCode API definitions to iwl-4965-commands.h
--- drivers/net/wireless/iwlwifi/iwl-4965-commands.h | 39 ++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 37 -------------------- 2 files changed, 39 insertions(+), 37 deletions(-)
drivers/net/wireless/iwlwifi/iwl-4965-commands.h +39 -0
@@ -335,6 +335,21 @@ enum { RXON_DEV_TYPE_SNIFFER = 6, }; + +#define RXON_RX_CHAIN_DRIVER_FORCE_MSK __constant_cpu_to_le16(0x1<<0) +#define RXON_RX_CHAIN_VALID_MSK __constant_cpu_to_le16(0x7<<1) +#define RXON_RX_CHAIN_VALID_POS (1) +#define RXON_RX_CHAIN_FORCE_SEL_MSK __constant_cpu_to_le16(0x7<<4) +#define RXON_RX_CHAIN_FORCE_SEL_POS (4) +#define RXON_RX_CHAIN_FORCE_MIMO_SEL_MSK __constant_cpu_to_le16(0x7<<7) +#define RXON_RX_CHAIN_FORCE_MIMO_SEL_POS (7) +#define RXON_RX_CHAIN_CNT_MSK __constant_cpu_to_le16(0x3<<10) +#define RXON_RX_CHAIN_CNT_POS (10) +#define RXON_RX_CHAIN_MIMO_CNT_MSK __constant_cpu_to_le16(0x3<<12) +#define RXON_RX_CHAIN_MIMO_CNT_POS (12) +#define RXON_RX_CHAIN_MIMO_FORCE_MSK __constant_cpu_to_le16(0x1<<14) +#define RXON_RX_CHAIN_MIMO_FORCE_POS (14) +/* rx_config flags */ /* band & modulation selection */ #define RXON_FLG_BAND_24G_MSK __constant_cpu_to_le32(1 << 0)
@@ -358,6 +373,21 @@ enum {* (according to ON_AIR deassertion) */ #define RXON_FLG_TSF2HOST_MSK __constant_cpu_to_le32(1 << 15) + +/* HT flags */ +#define RXON_FLG_CTRL_CHANNEL_LOC_POS (22) +#define RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK __constant_cpu_to_le32(0x1<<22) + +#define RXON_FLG_HT_OPERATING_MODE_POS (23) + +#define RXON_FLG_HT_PROT_MSK __constant_cpu_to_le32(0x1<<23) +#define RXON_FLG_FAT_PROT_MSK __constant_cpu_to_le32(0x2<<23) + +#define RXON_FLG_CHANNEL_MODE_POS (25) +#define RXON_FLG_CHANNEL_MODE_MSK __constant_cpu_to_le32(0x3<<25) +#define RXON_FLG_CHANNEL_MODE_PURE_40_MSK __constant_cpu_to_le32(0x1<<25) +#define RXON_FLG_CHANNEL_MODE_MIXED_MSK __constant_cpu_to_le32(0x2<<25) +/* rx_config filter flags */ /* accept all data frames */ #define RXON_FILTER_PROMISC_MSK __constant_cpu_to_le32(1 << 0)
@@ -431,6 +461,15 @@ struct iwl4965_tx_power {#define POWER_TABLE_NUM_ENTRIES 33#define POWER_TABLE_NUM_HT_OFDM_ENTRIES 32#define POWER_TABLE_CCK_ENTRY 32 + +union iwl4965_tx_power_dual_stream { +struct { +u8 radio_tx_gain[2 ]; +u8 dsp_predis_atten[2 ]; + } s; +u32 dw; +}; +struct tx_power_dual_stream {__le32 dw; } __attribute__ ((packed));
drivers/net/wireless/iwlwifi/iwl-4965-hw.h +0 -37
@@ -698,45 +698,8 @@ enum {#define CALIB_IWL_TX_ATTEN_GR5_FCH 1#define CALIB_IWL_TX_ATTEN_GR5_LCH 20 -union iwl4965_tx_power_dual_stream { -struct { -u8 radio_tx_gain[2 ]; -u8 dsp_predis_atten[2 ]; - } s; -u32 dw; -}; -/********************* END TXPOWER *****************************************/ -/* HT flags */ -#define RXON_FLG_CTRL_CHANNEL_LOC_POS (22) -#define RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK __constant_cpu_to_le32(0x1<<22) - -#define RXON_FLG_HT_OPERATING_MODE_POS (23) - -#define RXON_FLG_HT_PROT_MSK __constant_cpu_to_le32(0x1<<23) -#define RXON_FLG_FAT_PROT_MSK __constant_cpu_to_le32(0x2<<23) - -#define RXON_FLG_CHANNEL_MODE_POS (25) -#define RXON_FLG_CHANNEL_MODE_MSK __constant_cpu_to_le32(0x3<<25) -#define RXON_FLG_CHANNEL_MODE_PURE_40_MSK __constant_cpu_to_le32(0x1<<25) -#define RXON_FLG_CHANNEL_MODE_MIXED_MSK __constant_cpu_to_le32(0x2<<25) - -#define RXON_RX_CHAIN_DRIVER_FORCE_MSK __constant_cpu_to_le16(0x1<<0) -#define RXON_RX_CHAIN_VALID_MSK __constant_cpu_to_le16(0x7<<1) -#define RXON_RX_CHAIN_VALID_POS (1) -#define RXON_RX_CHAIN_FORCE_SEL_MSK __constant_cpu_to_le16(0x7<<4) -#define RXON_RX_CHAIN_FORCE_SEL_POS (4) -#define RXON_RX_CHAIN_FORCE_MIMO_SEL_MSK __constant_cpu_to_le16(0x7<<7) -#define RXON_RX_CHAIN_FORCE_MIMO_SEL_POS (7) -#define RXON_RX_CHAIN_CNT_MSK __constant_cpu_to_le16(0x3<<10) -#define RXON_RX_CHAIN_CNT_POS (10) -#define RXON_RX_CHAIN_MIMO_CNT_MSK __constant_cpu_to_le16(0x3<<12) -#define RXON_RX_CHAIN_MIMO_CNT_POS (12) -#define RXON_RX_CHAIN_MIMO_FORCE_MSK __constant_cpu_to_le16(0x1<<14) -#define RXON_RX_CHAIN_MIMO_FORCE_POS (14) - -/* Flow Handler Definitions */ /**********************/
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 19/34 iwlwifi: move HT_IE_EXT_CHANNEL_* driver definitions to iwl-4965.h
From: Ben Cahill <[email protected]>
Move HT_IE_EXT_CHANNEL_* driver definitions to iwl-4965.h
Add comments to guide .h file usage (hw/api/driver definitions)
Minor comment cleanup
--- drivers/net/wireless/iwlwifi/iwl-3945-commands.h | 5 +++ drivers/net/wireless/iwlwifi/iwl-3945-hw.h | 29 +++++++++---------- drivers/net/wireless/iwlwifi/iwl-3945.h | 6 +++- drivers/net/wireless/iwlwifi/iwl-4965-commands.h | 5 +++ drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 33 ++++++++++----------- drivers/net/wireless/iwlwifi/iwl-4965.h | 25 +++++++++++++--- 6 files changed, 65 insertions(+), 38 deletions(-)
drivers/net/wireless/iwlwifi/iwl-3945-commands.h +5 -0
@@ -60,6 +60,11 @@* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ +/* +* Please use this file (iwl-3945-commands.h) only for uCode API definitions. +* Please use iwl-3945-hw.h for hardware-related definitions. +* Please use iwl-3945.h for driver implementation definitions. +*/ #ifndef __iwl_3945_commands_h__#define __iwl_3945_commands_h__
drivers/net/wireless/iwlwifi/iwl-3945-hw.h +14 -15
@@ -60,6 +60,11 @@* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ +/* +* Please use this file (iwl-3945-hw.h) only for hardware-related definitions. +* Please use iwl-3945-commands.h for uCode API definitions. +* Please use iwl-3945.h for driver implementation definitions. +*/ #ifndef __iwl_3945_hw__#define __iwl_3945_hw__
@@ -73,9 +78,7 @@/* Tx rates */ #define IWL_CCK_RATES 4#define IWL_OFDM_RATES 8 -#define IWL_HT_RATES 0 -#define IWL_MAX_RATES (IWL_CCK_RATES+IWL_OFDM_RATES+IWL_HT_RATES)/* Time constants */
@@ -545,11 +548,6 @@ struct iwl3945_eeprom {#define FH_TSSR_CBB_BASE (FH_TSSR_TABLE+0x000)#define FH_TSSR_MSG_CONFIG (FH_TSSR_TABLE+0x008)#define FH_TSSR_TX_STATUS (FH_TSSR_TABLE+0x010) -/* 18 - reserved */ - -/* card static random access memory (SRAM) for processor data and instructs */ -#define RTC_INST_LOWER_BOUND (0x000000) -#define RTC_DATA_LOWER_BOUND (0x800000)/* DBM */
@@ -618,7 +616,6 @@ struct iwl3945_eeprom {#define TFD_QUEUE_MAX 6#define TFD_QUEUE_SIZE_MAX (256) -/* spectrum and channel data structures */ #define IWL_NUM_SCAN_RATES (2)#define IWL_DEFAULT_TX_RETRY 15
@@ -634,11 +631,6 @@ struct iwl3945_eeprom {#define U32_PAD (n) ((4-(n))&0x3) -/* -* Generic queue structure -* -* Contains common data for Rx and Tx queues -*/ #define TFD_CTL_COUNT_SET (n) (n<<24)#define TFD_CTL_COUNT_GET (ctl) ((ctl>>24) & 7)#define TFD_CTL_PAD_SET (n) (n<<28)
@@ -656,17 +648,24 @@ struct iwl3945_eeprom {#define RX_FREE_BUFFERS 64#define RX_LOW_WATERMARK 8 +/* Size of one Rx buffer in host DRAM */ +#define IWL_RX_BUF_SIZE 3000 -/* card static random access memory (SRAM) for processor data and instructs */ +#define RTC_DATA_LOWER_BOUND (0x800000)#define ALM_RTC_INST_UPPER_BOUND (0x014000)#define ALM_RTC_DATA_UPPER_BOUND (0x808000)#define ALM_RTC_INST_SIZE (ALM_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND)#define ALM_RTC_DATA_SIZE (ALM_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND) -#define IWL_MAX_BSM_SIZE ALM_RTC_INST_SIZE +/* Sizes and addresses for instruction and data memory (SRAM) in +* 3945's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */ +#define RTC_INST_LOWER_BOUND (0x000000)#define IWL_MAX_INST_SIZE ALM_RTC_INST_SIZE#define IWL_MAX_DATA_SIZE ALM_RTC_DATA_SIZE + +/* Size of uCode instruction memory in bootstrap state machine */ +#define IWL_MAX_BSM_SIZE ALM_RTC_INST_SIZE#define IWL_MAX_NUM_QUEUES 8static inline int iwl3945_hw_valid_rtc_data_addr (u32 addr)
drivers/net/wireless/iwlwifi/iwl-3945.h +5 -1
@@ -23,6 +23,11 @@* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 * *****************************************************************************/ +/* +* Please use this file (iwl-3945.h) for driver implementation definitions. +* Please use iwl-3945-commands.h for uCode API definitions. +* Please use iwl-3945-hw.h for hardware-related definitions. +*/ #ifndef __iwl_3945_h__#define __iwl_3945_h__
@@ -72,7 +77,6 @@ enum iwl3945_antenna {* else RTS for data/management frames where MPDU is larger * than RTS value. */ -#define IWL_RX_BUF_SIZE 3000U#define DEFAULT_RTS_THRESHOLD 2347U#define MIN_RTS_THRESHOLD 0U#define MAX_RTS_THRESHOLD 2347U
drivers/net/wireless/iwlwifi/iwl-4965-commands.h +5 -0
@@ -60,6 +60,11 @@* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ +/* +* Please use this file (iwl-4965-commands.h) only for uCode API definitions. +* Please use iwl-4965-hw.h for hardware-related definitions. +* Please use iwl-4965.h for driver implementation definitions. +*/ #ifndef __iwl4965_commands_h__#define __iwl4965_commands_h__
drivers/net/wireless/iwlwifi/iwl-4965-hw.h +16 -17
@@ -60,6 +60,11 @@* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ +/* +* Please use this file (iwl-4965-hw.h) only for hardware-related definitions. +* Use iwl-4965-commands.h for uCode API definitions. +* Use iwl-4965.h for driver implementation definitions. +*/ #ifndef __iwl_4965_hw_h__#define __iwl_4965_hw_h__
@@ -77,9 +82,7 @@/* Tx rates */ #define IWL_CCK_RATES 4#define IWL_OFDM_RATES 8 -#define IWL_HT_RATES 16 -#define IWL_MAX_RATES (IWL_CCK_RATES+IWL_OFDM_RATES+IWL_HT_RATES)/* Time constants */
@@ -449,8 +452,6 @@ struct iwl4965_eeprom {*/ #define CSR_HW_REV_WA_REG (CSR_BASE+0x22C) -#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000) -/* interrupt flags in INTA, set by uCode or hardware (e.g. dma), * acknowledged (reset) by host writing "1" to flagged bits. */ #define CSR_INT_BIT_FH_RX (1<<31)/* Rx DMA, cmd responses, FH_INT[17:16] */
@@ -592,17 +593,12 @@ struct iwl4965_eeprom {#define FH_TSSR_CBB_BASE (FH_TSSR_TABLE+0x000)#define FH_TSSR_MSG_CONFIG (FH_TSSR_TABLE+0x008)#define FH_TSSR_TX_STATUS (FH_TSSR_TABLE+0x010) -/* 18 - reserved */ -/* card static random access memory (SRAM) for processor data and instructs */ -#define RTC_INST_LOWER_BOUND (0x000000) -#define RTC_DATA_LOWER_BOUND (0x800000)#define HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED (0x00000004)#define TFD_QUEUE_SIZE_MAX (256) -/* spectrum and channel data structures */ #define IWL_NUM_SCAN_RATES (2)#define IWL_DEFAULT_TX_RETRY 15
@@ -623,10 +619,16 @@ struct iwl4965_eeprom {#define RX_FREE_BUFFERS 64#define RX_LOW_WATERMARK 8 +/* Size of one Rx buffer in host DRAM */ #define IWL_RX_BUF_SIZE_4K (4 * 1024)#define IWL_RX_BUF_SIZE_8K (8 * 1024) -#define IWL_MAX_BSM_SIZE BSM_SRAM_SIZE + +/* Sizes and addresses for instruction and data memory (SRAM) in +* 4965's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */ +#define RTC_INST_LOWER_BOUND (0x000000)#define KDR_RTC_INST_UPPER_BOUND (0x018000) + +#define RTC_DATA_LOWER_BOUND (0x800000)#define KDR_RTC_DATA_UPPER_BOUND (0x80A000)#define KDR_RTC_INST_SIZE (KDR_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND)#define KDR_RTC_DATA_SIZE (KDR_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND)
@@ -634,6 +636,9 @@ struct iwl4965_eeprom {#define IWL_MAX_INST_SIZE KDR_RTC_INST_SIZE#define IWL_MAX_DATA_SIZE KDR_RTC_DATA_SIZE +/* Size of uCode instruction memory in bootstrap state machine */ +#define IWL_MAX_BSM_SIZE BSM_SRAM_SIZE +static inline int iwl4965_hw_valid_rtc_data_addr (u32 addr) { return (addr >= RTC_DATA_LOWER_BOUND) &&
@@ -641,13 +646,6 @@ static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr) }/********************* START TXPOWER *****************************************/ -enum { -HT_IE_EXT_CHANNEL_NONE =0 , -HT_IE_EXT_CHANNEL_ABOVE , -HT_IE_EXT_CHANNEL_INVALID , -HT_IE_EXT_CHANNEL_BELOW , -HT_IE_EXT_CHANNEL_MAX -};enum {CALIB_CH_GROUP_1 =0 ,
@@ -822,6 +820,7 @@ enum {#define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x00000C00)#define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100)#define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200) +#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000)static inline u8 iwl4965_hw_get_rate (__le32 rate_n_flags) {
drivers/net/wireless/iwlwifi/iwl-4965.h +20 -5
@@ -23,6 +23,12 @@* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 * *****************************************************************************/ +/* +* Please use this file (iwl-4965.h) for driver implementation definitions. +* Please use iwl-4965-commands.h for uCode API definitions. +* Please use iwl-4965-hw.h for hardware-related definitions. +*/ +#ifndef __iwl_4965_h__#define __iwl_4965_h__
@@ -193,6 +199,15 @@ struct iwl4965_scan_power_info {s8 requested_power;/* scan pwr (dBm) requested for chnl/rate */ }; +/* For fat_extension_channel */ +enum { +HT_IE_EXT_CHANNEL_NONE =0 , +HT_IE_EXT_CHANNEL_ABOVE , +HT_IE_EXT_CHANNEL_INVALID , +HT_IE_EXT_CHANNEL_BELOW , +HT_IE_EXT_CHANNEL_MAX +}; +/* * One for each channel, holds all channel setup data * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant
@@ -203,14 +218,14 @@ struct iwl4965_scan_power_info {struct iwl4965_channel_info {struct iwl4965_channel_tgd_info tgd;struct iwl4965_channel_tgh_info tgh; -struct iwl4965_eeprom_channel eeprom;/* EEPROM regulatory limit */ -struct iwl4965_eeprom_channel fat_eeprom;/* EEPROM regulatory limit for -* FAT channel */ +struct iwl4965_eeprom_channel eeprom;/* EEPROM regulatory limit */ +struct iwl4965_eeprom_channel fat_eeprom;/* EEPROM regulatory limit for +* FAT channel */ u8 channel;/* channel number */ u8 flags;/* flags copied from EEPROM */ s8 max_power_avg;/* (dBm) regul. eeprom, normal Tx, any rate */ -s8 curr_txpow;/* (dBm) regulatory/spectrum/user (not h/w) */ +s8 curr_txpow;/* (dBm) regulatory/spectrum/user (not h/w) limit */ s8 min_power;/* always 0 */ s8 scan_power;/* (dBm) regul. eeprom, direct scans, any rate */
@@ -229,7 +244,7 @@ struct iwl4965_channel_info {s8 fat_min_power;/* always 0 */ s8 fat_scan_power;/* (dBm) eeprom, direct scans, any rate */ u8 fat_flags;/* flags copied from EEPROM */ -u8 fat_extension_channel; +u8 fat_extension_channel;/* HT_IE_EXT_CHANNEL_* */ /* Radio/DSP gain settings for each scan rate, for directed scans. */ struct iwl4965_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES ];
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 20/34 iwlwifi: document temperature calculation
From: Ben Cahill <[email protected]>
Document temperature calculation
--- drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 57 ++++++++++++++++++++++----- 1 files changed, 46 insertions(+), 11 deletions(-)
drivers/net/wireless/iwlwifi/iwl-4965-hw.h +46 -11
@@ -645,21 +645,43 @@ static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr) (addr <KDR_RTC_DATA_UPPER_BOUND ); } -/********************* START TXPOWER *****************************************/ - -enum { -CALIB_CH_GROUP_1 =0 , -CALIB_CH_GROUP_2 =1 , -CALIB_CH_GROUP_3 =2 , -CALIB_CH_GROUP_4 =3 , -CALIB_CH_GROUP_5 =4 , -CALIB_CH_GROUP_MAX -}; +/********************* START TEMPERATURE *************************************/ -/* Temperature calibration offset is 3% 0C in Kelvin */ +/* +* 4965 temperature calculation. +* +* The driver must calculate the device temperature before calculating +* a txpower setting (amplifier gain is temperature dependent). The +* calculation uses 4 measurements, 3 of which (R1, R2, R3) are calibration +* values used for the life of the driver, and one of which (R4) is the +* real-time temperature indicator. +* +* uCode provides all 4 values to the driver via the "initialize alive" +* notification (see struct iwl4965_init_alive_resp). After the runtime uCode +* image loads, uCode updates the R4 value via statistics notifications +* (see STATISTICS_NOTIFICATION), which occur after each received beacon +* when associated, or can be requested via REPLY_STATISTICS_CMD. +* +* NOTE: uCode provides the R4 value as a 23-bit signed value. Driver +* must sign-extend to 32 bits before applying formula below. +* +* Formula: +* +* degrees Kelvin = ((97 * 259 * (R4 - R2) / (R3 - R1)) / 100) + 8 +* +* NOTE: The basic formula is 259 * (R4-R2) / (R3-R1). The 97/100 is +* an additional correction, which should be centered around 0 degrees +* Celsius (273 degrees Kelvin). The 8 (3 percent of 273) compensates for +* centering the 97/100 correction around 0 degrees K. +* +* Add 273 to Kelvin value to find degrees Celsius, for comparing current +* temperature with factory-measured temperatures when calculating txpower +* settings. +*/ #define TEMPERATURE_CALIB_KELVIN_OFFSET 8#define TEMPERATURE_CALIB_A_VAL 259 +/* Limit range of calculated temperature to be between these Kelvin values */ #define IWL_TX_POWER_TEMPERATURE_MIN (263)#define IWL_TX_POWER_TEMPERATURE_MAX (410)
@@ -667,6 +689,19 @@ enum { (((t) <IWL_TX_POWER_TEMPERATURE_MIN ) || \ ((t) >IWL_TX_POWER_TEMPERATURE_MAX )) +/********************* END TEMPERATURE ***************************************/ + +/********************* START TXPOWER *****************************************/ + +enum { +CALIB_CH_GROUP_1 =0 , +CALIB_CH_GROUP_2 =1 , +CALIB_CH_GROUP_3 =2 , +CALIB_CH_GROUP_4 =3 , +CALIB_CH_GROUP_5 =4 , +CALIB_CH_GROUP_MAX +}; +#define IWL_TX_POWER_MIMO_REGULATORY_COMPENSATION (6)#define IWL_TX_POWER_TARGET_POWER_MIN (0)/* 0 dBm = 1 milliwatt */
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 21/34 iwlwifi: document txpower calculations
From: Ben Cahill <[email protected]>
Document txpower calculations
--- drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 575 +++++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-4965.h | 3 - 2 files changed, 562 insertions(+), 16 deletions(-)
drivers/net/wireless/iwlwifi/iwl-4965-hw.h +562 -13
@@ -647,7 +647,7 @@ static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr)/********************* START TEMPERATURE *************************************/ -/* +/** * 4965 temperature calculation. * * The driver must calculate the device temperature before calculating
@@ -693,44 +693,593 @@ static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr)/********************* START TXPOWER *****************************************/ -enum { -CALIB_CH_GROUP_1 =0 , -CALIB_CH_GROUP_2 =1 , -CALIB_CH_GROUP_3 =2 , -CALIB_CH_GROUP_4 =3 , -CALIB_CH_GROUP_5 =4 , -CALIB_CH_GROUP_MAX -}; +/** +* 4965 txpower calculations rely on information from three sources: +* +* 1) EEPROM +* 2) "initialize" alive notification +* 3) statistics notifications +* +* EEPROM data consists of: +* +* 1) Regulatory information (max txpower and channel usage flags) is provided +* separately for each channel that can possibly supported by 4965. +* 40 MHz wide (.11n fat) channels are listed separately from 20 MHz +* (legacy) channels. +* +* See struct iwl4965_eeprom_channel for format, and struct iwl4965_eeprom +* for locations in EEPROM. +* +* 2) Factory txpower calibration information is provided separately for +* sub-bands of contiguous channels. 2.4GHz has just one sub-band, +* but 5 GHz has several sub-bands. +* +* In addition, per-band (2.4 and 5 Ghz) saturation txpowers are provided. +* +* See struct iwl4965_eeprom_calib_info (and the tree of structures +* contained within it) for format, and struct iwl4965_eeprom for +* locations in EEPROM. +* +* "Initialization alive" notification (see struct iwl4965_init_alive_resp) +* consists of: +* +* 1) Temperature calculation parameters. +* +* 2) Power supply voltage measurement. +* +* 3) Tx gain compensation to balance 2 transmitters for MIMO use. +* +* Statistics notifications deliver: +* +* 1) Current values for temperature param R4. +*/ -#define IWL_TX_POWER_MIMO_REGULATORY_COMPENSATION (6) +/** +* To calculate a txpower setting for a given desired target txpower, channel, +* modulation bit rate, and transmitter chain (4965 has 2 transmitters to +* support MIMO and transmit diversity), driver must do the following: +* +* 1) Compare desired txpower vs. (EEPROM) regulatory limit for this channel. +* Do not exceed regulatory limit; reduce target txpower if necessary. +* +* If setting up txpowers for MIMO rates (rate indexes 8-15, 24-31), +* 2 transmitters will be used simultaneously; driver must reduce the +* regulatory limit by 3 dB (half-power) for each transmitter, so the +* combined total output of the 2 transmitters is within regulatory limits. +* +* +* 2) Compare target txpower vs. (EEPROM) saturation txpower *reduced by +* backoff for this bit rate*. Do not exceed (saturation - backoff[rate]); +* reduce target txpower if necessary. +* +* Backoff values below are in 1/2 dB units (equivalent to steps in +* txpower gain tables): +* +* OFDM 6 - 36 MBit: 10 steps (5 dB) +* OFDM 48 MBit: 15 steps (7.5 dB) +* OFDM 54 MBit: 17 steps (8.5 dB) +* OFDM 60 MBit: 20 steps (10 dB) +* CCK all rates: 10 steps (5 dB) +* +* Backoff values apply to saturation txpower on a per-transmitter basis; +* when using MIMO (2 transmitters), each transmitter uses the same +* saturation level provided in EEPROM, and the same backoff values; +* no reduction (such as with regulatory txpower limits) is required. +* +* Saturation and Backoff values apply equally to 20 Mhz (legacy) channel +* widths and 40 Mhz (.11n fat) channel widths; there is no separate +* factory measurement for fat channels. +* +* The result of this step is the final target txpower. The rest of +* the steps figure out the proper settings for the device to achieve +* that target txpower. +* +* +* 3) Determine (EEPROM) calibration subband for the target channel, by +* comparing against first and last channels in each subband +* (see struct iwl4965_eeprom_calib_subband_info). +* +* +* 4) Linearly interpolate (EEPROM) factory calibration measurement sets, +* referencing the 2 factory-measured (sample) channels within the subband. +* +* Interpolation is based on difference between target channel's frequency +* and the sample channels' frequencies. Since channel numbers are based +* on frequency (5 MHz between each channel number), this is equivalent +* to interpolating based on channel number differences. +* +* Note that the sample channels may or may not be the channels at the +* edges of the subband. The target channel may be "outside" of the +* span of the sampled channels. +* +* Driver may choose the pair (for 2 Tx chains) of measurements (see +* struct iwl4965_eeprom_calib_ch_info) for which the actual measured +* txpower comes closest to the desired txpower. Usually, though, +* the middle set of measurements is closest to the regulatory limits, +* and is therefore a good choice for all txpower calculations (this +* assumes that high accuracy is needed for maximizing legal txpower, +* while lower txpower configurations do not need as much accuracy). +* +* Driver should interpolate both members of the chosen measurement pair, +* i.e. for both Tx chains (radio transmitters), unless the driver knows +* that only one of the chains will be used (e.g. only one tx antenna +* connected, but this should be unusual). The rate scaling algorithm +* switches antennas to find best performance, so both Tx chains will +* be used (although only one at a time) even for non-MIMO transmissions. +* +* Driver should interpolate factory values for temperature, gain table +* index, and actual power. The power amplifier detector values are +* not used by the driver. +* +* Sanity check: If the target channel happens to be one of the sample +* channels, the results should agree with the sample channel's +* measurements! +* +* +* 5) Find difference between desired txpower and (interpolated) +* factory-measured txpower. Using (interpolated) factory gain table index +* (shown elsewhere) as a starting point, adjust this index lower to +* increase txpower, or higher to decrease txpower, until the target +* txpower is reached. Each step in the gain table is 1/2 dB. +* +* For example, if factory measured txpower is 16 dBm, and target txpower +* is 13 dBm, add 6 steps to the factory gain index to reduce txpower +* by 3 dB. +* +* +* 6) Find difference between current device temperature and (interpolated) +* factory-measured temperature for sub-band. Factory values are in +* degrees Celsius. To calculate current temperature, see comments for +* "4965 temperature calculation". +* +* If current temperature is higher than factory temperature, driver must +* increase gain (lower gain table index), and vice versa. +* +* Temperature affects gain differently for different channels: +* +* 2.4 GHz all channels: 3.5 degrees per half-dB step +* 5 GHz channels 34-43: 4.5 degrees per half-dB step +* 5 GHz channels >= 44: 4.0 degrees per half-dB step +* +* NOTE: Temperature can increase rapidly when transmitting, especially +* with heavy traffic at high txpowers. Driver should update +* temperature calculations often under these conditions to +* maintain strong txpower in the face of rising temperature. +* +* +* 7) Find difference between current power supply voltage indicator +* (from "initialize alive") and factory-measured power supply voltage +* indicator (EEPROM). +* +* If the current voltage is higher (indicator is lower) than factory +* voltage, gain should be reduced (gain table index increased) by: +* +* (eeprom - current) / 7 +* +* If the current voltage is lower (indicator is higher) than factory +* voltage, gain should be increased (gain table index decreased) by: +* +* 2 * (current - eeprom) / 7 +* +* If number of index steps in either direction turns out to be > 2, +* something is wrong ... just use 0. +* +* NOTE: Voltage compensation is independent of band/channel. +* +* NOTE: "Initialize" uCode measures current voltage, which is assumed +* to be constant after this initial measurement. Voltage +* compensation for txpower (number of steps in gain table) +* may be calculated once and used until the next uCode bootload. +* +* +* 8) If setting up txpowers for MIMO rates (rate indexes 8-15, 24-31), +* adjust txpower for each transmitter chain, so txpower is balanced +* between the two chains. There are 5 pairs of tx_atten[group][chain] +* values in "initialize alive", one pair for each of 5 channel ranges: +* +* Group 0: 5 GHz channel 34-43 +* Group 1: 5 GHz channel 44-70 +* Group 2: 5 GHz channel 71-124 +* Group 3: 5 GHz channel 125-200 +* Group 4: 2.4 GHz all channels +* +* Add the tx_atten[group][chain] value to the index for the target chain. +* The values are signed, but are in pairs of 0 and a non-negative number, +* so as to reduce gain (if necessary) of the "hotter" channel. This +* avoids any need to double-check for regulatory compliance after +* this step. +* +* +* 9) If setting up for a CCK rate, lower the gain by adding a CCK compensation +* value to the index: +* +* Hardware rev B: 9 steps (4.5 dB) +* Hardware rev C: 5 steps (2.5 dB) +* +* Hardware rev for 4965 can be determined by reading CSR_HW_REV_WA_REG, +* bits [3:2], 1 = B, 2 = C. +* +* NOTE: This compensation is in addition to any saturation backoff that +* might have been applied in an earlier step. +* +* +* 10) Select the gain table, based on band (2.4 vs 5 GHz). +* +* Limit the adjusted index to stay within the table! +* +* +* 11) Read gain table entries for DSP and radio gain, place into appropriate +* location(s) in command (struct iwl4965_txpowertable_cmd). +*/ +/* Limit range of txpower output target to be between these values */ #define IWL_TX_POWER_TARGET_POWER_MIN (0)/* 0 dBm = 1 milliwatt */ #define IWL_TX_POWER_TARGET_POWER_MAX (16)/* 16 dBm */ -#define MIN_TX_GAIN_INDEX (0) -#define MIN_TX_GAIN_INDEX_52GHZ_EXT (-9) +/** +* When MIMO is used (2 transmitters operating simultaneously), driver should +* limit each transmitter to deliver a max of 3 dB below the regulatory limit +* for the device. That is, use half power for each transmitter, so total +* txpower is within regulatory limits. +* +* The value "6" represents number of steps in gain table to reduce power 3 dB. +* Each step is 1/2 dB. +*/ +#define IWL_TX_POWER_MIMO_REGULATORY_COMPENSATION (6) + +/** +* CCK gain compensation. +* +* When calculating txpowers for CCK, after making sure that the target power +* is within regulatory and saturation limits, driver must additionally +* back off gain by adding these values to the gain table index. +* +* Hardware rev for 4965 can be determined by reading CSR_HW_REV_WA_REG, +* bits [3:2], 1 = B, 2 = C. +*/ +#define IWL_TX_POWER_CCK_COMPENSATION_B_STEP (9) +#define IWL_TX_POWER_CCK_COMPENSATION_C_STEP (5) + +/* +* 4965 power supply voltage compensation for txpower +*/ +#define TX_POWER_IWL_VOLTAGE_CODES_PER_03V (7) + +/** +* Gain tables. +* +* The following tables contain pair of values for setting txpower, i.e. +* gain settings for the output of the device's digital signal processor (DSP), +* and for the analog gain structure of the transmitter. +* +* Each entry in the gain tables represents a step of 1/2 dB. Note that these +* are *relative* steps, not indications of absolute output power. Output +* power varies with temperature, voltage, and channel frequency, and also +* requires consideration of average power (to satisfy regulatory constraints), +* and peak power (to avoid distortion of the output signal). +* +* Each entry contains two values: +* 1) DSP gain (or sometimes called DSP attenuation). This is a fine-grained +* linear value that multiplies the output of the digital signal processor, +* before being sent to the analog radio. +* 2) Radio gain. This sets the analog gain of the radio Tx path. +* It is a coarser setting, and behaves in a logarithmic (dB) fashion. +* +* EEPROM contains factory calibration data for txpower. This maps actual +* measured txpower levels to gain settings in the "well known" tables +* below ("well-known" means here that both factory calibration *and* the +* driver work with the same table). +* +* There are separate tables for 2.4 GHz and 5 GHz bands. The 5 GHz table +* has an extension (into negative indexes), in case the driver needs to +* boost power setting for high device temperatures (higher than would be +* present during factory calibration). A 5 Ghz EEPROM index of "40" +* corresponds to the 49th entry in the table used by the driver. +*/ +#define MIN_TX_GAIN_INDEX (0)/* highest gain, lowest idx, 2.4 */ +#define MIN_TX_GAIN_INDEX_52GHZ_EXT (-9)/* highest gain, lowest idx, 5 */ + +/** +* 2.4 GHz gain table +* +* Index Dsp gain Radio gain +* 0 110 0x3f (highest gain) +* 1 104 0x3f +* 2 98 0x3f +* 3 110 0x3e +* 4 104 0x3e +* 5 98 0x3e +* 6 110 0x3d +* 7 104 0x3d +* 8 98 0x3d +* 9 110 0x3c +* 10 104 0x3c +* 11 98 0x3c +* 12 110 0x3b +* 13 104 0x3b +* 14 98 0x3b +* 15 110 0x3a +* 16 104 0x3a +* 17 98 0x3a +* 18 110 0x39 +* 19 104 0x39 +* 20 98 0x39 +* 21 110 0x38 +* 22 104 0x38 +* 23 98 0x38 +* 24 110 0x37 +* 25 104 0x37 +* 26 98 0x37 +* 27 110 0x36 +* 28 104 0x36 +* 29 98 0x36 +* 30 110 0x35 +* 31 104 0x35 +* 32 98 0x35 +* 33 110 0x34 +* 34 104 0x34 +* 35 98 0x34 +* 36 110 0x33 +* 37 104 0x33 +* 38 98 0x33 +* 39 110 0x32 +* 40 104 0x32 +* 41 98 0x32 +* 42 110 0x31 +* 43 104 0x31 +* 44 98 0x31 +* 45 110 0x30 +* 46 104 0x30 +* 47 98 0x30 +* 48 110 0x6 +* 49 104 0x6 +* 50 98 0x6 +* 51 110 0x5 +* 52 104 0x5 +* 53 98 0x5 +* 54 110 0x4 +* 55 104 0x4 +* 56 98 0x4 +* 57 110 0x3 +* 58 104 0x3 +* 59 98 0x3 +* 60 110 0x2 +* 61 104 0x2 +* 62 98 0x2 +* 63 110 0x1 +* 64 104 0x1 +* 65 98 0x1 +* 66 110 0x0 +* 67 104 0x0 +* 68 98 0x0 +* 69 97 0 +* 70 96 0 +* 71 95 0 +* 72 94 0 +* 73 93 0 +* 74 92 0 +* 75 91 0 +* 76 90 0 +* 77 89 0 +* 78 88 0 +* 79 87 0 +* 80 86 0 +* 81 85 0 +* 82 84 0 +* 83 83 0 +* 84 82 0 +* 85 81 0 +* 86 80 0 +* 87 79 0 +* 88 78 0 +* 89 77 0 +* 90 76 0 +* 91 75 0 +* 92 74 0 +* 93 73 0 +* 94 72 0 +* 95 71 0 +* 96 70 0 +* 97 69 0 +* 98 68 0 +*/ + +/** +* 5 GHz gain table +* +* Index Dsp gain Radio gain +* -9 123 0x3F (highest gain) +* -8 117 0x3F +* -7 110 0x3F +* -6 104 0x3F +* -5 98 0x3F +* -4 110 0x3E +* -3 104 0x3E +* -2 98 0x3E +* -1 110 0x3D +* 0 104 0x3D +* 1 98 0x3D +* 2 110 0x3C +* 3 104 0x3C +* 4 98 0x3C +* 5 110 0x3B +* 6 104 0x3B +* 7 98 0x3B +* 8 110 0x3A +* 9 104 0x3A +* 10 98 0x3A +* 11 110 0x39 +* 12 104 0x39 +* 13 98 0x39 +* 14 110 0x38 +* 15 104 0x38 +* 16 98 0x38 +* 17 110 0x37 +* 18 104 0x37 +* 19 98 0x37 +* 20 110 0x36 +* 21 104 0x36 +* 22 98 0x36 +* 23 110 0x35 +* 24 104 0x35 +* 25 98 0x35 +* 26 110 0x34 +* 27 104 0x34 +* 28 98 0x34 +* 29 110 0x33 +* 30 104 0x33 +* 31 98 0x33 +* 32 110 0x32 +* 33 104 0x32 +* 34 98 0x32 +* 35 110 0x31 +* 36 104 0x31 +* 37 98 0x31 +* 38 110 0x30 +* 39 104 0x30 +* 40 98 0x30 +* 41 110 0x25 +* 42 104 0x25 +* 43 98 0x25 +* 44 110 0x24 +* 45 104 0x24 +* 46 98 0x24 +* 47 110 0x23 +* 48 104 0x23 +* 49 98 0x23 +* 50 110 0x22 +* 51 104 0x18 +* 52 98 0x18 +* 53 110 0x17 +* 54 104 0x17 +* 55 98 0x17 +* 56 110 0x16 +* 57 104 0x16 +* 58 98 0x16 +* 59 110 0x15 +* 60 104 0x15 +* 61 98 0x15 +* 62 110 0x14 +* 63 104 0x14 +* 64 98 0x14 +* 65 110 0x13 +* 66 104 0x13 +* 67 98 0x13 +* 68 110 0x12 +* 69 104 0x08 +* 70 98 0x08 +* 71 110 0x07 +* 72 104 0x07 +* 73 98 0x07 +* 74 110 0x06 +* 75 104 0x06 +* 76 98 0x06 +* 77 110 0x05 +* 78 104 0x05 +* 79 98 0x05 +* 80 110 0x04 +* 81 104 0x04 +* 82 98 0x04 +* 83 110 0x03 +* 84 104 0x03 +* 85 98 0x03 +* 86 110 0x02 +* 87 104 0x02 +* 88 98 0x02 +* 89 110 0x01 +* 90 104 0x01 +* 91 98 0x01 +* 92 110 0x00 +* 93 104 0x00 +* 94 98 0x00 +* 95 93 0x00 +* 96 88 0x00 +* 97 83 0x00 +* 98 78 0x00 +*/ + +/** +* Sanity checks and default values for EEPROM regulatory levels. +* If EEPROM values fall outside MIN/MAX range, use default values. +* +* Regulatory limits refer to the maximum average txpower allowed by +* regulatory agencies in the geographies in which the device is meant +* to be operated. These limits are SKU-specific (i.e. geography-specific), +* and channel-specific; each channel has an individual regulatory limit +* listed in the EEPROM. +* +* Units are in half-dBm (i.e. "34" means 17 dBm). +*/ #define IWL_TX_POWER_DEFAULT_REGULATORY_24 (34)#define IWL_TX_POWER_DEFAULT_REGULATORY_52 (34)#define IWL_TX_POWER_REGULATORY_MIN (0)#define IWL_TX_POWER_REGULATORY_MAX (34) + +/** +* Sanity checks and default values for EEPROM saturation levels. +* If EEPROM values fall outside MIN/MAX range, use default values. +* +* Saturation is the highest level that the output power amplifier can produce +* without significant clipping distortion. This is a "peak" power level. +* Different types of modulation (i.e. various "rates", and OFDM vs. CCK) +* require differing amounts of backoff, relative to their average power output, +* in order to avoid clipping distortion. +* +* Driver must make sure that it is violating neither the saturation limit, +* nor the regulatory limit, when calculating Tx power settings for various +* rates. +* +* Units are in half-dBm (i.e. "38" means 19 dBm). +*/ #define IWL_TX_POWER_DEFAULT_SATURATION_24 (38)#define IWL_TX_POWER_DEFAULT_SATURATION_52 (38)#define IWL_TX_POWER_SATURATION_MIN (20)#define IWL_TX_POWER_SATURATION_MAX (50) -/* First and last channels of all groups */ +/** +* Channel groups used for Tx Attenuation calibration (MIMO tx channel balance) +* and thermal Txpower calibration. +* +* When calculating txpower, driver must compensate for current device +* temperature; higher temperature requires higher gain. Driver must calculate +* current temperature (see "4965 temperature calculation"), then compare vs. +* factory calibration temperature in EEPROM; if current temperature is higher +* than factory temperature, driver must *increase* gain by proportions shown +* in table below. If current temperature is lower than factory, driver must +* *decrease* gain. +* +* Different frequency ranges require different compensation, as shown below. +*/ +/* Group 0, 5.2 GHz ch 34-43: 4.5 degrees per 1/2 dB. */ #define CALIB_IWL_TX_ATTEN_GR1_FCH 34#define CALIB_IWL_TX_ATTEN_GR1_LCH 43 + +/* Group 1, 5.3 GHz ch 44-70: 4.0 degrees per 1/2 dB. */ #define CALIB_IWL_TX_ATTEN_GR2_FCH 44#define CALIB_IWL_TX_ATTEN_GR2_LCH 70 + +/* Group 2, 5.5 GHz ch 71-124: 4.0 degrees per 1/2 dB. */ #define CALIB_IWL_TX_ATTEN_GR3_FCH 71#define CALIB_IWL_TX_ATTEN_GR3_LCH 124 + +/* Group 3, 5.7 GHz ch 125-200: 4.0 degrees per 1/2 dB. */ #define CALIB_IWL_TX_ATTEN_GR4_FCH 125#define CALIB_IWL_TX_ATTEN_GR4_LCH 200 + +/* Group 4, 2.4 GHz all channels: 3.5 degrees per 1/2 dB. */ #define CALIB_IWL_TX_ATTEN_GR5_FCH 1#define CALIB_IWL_TX_ATTEN_GR5_LCH 20 +enum { +CALIB_CH_GROUP_1 =0 , +CALIB_CH_GROUP_2 =1 , +CALIB_CH_GROUP_3 =2 , +CALIB_CH_GROUP_4 =3 , +CALIB_CH_GROUP_5 =4 , +CALIB_CH_GROUP_MAX +}; +/********************* END TXPOWER *****************************************/ /* Flow Handler Definitions */
drivers/net/wireless/iwlwifi/iwl-4965.h +0 -3
@@ -861,9 +861,6 @@ struct iwl4965_kw {#define NUM_RX_CHAINS (3)#define TX_POWER_IWL_ILLEGAL_VOLTAGE -10000 -#define TX_POWER_IWL_VOLTAGE_CODES_PER_03V 7 -#define IWL_TX_POWER_CCK_COMPENSATION_B_STEP (9) -#define IWL_TX_POWER_CCK_COMPENSATION_C_STEP (5)struct iwl4965_traffic_load {unsigned long time_stamp;
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 22/34 iwlwifi: document keep-warm buffer
From: Ben Cahill <[email protected]>
Document keep-warm buffer
Consolidate flow handler address definitions
--- drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 39 ++++++++++++++++++++-------- 1 files changed, 28 insertions(+), 11 deletions(-)
drivers/net/wireless/iwlwifi/iwl-4965-hw.h +28 -11
@@ -1282,20 +1282,37 @@ enum {/********************* END TXPOWER *****************************************/ +/****************************/ /* Flow Handler Definitions */ +/****************************/ -/**********************/ -/* Addresses */ -/**********************/ - +/* +* This I/O area is directly read/writable by driver (e.g. Linux uses writel()) +* Addresses are offsets from device's PCI hardware base address. +*/ #define FH_MEM_LOWER_BOUND (0x1000)#define FH_MEM_UPPER_BOUND (0x1EF0) -#define IWL_FH_REGS_LOWER_BOUND (0x1000) -#define IWL_FH_REGS_UPPER_BOUND (0x2000) - +/** +* Keep-Warm (KW) buffer base address. +* +* Driver must allocate a 4KByte buffer that is used by 4965 for keeping the +* host DRAM powered on (via dummy accesses to DRAM) to maintain low-latency +* DRAM access when 4965 is Txing or Rxing. The dummy accesses prevent host +* from going into a power-savings mode that would cause higher DRAM latency, +* and possible data over/under-runs, before all Tx/Rx is complete. +* +* Driver loads IWL_FH_KW_MEM_ADDR_REG with the physical address (bits 35:4) +* of the buffer, which must be 4K aligned. Once this is set up, the 4965 +* automatically invokes keep-warm accesses when normal accesses might not +* be sufficient to maintain fast DRAM response. +* +* Bit fields: +* 31-0: Keep-warm buffer physical base address [35:4], must be 4K aligned +*/ #define IWL_FH_KW_MEM_ADDR_REG (FH_MEM_LOWER_BOUND + 0x97C) +/* CBBC Area - Circular buffers base address cache pointers table */ #define FH_MEM_CBBC_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0x9D0)#define FH_MEM_CBBC_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xA10)
@@ -1326,16 +1343,16 @@ enum {#define FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV (FH_MEM_RSSR_LOWER_BOUND + 0x008)/* TCSR */ -#define IWL_FH_TCSR_LOWER_BOUND (IWL_FH_REGS_LOWER_BOUND + 0xD00) -#define IWL_FH_TCSR_UPPER_BOUND (IWL_FH_REGS_LOWER_BOUND + 0xE60) +#define IWL_FH_TCSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xD00) +#define IWL_FH_TCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xE60)#define IWL_FH_TCSR_CHNL_TX_CONFIG_REG (_chnl) \ (IWL_FH_TCSR_LOWER_BOUND + 0x20 * _chnl)/* TSSR Area - Tx shared status registers */ /* TSSR */ -#define IWL_FH_TSSR_LOWER_BOUND (IWL_FH_REGS_LOWER_BOUND + 0xEA0) -#define IWL_FH_TSSR_UPPER_BOUND (IWL_FH_REGS_LOWER_BOUND + 0xEC0) +#define IWL_FH_TSSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xEA0) +#define IWL_FH_TSSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xEC0)#define IWL_FH_TSSR_TX_STATUS_REG (IWL_FH_TSSR_LOWER_BOUND + 0x010)
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 23/34 iwlwifi: document Rx registers
From: Ben Cahill <[email protected]>
Document Rx registers
Document Tx circular buffer base registers
--- drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 170 +++++++++++++++++++++++++++- 1 files changed, 164 insertions(+), 6 deletions(-)
drivers/net/wireless/iwlwifi/iwl-4965-hw.h +164 -6
@@ -1286,7 +1286,7 @@ enum {/* Flow Handler Definitions */ /****************************/ -/* +/** * This I/O area is directly read/writable by driver (e.g. Linux uses writel()) * Addresses are offsets from device's PCI hardware base address. */
@@ -1313,35 +1313,193 @@ enum {#define IWL_FH_KW_MEM_ADDR_REG (FH_MEM_LOWER_BOUND + 0x97C) -/* CBBC Area - Circular buffers base address cache pointers table */ +/** +* TFD Circular Buffers Base (CBBC) addresses +* +* 4965 has 16 base pointer registers, one for each of 16 host-DRAM-resident +* circular buffers (CBs/queues) containing Transmit Frame Descriptors (TFDs) +* (see struct iwl_tfd_frame). These 16 pointer registers are offset by 0x04 +* bytes from one another. Each TFD circular buffer in DRAM must be 256-byte +* aligned (address bits 0-7 must be 0). +* +* Bit fields in each pointer register: +* 27-0: TFD CB physical base address [35:8], must be 256-byte aligned +*/ #define FH_MEM_CBBC_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0x9D0)#define FH_MEM_CBBC_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xA10) -/* queues 0 - 15 */ + +/* Find TFD CB base pointer for given queue (range 0-15). */ #define FH_MEM_CBBC_QUEUE (x) (FH_MEM_CBBC_LOWER_BOUND + (x) * 0x4) -/* RSCSR Area */ + +/** +* Rx SRAM Control and Status Registers (RSCSR) +* +* These registers provide handshake between driver and 4965 for the Rx queue +* (this queue handles *all* command responses, notifications, Rx data, etc. +* sent from 4965 uCode to host driver). Unlike Tx, there is only one Rx +* queue, and only one Rx DMA/FIFO channel. Also unlike Tx, which can +* concatenate up to 20 DRAM buffers to form a Tx frame, each Receive Buffer +* Descriptor (RBD) points to only one Rx Buffer (RB); there is a 1:1 +* mapping between RBDs and RBs. +* +* Driver must allocate host DRAM memory for the following, and set the +* physical address of each into 4965 registers: +* +* 1) Receive Buffer Descriptor (RBD) circular buffer (CB), typically with 256 +* entries (although any power of 2, up to 4096, is selectable by driver). +* Each entry (1 dword) points to a receive buffer (RB) of consistent size +* (typically 4K, although 8K or 16K are also selectable by driver). +* Driver sets up RB size and number of RBDs in the CB via Rx config +* register FH_MEM_RCSR_CHNL0_CONFIG_REG. +* +* Bit fields within one RBD: +* 27-0: Receive Buffer physical address bits [35:8], 256-byte aligned +* +* Driver sets physical address [35:8] of base of RBD circular buffer +* into FH_RSCSR_CHNL0_RBDCB_BASE_REG [27:0]. +* +* 2) Rx status buffer, 8 bytes, in which 4965 indicates which Rx Buffers +* (RBs) have been filled, via a "write pointer", actually the index of +* the RB's corresponding RBD within the circular buffer. Driver sets +* physical address [35:4] into FH_RSCSR_CHNL0_STTS_WPTR_REG [31:0]. +* +* Bit fields in lower dword of Rx status buffer (upper dword not used +* by driver; see struct iwl4965_shared, val0): +* 31-12: Not used by driver +* 11- 0: Index of last filled Rx buffer descriptor +* (4965 writes, driver reads this value) +* +* As the driver prepares Receive Buffers (RBs) for 4965 to fill, driver must +* enter pointers to these RBs into contiguous RBD circular buffer entries, +* and update the 4965's "write" index register, FH_RSCSR_CHNL0_RBDCB_WPTR_REG. +* +* This "write" index corresponds to the *next* RBD that the driver will make +* available, i.e. one RBD past the tail of the ready-to-fill RBDs within +* the circular buffer. This value should initially be 0 (before preparing any +* RBs), should be 8 after preparing the first 8 RBs (for example), and must +* wrap back to 0 at the end of the circular buffer (but don't wrap before +* "read" index has advanced past 1! See below). +* NOTE: 4965 EXPECTS THE WRITE INDEX TO BE INCREMENTED IN MULTIPLES OF 8. +* +* As the 4965 fills RBs (referenced from contiguous RBDs within the circular +* buffer), it updates the Rx status buffer in host DRAM, 2) described above, +* to tell the driver the index of the latest filled RBD. The driver must +* read this "read" index from DRAM after receiving an Rx interrupt from 4965. +* +* The driver must also internally keep track of a third index, which is the +* next RBD to process. When receiving an Rx interrupt, driver should process +* all filled but unprocessed RBs up to, but not including, the RB +* corresponding to the "read" index. For example, if "read" index becomes "1", +* driver may process the RB pointed to by RBD 0. Depending on volume of +* traffic, there may be many RBs to process. +* +* If read index == write index, 4965 thinks there is no room to put new data. +* Due to this, the maximum number of filled RBs is 255, instead of 256. To +* be safe, make sure that there is a gap of at least 2 RBDs between "write" +* and "read" indexes; that is, make sure that there are no more than 254 +* buffers waiting to be filled. +*/ #define FH_MEM_RSCSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xBC0)#define FH_MEM_RSCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xC00)#define FH_MEM_RSCSR_CHNL0 (FH_MEM_RSCSR_LOWER_BOUND) +/** +* Physical base address of 8-byte Rx Status buffer. +* Bit fields: +* 31-0: Rx status buffer physical base address [35:4], must 16-byte aligned. +*/ #define FH_RSCSR_CHNL0_STTS_WPTR_REG (FH_MEM_RSCSR_CHNL0) + +/** +* Physical base address of Rx Buffer Descriptor Circular Buffer. +* Bit fields: +* 27-0: RBD CD physical base address [35:8], must be 256-byte aligned. +*/ #define FH_RSCSR_CHNL0_RBDCB_BASE_REG (FH_MEM_RSCSR_CHNL0 + 0x004) + +/** +* Rx write pointer (index, really!). +* Bit fields: +* 11-0: Index of driver's most recent prepared-to-be-filled RBD, + 1. +* NOTE: For 256-entry circular buffer, use only bits [7:0]. +*/ #define FH_RSCSR_CHNL0_RBDCB_WPTR_REG (FH_MEM_RSCSR_CHNL0 + 0x008) -/* RCSR Area - Registers address map */ + +/** +* Rx Config/Status Registers (RCSR) +* Rx Config Reg for channel 0 (only channel used) +* +* Driver must initialize FH_MEM_RCSR_CHNL0_CONFIG_REG as follows for +* normal operation (see bit fields). +* +* Clearing FH_MEM_RCSR_CHNL0_CONFIG_REG to 0 turns off Rx DMA. +* Driver should poll FH_MEM_RSSR_RX_STATUS_REG for +* FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (bit 24) before continuing. +* +* Bit fields: +* 31-30: Rx DMA channel enable: '00' off/pause, '01' pause at end of frame, +* '10' operate normally +* 29-24: reserved +* 23-20: # RBDs in circular buffer = 2^value; use "8" for 256 RBDs (normal), +* min "5" for 32 RBDs, max "12" for 4096 RBDs. +* 19-18: reserved +* 17-16: size of each receive buffer; '00' 4K (normal), '01' 8K, +* '10' 12K, '11' 16K. +* 15-14: reserved +* 13-12: IRQ destination; '00' none, '01' host driver (normal operation) +* 11- 4: timeout for closing Rx buffer and interrupting host (units 32 usec) +* typical value 0x10 (about 1/2 msec) +* 3- 0: reserved +*/ #define FH_MEM_RCSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xC00)#define FH_MEM_RCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xCC0)#define FH_MEM_RCSR_CHNL0 (FH_MEM_RCSR_LOWER_BOUND)#define FH_MEM_RCSR_CHNL0_CONFIG_REG (FH_MEM_RCSR_CHNL0) -/* RSSR Area - Rx shared ctrl & status registers */ +#define FH_RCSR_CHNL0_RX_CONFIG_RB_TIMEOUT_MASK (0x00000FF0)/* bit 4-11 */ +#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_MASK (0x00001000)/* bit 12 */ +#define FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MASK (0x00008000)/* bit 15 */ +#define FH_RCSR_CHNL0_RX_CONFIG_RB_SIZE_MASK (0x00030000)/* bits 16-17 */ +#define FH_RCSR_CHNL0_RX_CONFIG_RBDBC_SIZE_MASK (0x00F00000)/* bits 20-23 */ +#define FH_RCSR_CHNL0_RX_CONFIG_DMA_CHNL_EN_MASK (0xC0000000)/* bits 30-31 */ + +#define FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT (20) +#define FH_RCSR_RX_CONFIG_RB_SIZE_BITSHIFT (16) + +#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_VAL (0x00000000) +#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_EOF_VAL (0x40000000) +#define FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL (0x80000000) + +#define IWL_FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K (0x00000000) + +#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_NO_INT_VAL (0x00000000) +#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL (0x00001000) + + +/** +* Rx Shared Status Registers (RSSR) +* +* After stopping Rx DMA channel (writing 0 to FH_MEM_RCSR_CHNL0_CONFIG_REG), +* driver must poll FH_MEM_RSSR_RX_STATUS_REG until Rx channel is idle. +* +* Bit fields: +* 24: 1 = Channel 0 is idle +* +* FH_MEM_RSSR_SHARED_CTRL_REG and FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV contain +* default values that should not be altered by the driver. +*/ #define FH_MEM_RSSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xC40)#define FH_MEM_RSSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xD00) +#define FH_MEM_RSSR_SHARED_CTRL_REG (FH_MEM_RSSR_LOWER_BOUND)#define FH_MEM_RSSR_RX_STATUS_REG (FH_MEM_RSSR_LOWER_BOUND + 0x004)#define FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV (FH_MEM_RSSR_LOWER_BOUND + 0x008) +#define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000) +/* TCSR */ #define IWL_FH_TCSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xD00)#define IWL_FH_TCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xE60)
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 24/34 iwlwifi: document shared Tx structures
From: Ben Cahill <[email protected]>
Document shared Tx structures
--- drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 147 +++++++++++++++++++++++++--- 1 files changed, 135 insertions(+), 12 deletions(-)
drivers/net/wireless/iwlwifi/iwl-4965-hw.h +135 -12
@@ -452,6 +452,13 @@ struct iwl4965_eeprom {*/ #define CSR_HW_REV_WA_REG (CSR_BASE+0x22C) +/* Hardware interface configuration bits */ +#define CSR_HW_IF_CONFIG_REG_BIT_KEDRON_R (0x00000010) +#define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x00000C00) +#define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100) +#define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200) +#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000) +/* interrupt flags in INTA, set by uCode or hardware (e.g. dma), * acknowledged (reset) by host writing "1" to flagged bits. */ #define CSR_INT_BIT_FH_RX (1<<31)/* Rx DMA, cmd responses, FH_INT[17:16] */
@@ -1575,12 +1582,6 @@ enum {#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16)#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000) -#define CSR_HW_IF_CONFIG_REG_BIT_KEDRON_R (0x00000010) -#define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x00000C00) -#define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100) -#define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200) -#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000) -static inline u8 iwl4965_hw_get_rate (__le32 rate_n_flags) {return le32_to_cpu (rate_n_flags) &0xFF ;
@@ -1594,6 +1595,53 @@ static inline __le32 iwl4965_hw_set_rate_n_flags(u8 rate, u16 flags)return cpu_to_le32 (flags|(u16 )rate); } + +/** +* Tx/Rx Queues +* +* Most communication between driver and 4965 is via queues of data buffers. +* For example, all commands that the driver issues to device's embedded +* controller (uCode) are via the command queue (one of the Tx queues). All +* uCode command responses/replies/notifications, including Rx frames, are +* conveyed from uCode to driver via the Rx queue. +* +* Most support for these queues, including handshake support, resides in +* structures in host DRAM, shared between the driver and the device. When +* allocating this memory, the driver must make sure that data written by +* the host CPU updates DRAM immediately (and does not get "stuck" in CPU's +* cache memory), so DRAM and cache are consistent, and the device can +* immediately see changes made by the driver. +* +* 4965 supports up to 16 DRAM-based Tx queues, and services these queues via +* up to 7 DMA channels (FIFOs). Each Tx queue is supported by a circular array +* in DRAM containing 256 Transmit Frame Descriptors (TFDs). +*/ +#define IWL4965_MAX_WIN_SIZE 64 +#define IWL4965_QUEUE_SIZE 256 +#define IWL4965_NUM_FIFOS 7 +#define IWL_MAX_NUM_QUEUES 16 + + +/** +* struct iwl4965_tfd_frame_data +* +* Describes up to 2 buffers containing (contiguous) portions of a Tx frame. +* Each buffer must be on dword boundary. +* Up to 10 iwl_tfd_frame_data structures, describing up to 20 buffers, +* may be filled within a TFD (iwl_tfd_frame). +* +* Bit fields in tb1_addr: +* 31- 0: Tx buffer 1 address bits [31:0] +* +* Bit fields in val1: +* 31-16: Tx buffer 2 address bits [15:0] +* 15- 4: Tx buffer 1 length (bytes) +* 3- 0: Tx buffer 1 address bits [32:32] +* +* Bit fields in val2: +* 31-20: Tx buffer 2 length (bytes) +* 19- 0: Tx buffer 2 address bits [35:16] +*/ struct iwl4965_tfd_frame_data {__le32 tb1_addr;
@@ -1622,6 +1670,35 @@ struct iwl4965_tfd_frame_data {#define IWL_tb2_len_SYM val2 } __attribute__ ((packed)); + +/** +* struct iwl4965_tfd_frame +* +* Transmit Frame Descriptor (TFD) +* +* 4965 supports up to 16 Tx queues resident in host DRAM. +* Each Tx queue uses a circular buffer of 256 TFDs stored in host DRAM. +* Both driver and device share these circular buffers, each of which must be +* contiguous 256 TFDs x 128 bytes-per-TFD = 32 KBytes for 4965. +* +* Driver must indicate the physical address of the base of each +* circular buffer via the 4965's FH_MEM_CBBC_QUEUE registers. +* +* Each TFD contains pointer/size information for up to 20 data buffers +* in host DRAM. These buffers collectively contain the (one) frame described +* by the TFD. Each buffer must be a single contiguous block of memory within +* itself, but buffers may be scattered in host DRAM. Each buffer has max size +* of (4K - 4). The 4965 concatenates all of a TFD's buffers into a single +* Tx frame, up to 8 KBytes in size. +* +* Bit fields in the control dword (val0): +* 31-30: # dwords (0-3) of padding required at end of frame for 16-byte bound +* 29: reserved +* 28-24: # Transmit Buffer Descriptors in TFD +* 23- 0: reserved +* +* A maximum of 255 (not 256!) TFDs may be on a queue waiting for Tx. +*/ struct iwl4965_tfd_frame {__le32 val0;/* __le32 rsvd1:24; */
@@ -1635,11 +1712,16 @@ struct iwl4965_tfd_frame {__le32 reserved; } __attribute__ ((packed)); -#define IWL4965_MAX_WIN_SIZE 64 -#define IWL4965_QUEUE_SIZE 256 -#define IWL4965_NUM_FIFOS 7 -#define IWL_MAX_NUM_QUEUES 16 +/** +* struct iwl4965_queue_byte_cnt_entry +* +* Byte Count Table Entry +* +* Bit fields: +* 15-12: reserved +* 11- 0: total to-be-transmitted byte count of frame (does not include command) +*/ struct iwl4965_queue_byte_cnt_entry {__le16 val;/* __le16 byte_cnt:12; */
@@ -1649,6 +1731,25 @@ struct iwl4965_queue_byte_cnt_entry {/* __le16 rsvd:4; */ } __attribute__ ((packed)); + +/** +* struct iwl4965_sched_queue_byte_cnt_tbl +* +* Byte Count table +* +* Each Tx queue uses a byte-count table containing 320 entries: +* one 16-bit entry for each of 256 TFDs, plus an additional 64 entries that +* duplicate the first 64 entries (to avoid wrap-around within a Tx window; +* max Tx window is 64 TFDs). +* +* When driver sets up a new TFD, it must also enter the total byte count +* of the frame to be transmitted into the corresponding entry in the byte +* count table for the chosen Tx queue. If the TFD index is 0-63, the driver +* must duplicate the byte count entry in corresponding index 256-319. +* +* "dont_care" padding puts each byte count table on a 1024-byte boundary; +* 4965 assumes tables are separated by 1024 bytes. +*/ struct iwl4965_sched_queue_byte_cnt_tbl {struct iwl4965_queue_byte_cnt_entry tfd_offset[IWL4965_QUEUE_SIZE +IWL4965_MAX_WIN_SIZE ];
@@ -1657,8 +1758,30 @@ struct iwl4965_sched_queue_byte_cnt_tbl { sizeof(__le16)]; } __attribute__ ((packed)); -/* Base physical address of iwl4965_shared is provided to KDR_SCD_DRAM_BASE_ADDR -* and &iwl4965_shared.val0 is provided to FH_RSCSR_CHNL0_STTS_WPTR_REG */ + +/** +* struct iwl4965_shared - handshake area for Tx and Rx +* +* For convenience in allocating memory, this structure combines 2 areas of +* DRAM which must be shared between driver and 4965. These do not need to +* be combined, if better allocation would result from keeping them separate: +* +* 1) The Tx byte count tables occupy 1024 bytes each (16 KBytes total for +* 16 queues). Driver uses SCD_DRAM_BASE_ADDR to tell 4965 where to find +* the first of these tables. 4965 assumes tables are 1024 bytes apart. +* +* 2) The Rx status (val0 and val1) occupies only 8 bytes. Driver uses +* FH_RSCSR_CHNL0_STTS_WPTR_REG to tell 4965 where to find this area. +* Driver reads val0 to determine the latest Receive Buffer Descriptor (RBD) +* that has been filled by the 4965. +* +* Bit fields val0: +* 31-12: Not used +* 11- 0: Index of last filled Rx buffer descriptor (4965 writes, driver reads) +* +* Bit fields val1: +* 31- 0: Not used +*/ struct iwl4965_shared {struct iwl4965_sched_queue_byte_cnt_tbl queues_byte_cnt_tbls[IWL_MAX_NUM_QUEUES ];
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 25/34 iwlwifi: document 4965 Tx scheduler
From: Ben Cahill <[email protected]>
Document 4965 Tx scheduler
--- drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 268 ++++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-prph.h | 14 +- drivers/net/wireless/iwlwifi/iwl4965-base.c | 2 + 3 files changed, 272 insertions(+), 12 deletions(-)
drivers/net/wireless/iwlwifi/iwl-4965-hw.h +260 -8
@@ -1555,33 +1555,285 @@ enum {/* RSCSR: defs used in normal mode */ #define FH_RSCSR_CHNL0_RBDCB_WPTR_MASK (0x00000FFF)/* bits 0-11 */ +/********************* START TX SCHEDULER *************************************/ + +/** +* 4965 Tx Scheduler +* +* The Tx Scheduler selects the next frame to be transmitted, chosing TFDs +* (Transmit Frame Descriptors) from up to 16 circular Tx queues resident in +* host DRAM. It steers each frame's Tx command (which contains the frame +* data) into one of up to 7 prioritized Tx DMA FIFO channels within the +* device. A queue maps to only one (selectable by driver) Tx DMA channel, +* but one DMA channel may take input from several queues. +* +* Tx DMA channels have dedicated purposes. For 4965, they are used as follows: +* +* 0 -- EDCA BK (background) frames, lowest priority +* 1 -- EDCA BE (best effort) frames, normal priority +* 2 -- EDCA VI (video) frames, higher priority +* 3 -- EDCA VO (voice) and management frames, highest priority +* 4 -- Commands (e.g. RXON, etc.) +* 5 -- HCCA short frames +* 6 -- HCCA long frames +* 7 -- not used by driver (device-internal only) +* +* Driver should normally map queues 0-6 to Tx DMA/FIFO channels 0-6. +* In addition, driver can map queues 7-15 to Tx DMA/FIFO channels 0-3 to +* support 11n aggregation via EDCA DMA channels. +* +* The driver sets up each queue to work in one of two modes: +* +* 1) Scheduler-Ack, in which the scheduler automatically supports a +* block-ack (BA) window of up to 64 TFDs. In this mode, each queue +* contains TFDs for a unique combination of Recipient Address (RA) +* and Traffic Identifier (TID), that is, traffic of a given +* Quality-Of-Service (QOS) priority, destined for a single station. +* +* In scheduler-ack mode, the scheduler keeps track of the Tx status of +* each frame within the BA window, including whether it's been transmitted, +* and whether it's been acknowledged by the receiving station. The device +* automatically processes block-acks received from the receiving STA, +* and reschedules un-acked frames to be retransmitted (successful +* Tx completion may end up being out-of-order). +* +* The driver must maintain the queue's Byte Count table in host DRAM +* (struct iwl4965_sched_queue_byte_cnt_tbl) for this mode. +* This mode does not support fragmentation. +* +* 2) FIFO (a.k.a. non-Scheduler-ACK), in which each TFD is processed in order. +* The device may automatically retry Tx, but will retry only one frame +* at a time, until receiving ACK from receiving station, or reaching +* retry limit and giving up. +* +* The command queue (#4) must use this mode! +* This mode does not require use of the Byte Count table in host DRAM. +* +* Driver controls scheduler operation via 3 means: +* 1) Scheduler registers +* 2) Shared scheduler data base in internal 4956 SRAM +* 3) Shared data in host DRAM +* +* Initialization: +* +* When loading, driver should allocate memory for: +* 1) 16 TFD circular buffers, each with space for (typically) 256 TFDs. +* 2) 16 Byte Count circular buffers in 16 KBytes contiguous memory +* (1024 bytes for each queue). +* +* After receiving "Alive" response from uCode, driver must initialize +* the scheduler (especially for queue #4, the command queue, otherwise +* the driver can't issue commands!): +*/ + +/** +* Max Tx window size is the max number of contiguous TFDs that the scheduler +* can keep track of at one time when creating block-ack chains of frames. +* Note that "64" matches the number of ack bits in a block-ack packet. +* Driver should use SCD_WIN_SIZE and SCD_FRAME_LIMIT values to initialize +* SCD_CONTEXT_QUEUE_OFFSET(x) values. +*/ #define SCD_WIN_SIZE 64#define SCD_FRAME_LIMIT 64 -/* SRAM structures */ -#define SCD_CONTEXT_DATA_OFFSET 0x380 -#define SCD_TX_STTS_BITMAP_OFFSET 0x400 -#define SCD_TRANSLATE_TBL_OFFSET 0x500 -#define SCD_CONTEXT_QUEUE_OFFSET (x) (SCD_CONTEXT_DATA_OFFSET + ((x) * 8)) -#define SCD_TRANSLATE_TBL_OFFSET_QUEUE (x) \ - ((SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffffffc) +/* SCD registers are internal, must be accessed via HBUS_TARG_PRPH regs */ +#define SCD_START_OFFSET 0xa02c00 + +/* +* 4965 tells driver SRAM address for internal scheduler structs via this reg. +* Value is valid only after "Alive" response from uCode. +*/ +#define SCD_SRAM_BASE_ADDR (SCD_START_OFFSET + 0x0) +/* +* Driver may need to update queue-empty bits after changing queue's +* write and read pointers (indexes) during (re-)initialization (i.e. when +* scheduler is not tracking what's happening). +* Bit fields: +* 31-16: Write mask -- 1: update empty bit, 0: don't change empty bit +* 15-00: Empty state, one for each queue -- 1: empty, 0: non-empty +* NOTE: This register is not used by Linux driver. +*/ +#define SCD_EMPTY_BITS (SCD_START_OFFSET + 0x4) + +/* +* Physical base address of array of byte count (BC) circular buffers (CBs). +* Each Tx queue has a BC CB in host DRAM to support Scheduler-ACK mode. +* This register points to BC CB for queue 0, must be on 1024-byte boundary. +* Others are spaced by 1024 bytes. +* Each BC CB is 2 bytes * (256 + 64) = 740 bytes, followed by 384 bytes pad. +* (Index into a queue's BC CB) = (index into queue's TFD CB) = (SSN & 0xff). +* Bit fields: +* 25-00: Byte Count CB physical address [35:10], must be 1024-byte aligned. +*/ +#define SCD_DRAM_BASE_ADDR (SCD_START_OFFSET + 0x10) + +/* +* Enables any/all Tx DMA/FIFO channels. +* Scheduler generates requests for only the active channels. +* Set this to 0xff to enable all 8 channels (normal usage). +* Bit fields: +* 7- 0: Enable (1), disable (0), one bit for each channel 0-7 +*/ +#define SCD_TXFACT (SCD_START_OFFSET + 0x1c) + +/* Mask to enable contiguous Tx DMA/FIFO channels between "lo" and "hi". */ #define SCD_TXFACT_REG_TXFIFO_MASK (lo, hi) \ ((1<<(hi))|((1<<(hi))-(1<<(lo)))) +/* +* Queue (x) Write Pointers (indexes, really!), one for each Tx queue. +* Initialized and updated by driver as new TFDs are added to queue. +* NOTE: If using Block Ack, index must correspond to frame's +* Start Sequence Number; index = (SSN & 0xff) +* NOTE: Alternative to HBUS_TARG_WRPTR, which is what Linux driver uses? +*/ +#define SCD_QUEUE_WRPTR (x) (SCD_START_OFFSET + 0x24 + (x) * 4) + +/* +* Queue (x) Read Pointers (indexes, really!), one for each Tx queue. +* For FIFO mode, index indicates next frame to transmit. +* For Scheduler-ACK mode, index indicates first frame in Tx window. +* Initialized by driver, updated by scheduler. +*/ +#define SCD_QUEUE_RDPTR (x) (SCD_START_OFFSET + 0x64 + (x) * 4) + +/* +* Select which queues work in chain mode (1) vs. not (0). +* Use chain mode to build chains of aggregated frames. +* Bit fields: +* 31-16: Reserved +* 15-00: Mode, one bit for each queue -- 1: Chain mode, 0: one-at-a-time +* NOTE: If driver sets up queue for chain mode, it should be also set up +* Scheduler-ACK mode as well, via SCD_QUEUE_STATUS_BITS(x). +*/ +#define SCD_QUEUECHAIN_SEL (SCD_START_OFFSET + 0xd0) + +/* +* Select which queues interrupt driver when scheduler increments +* a queue's read pointer (index). +* Bit fields: +* 31-16: Reserved +* 15-00: Interrupt enable, one bit for each queue -- 1: enabled, 0: disabled +* NOTE: This functionality is apparently a no-op; driver relies on interrupts +* from Rx queue to read Tx command responses and update Tx queues. +*/ +#define SCD_INTERRUPT_MASK (SCD_START_OFFSET + 0xe4) + +/* +* Queue search status registers. One for each queue. +* Sets up queue mode and assigns queue to Tx DMA channel. +* Bit fields: +* 19-10: Write mask/enable bits for bits 0-9 +* 9: Driver should init to "0" +* 8: Scheduler-ACK mode (1), non-Scheduler-ACK (i.e. FIFO) mode (0). +* Driver should init to "1" for aggregation mode, or "0" otherwise. +* 7-6: Driver should init to "0" +* 5: Window Size Left; indicates whether scheduler can request +* another TFD, based on window size, etc. Driver should init +* this bit to "1" for aggregation mode, or "0" for non-agg. +* 4-1: Tx FIFO to use (range 0-7). +* 0: Queue is active (1), not active (0). +* Other bits should be written as "0" +* +* NOTE: If enabling Scheduler-ACK mode, chain mode should also be enabled +* via SCD_QUEUECHAIN_SEL. +*/ +#define SCD_QUEUE_STATUS_BITS (x) (SCD_START_OFFSET + 0x104 + (x) * 4) + +/* Bit field positions */ #define SCD_QUEUE_STTS_REG_POS_ACTIVE (0)#define SCD_QUEUE_STTS_REG_POS_TXF (1)#define SCD_QUEUE_STTS_REG_POS_WSL (5)#define SCD_QUEUE_STTS_REG_POS_SCD_ACK (8) + +/* Write masks */ #define SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (10)#define SCD_QUEUE_STTS_REG_MSK (0x0007FC00) +/** +* 4965 internal SRAM structures for scheduler, shared with driver ... +* +* Driver should clear and initialize the following areas after receiving +* "Alive" response from 4965 uCode, i.e. after initial +* uCode load, or after a uCode load done for error recovery: +* +* SCD_CONTEXT_DATA_OFFSET (size 128 bytes) +* SCD_TX_STTS_BITMAP_OFFSET (size 256 bytes) +* SCD_TRANSLATE_TBL_OFFSET (size 32 bytes) +* +* Driver accesses SRAM via HBUS_TARG_MEM_* registers. +* Driver reads base address of this scheduler area from SCD_SRAM_BASE_ADDR. +* All OFFSET values must be added to this base address. +*/ + +/* +* Queue context. One 8-byte entry for each of 16 queues. +* +* Driver should clear this entire area (size 0x80) to 0 after receiving +* "Alive" notification from uCode. Additionally, driver should init +* each queue's entry as follows: +* +* LS Dword bit fields: +* 0-06: Max Tx window size for Scheduler-ACK. Driver should init to 64. +* +* MS Dword bit fields: +* 16-22: Frame limit. Driver should init to 10 (0xa). +* +* Driver should init all other bits to 0. +* +* Init must be done after driver receives "Alive" response from 4965 uCode, +* and when setting up queue for aggregation. +*/ +#define SCD_CONTEXT_DATA_OFFSET 0x380 +#define SCD_CONTEXT_QUEUE_OFFSET (x) (SCD_CONTEXT_DATA_OFFSET + ((x) * 8)) +#define SCD_QUEUE_CTX_REG1_WIN_SIZE_POS (0)#define SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK (0x0000007F) -#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16)#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000) +/* +* Tx Status Bitmap +* +* Driver should clear this entire area (size 0x100) to 0 after receiving +* "Alive" notification from uCode. Area is used only by device itself; +* no other support (besides clearing) is required from driver. +*/ +#define SCD_TX_STTS_BITMAP_OFFSET 0x400 + +/* +* RAxTID to queue translation mapping. +* +* When queue is in Scheduler-ACK mode, frames placed in a that queue must be +* for only one combination of receiver address (RA) and traffic ID (TID), i.e. +* one QOS priority level destined for one station (for this wireless link, +* not final destination). The SCD_TRANSLATE_TABLE area provides 16 16-bit +* mappings, one for each of the 16 queues. If queue is not in Scheduler-ACK +* mode, the device ignores the mapping value. +* +* Bit fields, for each 16-bit map: +* 15-9: Reserved, set to 0 +* 8-4: Index into device's station table for recipient station +* 3-0: Traffic ID (tid), range 0-15 +* +* Driver should clear this entire area (size 32 bytes) to 0 after receiving +* "Alive" notification from uCode. To update a 16-bit map value, driver +* must read a dword-aligned value from device SRAM, replace the 16-bit map +* value of interest, and write the dword value back into device SRAM. +*/ +#define SCD_TRANSLATE_TBL_OFFSET 0x500 + +/* Find translation table dword to read/write for given queue */ +#define SCD_TRANSLATE_TBL_OFFSET_QUEUE (x) \ + ((SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffffffc) + +#define SCD_TXFIFO_POS_TID (0) +#define SCD_TXFIFO_POS_RA (4) +#define SCD_QUEUE_RA_TID_MAP_RATID_MSK (0x01FF) + +/*********************** END TX SCHEDULER *************************************/ +static inline u8 iwl4965_hw_get_rate (__le32 rate_n_flags) {return le32_to_cpu (rate_n_flags) &0xFF ;
drivers/net/wireless/iwlwifi/iwl-prph.h +10 -4
@@ -63,7 +63,10 @@#ifndef __iwl_prph_h__#define __iwl_prph_h__ - +/* +* Registers in this file are internal, not PCI bus memory mapped. +* Driver accesses these via HBUS_TARG_PRPH_* registers. +*/ #define PRPH_BASE (0x00000)#define PRPH_END (0xFFFFF)
@@ -225,8 +228,8 @@#define BSM_SRAM_LOWER_BOUND (PRPH_BASE + 0x3800)#define BSM_SRAM_SIZE (1024)/* bytes */ -/* ALM SCD */ -/* SCD (Scheduler) */ + +/* 3945 Tx scheduler registers */ #define ALM_SCD_BASE (PRPH_BASE + 0x2E00)#define ALM_SCD_MODE_REG (ALM_SCD_BASE + 0x000)#define ALM_SCD_ARASTAT_REG (ALM_SCD_BASE + 0x004)
@@ -236,7 +239,10 @@#define ALM_SCD_SBYP_MODE_1_REG (ALM_SCD_BASE + 0x02C)#define ALM_SCD_SBYP_MODE_2_REG (ALM_SCD_BASE + 0x030) -/* 4965 SCD memory mapped registers */ +/* +* 4965 Tx Scheduler registers. +* Details are documented in iwl-4965-hw.h +*/ #define KDR_SCD_BASE (PRPH_BASE + 0xa02c00)#define KDR_SCD_SRAM_BASE_ADDR (KDR_SCD_BASE + 0x0)
drivers/net/wireless/iwlwifi/iwl4965-base.c +2 -0
@@ -202,6 +202,8 @@ static void iwl4965_print_hex_dump(int level, void *p, u32 len)* The 4965 operates with up to 17 queues: One receive queue, one transmit * queue (#4) for sending commands to the device firmware, and 15 other * Tx queues that may be mapped to prioritized Tx DMA/FIFO channels. +* +* See more detailed info in iwl-4965-hw.h. ***************************************************/ static int iwl4965_queue_space (const struct iwl4965_queue *q)
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 26/34 iwlwifi: document command header and "alive" responses
From: Ben Cahill <[email protected]>
Document command header and "alive" responses
--- drivers/net/wireless/iwlwifi/iwl-3945-commands.h | 85 +++++++++--- drivers/net/wireless/iwlwifi/iwl-4965-commands.h | 160 +++++++++++++++++----- 2 files changed, 192 insertions(+), 53 deletions(-)
drivers/net/wireless/iwlwifi/iwl-3945-commands.h +66 -19
@@ -121,7 +121,7 @@ enum {REPLY_TX_PWR_TABLE_CMD =0x97 ,MEASURE_ABORT_NOTIFICATION =0x99 ,/* not used */ -/* BT config command */ +/* Bluetooth device coexistance config command */ REPLY_BT_CONFIG = 0x9b,/* 4965 Statistics */
@@ -144,25 +144,42 @@ enum {* *****************************************************************************/ +/* iwl3945_cmd_header flags value */ #define IWL_CMD_FAILED_MSK 0x40 +/** +* struct iwl3945_cmd_header +* +* This header format appears in the beginning of each command sent from the +* driver, and each response/notification received from uCode. +*/ struct iwl3945_cmd_header { -u8 cmd; -u8 flags; -/* We have 15 LSB to use as we please (MSB indicates -* a frame Rx'd from the HW). We encode the following -* information into the sequence field: +u8 cmd;/* Command ID: REPLY_RXON, etc. */ +u8 flags;/* IWL_CMD_* */ +/* +* The driver sets up the sequence number to values of its chosing. +* uCode does not use this value, but passes it back to the driver +* when sending the response to each driver-originated command, so +* the driver can match the response to the command. Since the values +* don't get used by uCode, the driver may set up an arbitrary format. +* +* There is one exception: uCode sets bit 15 when it originates +* the response/notification, i.e. when the response/notification +* is not a direct response to a command sent by the driver. For +* example, uCode issues REPLY_3945_RX when it sends a received frame +* to the driver; it is not a direct response to any driver command. * -* 0:7 index in fifo -* 8:13 fifo selection -* 14:14 bit indicating if this packet references the 'extra' -* storage at the end of the memory queue -* 15:15 (Rx indication) +* The Linux driver uses the following format: * +* 0:7 index/position within Tx queue +* 8:13 Tx queue selection +* 14:14 driver sets this to indicate command is in the 'huge' +* storage at the end of the command buffers, i.e. scan cmd +* 15:15 uCode sets this in uCode-originated response/notification */ __le16 sequence; -/* command data follows immediately */ +/* command or response/notification data follows immediately */ u8 data[0 ]; } __attribute__ ((packed));
@@ -176,15 +193,22 @@ struct iwl3945_cmd_header {#define INITIALIZE_SUBTYPE (9)/* -* REPLY_ALIVE = 0x1 (response only, not a command) +* ("Initialize") REPLY_ALIVE = 0x1 (response only, not a command) +* +* uCode issues this "initialize alive" notification once the initialization +* uCode image has completed its work, and is ready to load the runtime image. +* This is the *first* "alive" notification that the driver will receive after +* rebooting uCode; the "initialize" alive is indicated by subtype field == 9. +* +* See comments documenting "BSM" (bootstrap state machine). */ -struct iwl3945_alive_resp { +struct iwl3945_init_alive_resp {u8 ucode_minor;u8 ucode_major;__le16 reserved1;u8 sw_rev[8 ];u8 ver_type; -u8 ver_subtype; +u8 ver_subtype;/* "9" for initialize alive */ __le16 reserved2;__le32 log_event_table_ptr;__le32 error_event_table_ptr;
@@ -192,16 +216,39 @@ struct iwl3945_alive_resp {__le32 is_valid; } __attribute__ ((packed)); -struct iwl3945_init_alive_resp { + +/** +* REPLY_ALIVE = 0x1 (response only, not a command) +* +* uCode issues this "alive" notification once the runtime image is ready +* to receive commands from the driver. This is the *second* "alive" +* notification that the driver will receive after rebooting uCode; +* this "alive" is indicated by subtype field != 9. +* +* See comments documenting "BSM" (bootstrap state machine). +* +* This response includes two pointers to structures within the device's +* data SRAM (access via HBUS_TARG_MEM_* regs) that are useful for debugging: +* +* 1) log_event_table_ptr indicates base of the event log. This traces +* a 256-entry history of uCode execution within a circular buffer. +* +* 2) error_event_table_ptr indicates base of the error log. This contains +* information about any uCode error that occurs. +* +* The Linux driver can print both logs to the system log when a uCode error +* occurs. +*/ +struct iwl3945_alive_resp {u8 ucode_minor;u8 ucode_major;__le16 reserved1;u8 sw_rev[8 ];u8 ver_type; -u8 ver_subtype; +u8 ver_subtype;/* not "9" for runtime alive */ __le16 reserved2; -__le32 log_event_table_ptr; -__le32 error_event_table_ptr; +__le32 log_event_table_ptr;/* SRAM address for event log */ +__le32 error_event_table_ptr;/* SRAM address for error log */ __le32 timestamp;__le32 is_valid; } __attribute__ ((packed));
drivers/net/wireless/iwlwifi/iwl-4965-commands.h +126 -34
231 lines not on this page · raw message
__le16 word[4];
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 27/34 iwlwifi: add comments to RXON command and txpower formats
From: Ben Cahill <[email protected]>
Add comments to RXON command and txpower formats
--- drivers/net/wireless/iwlwifi/iwl-3945-commands.h | 62 ++++++++++--- drivers/net/wireless/iwlwifi/iwl-4965-commands.h | 104 ++++++++++++++++------ 2 files changed, 124 insertions(+), 42 deletions(-)
drivers/net/wireless/iwlwifi/iwl-3945-commands.h +48 -14
@@ -124,7 +124,7 @@ enum {/* Bluetooth device coexistance config command */ REPLY_BT_CONFIG =0x9b , -/* 4965 Statistics */ +/* Statistics */ REPLY_STATISTICS_CMD =0x9c , STATISTICS_NOTIFICATION = 0x9d,
@@ -140,7 +140,8 @@ enum {/****************************************************************************** * (0) -* Header +* Commonly used structures and definitions: +* Command header, txpower * *****************************************************************************/
@@ -183,6 +184,36 @@ struct iwl3945_cmd_header {u8 data[0 ]; } __attribute__ ((packed)); +/** +* struct iwl3945_tx_power +* +* Used in REPLY_TX_PWR_TABLE_CMD, REPLY_SCAN_CMD, REPLY_CHANNEL_SWITCH +* +* Each entry contains two values: +* 1) DSP gain (or sometimes called DSP attenuation). This is a fine-grained +* linear value that multiplies the output of the digital signal processor, +* before being sent to the analog radio. +* 2) Radio gain. This sets the analog gain of the radio Tx path. +* It is a coarser setting, and behaves in a logarithmic (dB) fashion. +* +* Driver obtains values from struct iwl3945_tx_power power_gain_table[][]. +*/ +struct iwl3945_tx_power { +u8 tx_gain;/* gain for analog radio */ +u8 dsp_atten;/* gain for DSP */ +} __attribute__ ((packed)); + +/** +* struct iwl3945_power_per_rate +* +* Used in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH +*/ +struct iwl3945_power_per_rate { +u8 rate;/* plcp */ +struct iwl3945_tx_power tpc; +u8 reserved; +} __attribute__ ((packed)); +/****************************************************************************** * (0a) * Alive and Error Commands & Responses:
@@ -328,8 +359,22 @@ enum {/* transfer to host non bssid beacons in associated state */ #define RXON_FILTER_BCON_AWARE_MSK __constant_cpu_to_le32(1 << 6) -/* +/** * REPLY_RXON = 0x10 (command, has simple generic response) +* +* RXON tunes the radio tuner to a service channel, and sets up a number +* of parameters that are used primarily for Rx, but also for Tx operations. +* +* NOTE: When tuning to a new channel, driver must set the +* RXON_FILTER_ASSOC_MSK to 0. This will clear station-dependent +* info within the device, including the station tables, tx retry +* rate tables, and txpower tables. Driver must build a new station +* table and txpower table before transmitting anything on the RXON +* channel. +* +* NOTE: All RXONs wipe clean the internal txpower table. Driver must +* issue a new REPLY_TX_PWR_TABLE_CMD after each REPLY_RXON (0x10), +* regardless of whether RXON_FILTER_ASSOC_MSK is set. */ struct iwl3945_rxon_cmd {u8 node_addr[6 ];
@@ -373,17 +418,6 @@ struct iwl3945_rxon_time_cmd {__le16 reserved; } __attribute__ ((packed)); -struct iwl3945_tx_power { -u8 tx_gain;/* gain for analog radio */ -u8 dsp_atten;/* gain for DSP */ -} __attribute__ ((packed)); - -struct iwl3945_power_per_rate { -u8 rate;/* plcp */ -struct iwl3945_tx_power tpc; -u8 reserved; -} __attribute__ ((packed)); -/* * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response) */
drivers/net/wireless/iwlwifi/iwl-4965-commands.h +76 -28
135 lines not on this page · raw message
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 28/34 iwlwifi: add comments to QOS and ADD_STA commands
From: Ben Cahill <[email protected]>
Add comments to QOS and ADD_STA commands
--- drivers/net/wireless/iwlwifi/iwl-3945-commands.h | 97 +++++++++++++++++---- drivers/net/wireless/iwlwifi/iwl-4965-commands.h | 99 +++++++++++++++++++--- 2 files changed, 165 insertions(+), 31 deletions(-)
drivers/net/wireless/iwlwifi/iwl-3945-commands.h +80 -17
@@ -445,6 +445,23 @@ struct iwl3945_csa_notification {* Quality-of-Service (QOS) Commands & Responses: * *****************************************************************************/ + +/** +* struct iwl_ac_qos -- QOS timing params for REPLY_QOS_PARAM +* One for each of 4 EDCA access categories in struct iwl_qosparam_cmd +* +* @cw_min: Contention window, start value in numbers of slots. +* Should be a power-of-2, minus 1. Device's default is 0x0f. +* @cw_max: Contention window, max value in numbers of slots. +* Should be a power-of-2, minus 1. Device's default is 0x3f. +* @aifsn: Number of slots in Arbitration Interframe Space (before +* performing random backoff timing prior to Tx). Device default 1. +* @edca_txop: Length of Tx opportunity, in uSecs. Device default is 0. +* +* Device will automatically increase contention window by (2*CW) + 1 for each +* transmission retry. Device uses cw_max as a bit mask, ANDed with new CW +* value, to cap the CW value. +*/ struct iwl3945_ac_qos {__le16 cw_min;__le16 cw_max;
@@ -458,14 +475,14 @@ struct iwl3945_ac_qos {#define QOS_PARAM_FLG_TGN_MSK __constant_cpu_to_le32(0x02)#define QOS_PARAM_FLG_TXOP_TYPE_MSK __constant_cpu_to_le32(0x10) -/* -* TXFIFO Queue number defines -*/ -/* number of Access categories (AC) (EDCA), queues 0..3 */ +/* Number of Access Categories (AC) (EDCA), queues 0..3 */ #define AC_NUM 4/* * REPLY_QOS_PARAM = 0x13 (command, has simple generic response) +* +* This command sets up timings for each of the 4 prioritized EDCA Tx FIFOs +* 0: Background, 1: Best Effort, 2: Video, 3: Voice. */ struct iwl3945_qosparam_cmd {__le32 qos_flags;
@@ -480,22 +497,21 @@ struct iwl3945_qosparam_cmd {/* * Multi station support */ + +/* Special, dedicated locations within device's station table */ #define IWL_AP_ID 0#define IWL_MULTICAST_ID 1#define IWL_STA_ID 2 -#define IWL3945_BROADCAST_ID 24#define IWL3945_STATION_COUNT 25 -#define IWL4965_BROADCAST_ID 31 -#define IWL4965_STATION_COUNT 32 -#define IWL_STATION_COUNT 32/* MAX(3945,4965)*/ #define IWL_INVALID_STATION 255#define STA_FLG_TX_RATE_MSK __constant_cpu_to_le32(1<<2);#define STA_FLG_PWR_SAVE_MSK __constant_cpu_to_le32(1<<8); +/* Use in mode field. 1: modify existing entry, 0: add new station entry */ #define STA_CONTROL_MODIFY_MSK 0x01/* key flags __le16*/
@@ -508,13 +524,10 @@ struct iwl3945_qosparam_cmd {#define STA_KEY_FLG_KEYID_POS 8#define STA_KEY_FLG_INVALID __constant_cpu_to_le16(0x0800) -/* modify flags */ +/* Flags indicate whether to modify vs. don't change various station params */ #define STA_MODIFY_KEY_MASK 0x01#define STA_MODIFY_TID_DISABLE_TX 0x02#define STA_MODIFY_TX_RATE_MSK 0x04 -#define STA_MODIFY_ADDBA_TID_MSK 0x08 -#define STA_MODIFY_DELBA_TID_MSK 0x10 -#define BUILD_RAxTID (sta_id, tid) (((sta_id) << 4) + (tid))/* * Antenna masks:
@@ -537,6 +550,18 @@ struct iwl3945_keyinfo {u8 key[16 ];/* 16-byte unicast decryption key */ } __attribute__ ((packed)); +/** +* struct sta_id_modify +* @addr[ETH_ALEN]: station's MAC address +* @sta_id: index of station in uCode's station table +* @modify_mask: STA_MODIFY_*, 1: modify, 0: don't change +* +* Driver selects unused table index when adding new station, +* or the index to a pre-existing station entry when modifying that station. +* Some indexes have special purposes (IWL_AP_ID, index 0, is for AP). +* +* modify_mask flags select which parameters to modify vs. leave alone. +*/ struct sta_id_modify {u8 addr[ETH_ALEN ];__le16 reserved1;
@@ -547,29 +572,67 @@ struct sta_id_modify {/* * REPLY_ADD_STA = 0x18 (command) +* +* The device contains an internal table of per-station information, +* with info on security keys, aggregation parameters, and Tx rates for +* initial Tx attempt and any retries (4965 uses REPLY_TX_LINK_QUALITY_CMD, +* 3945 uses REPLY_RATE_SCALE to set up rate tables). +* +* REPLY_ADD_STA sets up the table entry for one station, either creating +* a new entry, or modifying a pre-existing one. +* +* NOTE: RXON command (without "associated" bit set) wipes the station table +* clean. Moving into RF_KILL state does this also. Driver must set up +* new station table before transmitting anything on the RXON channel +* (except active scans or active measurements; those commands carry +* their own txpower/rate setup data). +* +* When getting started on a new channel, driver must set up the +* IWL_BROADCAST_ID entry (last entry in the table). For a client +* station in a BSS, once an AP is selected, driver sets up the AP STA +* in the IWL_AP_ID entry (1st entry in the table). BROADCAST and AP +* are all that are needed for a BSS client station. If the device is +* used as AP, or in an IBSS network, driver must set up station table +* entries for all STAs in network, starting with index IWL_STA_ID. */ struct iwl3945_addsta_cmd { -u8 mode; +u8 mode;/* 1: modify existing, 0: add new station */ u8 reserved[3 ];struct sta_id_modify sta;struct iwl3945_keyinfo key; -__le32 station_flags; -__le32 station_flags_msk; +__le32 station_flags;/* STA_FLG_* */ +__le32 station_flags_msk;/* STA_FLG_* */ + +/* bit field to disable (1) or enable (0) Tx for Traffic ID (TID) +* corresponding to bit (e.g. bit 5 controls TID 5). +* Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */ __le16 tid_disable_tx; +__le16 rate_n_flags; + +/* TID for which to add block-ack support. +* Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ u8 add_immediate_ba_tid; + +/* TID for which to remove block-ack support. +* Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */ u8 remove_immediate_ba_tid; + +/* Starting Sequence Number for added block-ack support. +* Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ __le16 add_immediate_ba_ssn; } __attribute__ ((packed)); +#define ADD_STA_SUCCESS_MSK 0x1 +#define ADD_STA_NO_ROOM_IN_TABLE 0x2 +#define ADD_STA_NO_BLOCK_ACK_RESOURCE 0x4/* * REPLY_ADD_STA = 0x18 (response) */ struct iwl3945_add_sta_resp { -u8 status; +u8 status;/* ADD_STA_* */ } __attribute__ ((packed)); -#define ADD_STA_SUCCESS_MSK 0x1/****************************************************************************** * (4)
drivers/net/wireless/iwlwifi/iwl-4965-commands.h +85 -14
172 lines not on this page · raw message
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 29/34 iwlwifi: add comments to Tx commands
From: Ben Cahill <[email protected]>
Add comments to Tx commands
Clean up unused definitions in iwl-3945-commands.h
--- drivers/net/wireless/iwlwifi/iwl-3945-commands.h | 161 ++++++++++-------- drivers/net/wireless/iwlwifi/iwl-4965-commands.h | 201 +++++++++++++++++++--- 2 files changed, 267 insertions(+), 95 deletions(-)
drivers/net/wireless/iwlwifi/iwl-3945-commands.h +92 -69
@@ -743,36 +743,86 @@ struct iwl4965_rx_mpdu_res_start {* (5) * Tx Commands & Responses: * +* Driver must place each REPLY_TX command into one of the prioritized Tx +* queues in host DRAM, shared between driver and device. When the device's +* Tx scheduler and uCode are preparing to transmit, the device pulls the +* Tx command over the PCI bus via one of the device's Tx DMA channels, +* to fill an internal FIFO from which data will be transmitted. +* +* uCode handles all timing and protocol related to control frames +* (RTS/CTS/ACK), based on flags in the Tx command. +* +* uCode handles retrying Tx when an ACK is expected but not received. +* This includes trying lower data rates than the one requested in the Tx +* command, as set up by the REPLY_RATE_SCALE (for 3945) or +* REPLY_TX_LINK_QUALITY_CMD (4965). +* +* Driver sets up transmit power for various rates via REPLY_TX_PWR_TABLE_CMD. +* This command must be executed after every RXON command, before Tx can occur. *****************************************************************************/ -/* Tx flags */ +/* REPLY_TX Tx flags field */ + +/* 1: Use Request-To-Send protocol before this frame. +* Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */ #define TX_CMD_FLG_RTS_MSK __constant_cpu_to_le32(1 << 1) + +/* 1: Transmit Clear-To-Send to self before this frame. +* Driver should set this for AUTH/DEAUTH/ASSOC-REQ/REASSOC mgmnt frames. +* Mutually exclusive vs. TX_CMD_FLG_RTS_MSK. */ #define TX_CMD_FLG_CTS_MSK __constant_cpu_to_le32(1 << 2) + +/* 1: Expect ACK from receiving station +* 0: Don't expect ACK (MAC header's duration field s/b 0) +* Set this for unicast frames, but not broadcast/multicast. */ #define TX_CMD_FLG_ACK_MSK __constant_cpu_to_le32(1 << 3) + +/* 1: Use rate scale table (see REPLY_TX_LINK_QUALITY_CMD). +* Tx command's initial_rate_index indicates first rate to try; +* uCode walks through table for additional Tx attempts. +* 0: Use Tx rate/MCS from Tx command's rate_n_flags field. +* This rate will be used for all Tx attempts; it will not be scaled. */ #define TX_CMD_FLG_STA_RATE_MSK __constant_cpu_to_le32(1 << 4) + +/* 1: Expect immediate block-ack. +* Set when Txing a block-ack request frame. Also set TX_CMD_FLG_ACK_MSK. */ #define TX_CMD_FLG_IMM_BA_RSP_MASK __constant_cpu_to_le32(1 << 6) + +/* 1: Frame requires full Tx-Op protection. +* Set this if either RTS or CTS Tx Flag gets set. */ #define TX_CMD_FLG_FULL_TXOP_PROT_MSK __constant_cpu_to_le32(1 << 7) + +/* Tx antenna selection field; used only for 3945, reserved (0) for 4965. +* Set field to "0" to allow 3945 uCode to select antenna (normal usage). */ #define TX_CMD_FLG_ANT_SEL_MSK __constant_cpu_to_le32(0xf00)#define TX_CMD_FLG_ANT_A_MSK __constant_cpu_to_le32(1 << 8)#define TX_CMD_FLG_ANT_B_MSK __constant_cpu_to_le32(1 << 9) -/* ucode ignores BT priority for this frame */ +/* 1: Ignore Bluetooth priority for this frame. +* 0: Delay Tx until Bluetooth device is done (normal usage). */ #define TX_CMD_FLG_BT_DIS_MSK __constant_cpu_to_le32(1 << 12) -/* ucode overrides sequence control */ +/* 1: uCode overrides sequence control field in MAC header. +* 0: Driver provides sequence control field in MAC header. +* Set this for management frames, non-QOS data frames, non-unicast frames, +* and also in Tx command embedded in REPLY_SCAN_CMD for active scans. */ #define TX_CMD_FLG_SEQ_CTL_MSK __constant_cpu_to_le32(1 << 13) -/* signal that this frame is non-last MPDU */ +/* 1: This frame is non-last MPDU; more fragments are coming. +* 0: Last fragment, or not using fragmentation. */ #define TX_CMD_FLG_MORE_FRAG_MSK __constant_cpu_to_le32(1 << 14) -/* calculate TSF in outgoing frame */ +/* 1: uCode calculates and inserts Timestamp Function (TSF) in outgoing frame. +* 0: No TSF required in outgoing frame. +* Set this for transmitting beacons and probe responses. */ #define TX_CMD_FLG_TSF_MSK __constant_cpu_to_le32(1 << 16) -/* activate TX calibration. */ -#define TX_CMD_FLG_CALIB_MSK __constant_cpu_to_le32(1 << 17) - -/* signals that 2 bytes pad was inserted -after the MAC header */ +/* 1: Driver inserted 2 bytes pad after the MAC header, for (required) dword +* alignment of frame's payload data field. +* 0: No pad +* Set this for MAC headers with 26 or 30 bytes, i.e. those with QOS or ADDR4 +* field (but not both). Driver must align frame data (i.e. data following +* MAC header) to DWORD boundary. */ #define TX_CMD_FLG_MH_PAD_MSK __constant_cpu_to_le32(1 << 20)/* HCCA-AP - disable duration overwriting. */
@@ -789,23 +839,33 @@ struct iwl4965_rx_mpdu_res_start {#define TX_CMD_SEC_KEY128 0x08/* -* TX command Frame life time -*/ - -struct iwl3945_dram_scratch { -u8 try_cnt; -u8 bt_kill_cnt; -__le16 reserved; -} __attribute__ ((packed)); - -/* * REPLY_TX = 0x1c (command) */ struct iwl3945_tx_cmd { +/* +* MPDU byte count: +* MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size, +* + 8 byte IV for CCM or TKIP (not used for WEP) +* + Data payload +* + 8-byte MIC (not used for CCM/WEP) +* NOTE: Does not include Tx command bytes, post-MAC pad bytes, +* MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i +* Range: 14-2342 bytes. +*/ __le16 len; + +/* +* MPDU or MSDU byte count for next frame. +* Used for fragmentation and bursting, but not 11n aggregation. +* Same as "len", but for next frame. Set to 0 if not applicable. +*/ __le16 next_frame_len; -__le32 tx_flags; + +__le32 tx_flags;/* TX_CMD_FLG_* */ +u8 rate; + +/* Index of recipient station in uCode's station table */ u8 sta_id;u8 tid_tspec;u8 sec_ctl;
@@ -827,7 +887,17 @@ struct iwl3945_tx_cmd {__le16 pm_frame_timeout;__le16 attempt_duration; } timeout; + +/* +* Duration of EDCA burst Tx Opportunity, in 32-usec units. +* Set this if txop time is not specified by HCCA protocol (e.g. by AP). +*/ __le16 driver_txop; + +/* +* MAC header goes here, followed by 2 bytes padding if MAC header +* length is 26 or 30 bytes, followed by payload data +*/ u8 payload[0 ];struct ieee80211_hdr hdr[0 ]; } __attribute__ ((packed));
@@ -899,37 +969,6 @@ enum { TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */ }; -/* ******************************* -* TX aggregation state -******************************* */ - -enum { -AGG_TX_STATE_TRANSMITTED =0x00 , -AGG_TX_STATE_UNDERRUN_MSK =0x01 , -AGG_TX_STATE_BT_PRIO_MSK =0x02 , -AGG_TX_STATE_FEW_BYTES_MSK =0x04 , -AGG_TX_STATE_ABORT_MSK =0x08 , -AGG_TX_STATE_LAST_SENT_TTL_MSK =0x10 , -AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK =0x20 , -AGG_TX_STATE_LAST_SENT_BT_KILL_MSK =0x40 , -AGG_TX_STATE_SCD_QUERY_MSK =0x80 , -AGG_TX_STATE_TEST_BAD_CRC32_MSK =0x100 , -AGG_TX_STATE_RESPONSE_MSK =0x1ff , -AGG_TX_STATE_DUMP_TX_MSK =0x200 , -AGG_TX_STATE_DELAY_TX_MSK =0x400 -}; - -#define AGG_TX_STATE_LAST_SENT_MSK \ -(AGG_TX_STATE_LAST_SENT_TTL_MSK | \ - AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK | \ - AGG_TX_STATE_LAST_SENT_BT_KILL_MSK) - -#define AGG_TX_STATE_TRY_CNT_POS 12 -#define AGG_TX_STATE_TRY_CNT_MSK 0xf000 - -#define AGG_TX_STATE_SEQ_NUM_POS 16 -#define AGG_TX_STATE_SEQ_NUM_MSK 0xffff0000 -/* * REPLY_TX = 0x1c (response) */
@@ -939,23 +978,7 @@ struct iwl3945_tx_resp {u8 bt_kill_count;u8 rate;__le32 wireless_media_time; -__le32 status;/* TX status (for aggregation status of 1st frame) */ -} __attribute__ ((packed)); - -/* -* REPLY_COMPRESSED_BA = 0xc5 (response only, not a command) -*/ -struct iwl3945_compressed_ba_resp { -__le32 sta_addr_lo32; -__le16 sta_addr_hi16; -__le16 reserved; -u8 sta_id; -u8 tid; -__le16 ba_seq_ctl; -__le32 ba_bitmap0; -__le32 ba_bitmap1; -__le16 scd_flow; -__le16 scd_ssn; +__le32 status;/* TX status */ } __attribute__ ((packed));/*
drivers/net/wireless/iwlwifi/iwl-4965-commands.h +175 -26
306 lines not on this page · raw message
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 30/34 iwlwifi: document 4965 rate scaling
From: Ben Cahill <[email protected]>
Document 4965 rate scaling
--- drivers/net/wireless/iwlwifi/iwl-4965-commands.h | 251 +++++++++++++++++++++- 1 files changed, 247 insertions(+), 4 deletions(-)
drivers/net/wireless/iwlwifi/iwl-4965-commands.h +247 -4
@@ -1322,6 +1322,8 @@ struct iwl4965_compressed_ba_resp {/* * REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response) +* +* See details under "TXPOWER" in iwl-4965-hw.h. */ struct iwl4965_txpowertable_cmd {u8 band;/* 0: 5 GHz, 1: 2.4 GHz */
@@ -1333,39 +1335,280 @@ struct iwl4965_txpowertable_cmd {/*RS_NEW_API: only TLC_RTS remains and moved to bit 0 */ #define LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK (1<<0) +/* # of EDCA prioritized tx fifos */ #define LINK_QUAL_AC_NUM AC_NUM + +/* # entries in rate scale table to support Tx retries */ #define LINK_QUAL_MAX_RETRY_NUM 16 +/* Tx antenna selection values */ #define LINK_QUAL_ANT_A_MSK (1<<0)#define LINK_QUAL_ANT_B_MSK (1<<1)#define LINK_QUAL_ANT_MSK (LINK_QUAL_ANT_A_MSK|LINK_QUAL_ANT_B_MSK) + +/** +* struct iwl4965_link_qual_general_params +* +* Used in REPLY_TX_LINK_QUALITY_CMD +*/ struct iwl4965_link_qual_general_params {u8 flags; + +/* No entries at or above this (driver chosen) index contain MIMO */ u8 mimo_delimiter; -u8 single_stream_ant_msk; -u8 dual_stream_ant_msk; + +/* Best single antenna to use for single stream (legacy, SISO). */ +u8 single_stream_ant_msk;/* LINK_QUAL_ANT_* */ + +/* Best antennas to use for MIMO (unused for 4965, assumes both). */ +u8 dual_stream_ant_msk;/* LINK_QUAL_ANT_* */ + +/* +* If driver needs to use different initial rates for different +* EDCA QOS access categories (as implemented by tx fifos 0-3), +* this table will set that up, by indicating the indexes in the +* rs_table[LINK_QUAL_MAX_RETRY_NUM] rate table at which to start. +* Otherwise, driver should set all entries to 0. +* +* Entry usage: +* 0 = Background, 1 = Best Effort (normal), 2 = Video, 3 = Voice +* TX FIFOs above 3 use same value (typically 0) as TX FIFO 3. +*/ u8 start_rate_index[LINK_QUAL_AC_NUM ]; } __attribute__ ((packed)); +/** +* struct iwl4965_link_qual_agg_params +* +* Used in REPLY_TX_LINK_QUALITY_CMD +*/ struct iwl4965_link_qual_agg_params { + +/* Maximum number of uSec in aggregation. +* Driver should set this to 4000 (4 milliseconds). */ __le16 agg_time_limit; + +/* +* Number of Tx retries allowed for a frame, before that frame will +* no longer be considered for the start of an aggregation sequence +* (scheduler will then try to tx it as single frame). +* Driver should set this to 3. +*/ u8 agg_dis_start_th; + +/* +* Maximum number of frames in aggregation. +* 0 = no limit (default). 1 = no aggregation. +* Other values = max # frames in aggregation. +*/ u8 agg_frame_cnt_limit; +__le32 reserved; } __attribute__ ((packed));/* * REPLY_TX_LINK_QUALITY_CMD = 0x4e (command, has simple generic response) +* +* For 4965 only; 3945 uses REPLY_RATE_SCALE. +* +* Each station in the 4965's internal station table has its own table of 16 +* Tx rates and modulation modes (e.g. legacy/SISO/MIMO) for retrying Tx when +* an ACK is not received. This command replaces the entire table for +* one station. +* +* NOTE: Station must already be in 4965's station table. Use REPLY_ADD_STA. +* +* The rate scaling procedures described below work well. Of course, other +* procedures are possible, and may work better for particular environments. +* +* +* FILLING THE RATE TABLE +* +* Given a particular initial rate and mode, as determined by the rate +* scaling algorithm described below, the Linux driver uses the following +* formula to fill the rs_table[LINK_QUAL_MAX_RETRY_NUM] rate table in the +* Link Quality command: +* +* +* 1) If using High-throughput (HT) (SISO or MIMO) initial rate: +* a) Use this same initial rate for first 3 entries. +* b) Find next lower available rate using same mode (SISO or MIMO), +* use for next 3 entries. If no lower rate available, switch to +* legacy mode (no FAT channel, no MIMO, no short guard interval). +* c) If using MIMO, set command's mimo_delimiter to number of entries +* using MIMO (3 or 6). +* d) After trying 2 HT rates, switch to legacy mode (no FAT channel, +* no MIMO, no short guard interval), at the next lower bit rate +* (e.g. if second HT bit rate was 54, try 48 legacy), and follow +* legacy procedure for remaining table entries. +* +* 2) If using legacy initial rate: +* a) Use the initial rate for only one entry. +* b) For each following entry, reduce the rate to next lower available +* rate, until reaching the lowest available rate. +* c) When reducing rate, also switch antenna selection. +* d) Once lowest available rate is reached, repeat this rate until +* rate table is filled (16 entries), switching antenna each entry. +* +* +* ACCUMULATING HISTORY +* +* The rate scaling algorithm for 4965, as implemented in Linux driver, uses +* two sets of frame Tx success history: One for the current/active modulation +* mode, and one for a speculative/search mode that is being attempted. If the +* speculative mode turns out to be more effective (i.e. actual transfer +* rate is better), then the driver continues to use the speculative mode +* as the new current active mode. +* +* Each history set contains, separately for each possible rate, data for a +* sliding window of the 62 most recent tx attempts at that rate. The data +* includes a shifting bitmap of success(1)/failure(0), and sums of successful +* and attempted frames, from which the driver can additionally calculate a +* success ratio (success / attempted) and number of failures +* (attempted - success), and control the size of the window (attempted). +* The driver uses the bit map to remove successes from the success sum, as +* the oldest tx attempts fall out of the window. +* +* When the 4965 makes multiple tx attempts for a given frame, each attempt +* might be at a different rate, and have different modulation characteristics +* (e.g. antenna, fat channel, short guard interval), as set up in the rate +* scaling table in the Link Quality command. The driver must determine +* which rate table entry was used for each tx attempt, to determine which +* rate-specific history to update, and record only those attempts that +* match the modulation characteristics of the history set. +* +* When using block-ack (aggregation), all frames are transmitted at the same +* rate, since there is no per-attempt acknowledgement from the destination +* station. The Tx response struct iwl_tx_resp indicates the Tx rate in +* rate_n_flags field. After receiving a block-ack, the driver can update +* history for the entire block all at once. +* +* +* FINDING BEST STARTING RATE: +* +* When working with a selected initial modulation mode (see below), the +* driver attempts to find a best initial rate. The initial rate is the +* first entry in the Link Quality command's rate table. +* +* 1) Calculate actual throughput (success ratio * expected throughput, see +* table below) for current initial rate. Do this only if enough frames +* have been attempted to make the value meaningful: at least 6 failed +* tx attempts, or at least 8 successes. If not enough, don't try rate +* scaling yet. +* +* 2) Find available rates adjacent to current initial rate. Available means: +* a) supported by hardware && +* b) supported by association && +* c) within any constraints selected by user +* +* 3) Gather measured throughputs for adjacent rates. These might not have +* enough history to calculate a throughput. That's okay, we might try +* using one of them anyway! +* +* 4) Try decreasing rate if, for current rate: +* a) success ratio is < 15% || +* b) lower adjacent rate has better measured throughput || +* c) higher adjacent rate has worse throughput, and lower is unmeasured +* +* As a sanity check, if decrease was determined above, leave rate +* unchanged if: +* a) lower rate unavailable +* b) success ratio at current rate > 85% (very good) +* c) current measured throughput is better than expected throughput +* of lower rate (under perfect 100% tx conditions, see table below) +* +* 5) Try increasing rate if, for current rate: +* a) success ratio is < 15% || +* b) both adjacent rates' throughputs are unmeasured (try it!) || +* b) higher adjacent rate has better measured throughput || +* c) lower adjacent rate has worse throughput, and higher is unmeasured +* +* As a sanity check, if increase was determined above, leave rate +* unchanged if: +* a) success ratio at current rate < 70%. This is not particularly +* good performance; higher rate is sure to have poorer success. +* +* 6) Re-evaluate the rate after each tx frame. If working with block- +* acknowledge, history and statistics may be calculated for the entire +* block (including prior history that fits within the history windows), +* before re-evaluation. +* +* FINDING BEST STARTING MODULATION MODE: +* +* After working with a modulation mode for a "while" (and doing rate scaling), +* the driver searches for a new initial mode in an attempt to improve +* throughput. The "while" is measured by numbers of attempted frames: +* +* For legacy mode, search for new mode after: +* 480 successful frames, or 160 failed frames +* For high-throughput modes (SISO or MIMO), search for new mode after: +* 4500 successful frames, or 400 failed frames +* +* Mode switch possibilities are (3 for each mode): +* +* For legacy: +* Change antenna, try SISO (if HT association), try MIMO (if HT association) +* For SISO: +* Change antenna, try MIMO, try shortened guard interval (SGI) +* For MIMO: +* Try SISO antenna A, SISO antenna B, try shortened guard interval (SGI) +* +* When trying a new mode, use the same bit rate as the old/current mode when +* trying antenna switches and shortened guard interval. When switching to +* SISO from MIMO or legacy, or to MIMO from SISO or legacy, use a rate +* for which the expected throughput (under perfect conditions) is about the +* same or slightly better than the actual measured throughput delivered by +* the old/current mode. +* +* Actual throughput can be estimated by multiplying the expected throughput +* by the success ratio (successful / attempted tx frames). Frame size is +* not considered in this calculation; it assumes that frame size will average +* out to be fairly consistent over several samples. The following are +* metric values for expected throughput assuming 100% success ratio. +* Only G band has support for CCK rates: +* +* RATE: 1 2 5 11 6 9 12 18 24 36 48 54 60 +* +* G: 7 13 35 58 40 57 72 98 121 154 177 186 186 +* A: 0 0 0 0 40 57 72 98 121 154 177 186 186 +* SISO 20MHz: 0 0 0 0 42 42 76 102 124 159 183 193 202 +* SGI SISO 20MHz: 0 0 0 0 46 46 82 110 132 168 192 202 211 +* MIMO 20MHz: 0 0 0 0 74 74 123 155 179 214 236 244 251 +* SGI MIMO 20MHz: 0 0 0 0 81 81 131 164 188 222 243 251 257 +* SISO 40MHz: 0 0 0 0 77 77 127 160 184 220 242 250 257 +* SGI SISO 40MHz: 0 0 0 0 83 83 135 169 193 229 250 257 264 +* MIMO 40MHz: 0 0 0 0 123 123 182 214 235 264 279 285 289 +* SGI MIMO 40MHz: 0 0 0 0 131 131 191 222 242 270 284 289 293 +* +* After the new mode has been tried for a short while (minimum of 6 failed +* frames or 8 successful frames), compare success ratio and actual throughput +* estimate of the new mode with the old. If either is better with the new +* mode, continue to use the new mode. +* +* Continue comparing modes until all 3 possibilities have been tried. +* If moving from legacy to HT, try all 3 possibilities from the new HT +* mode. After trying all 3, a best mode is found. Continue to use this mode +* for the longer "while" described above (e.g. 480 successful frames for +* legacy), and then repeat the search process. +* */ struct iwl4965_link_quality_cmd { + +/* Index of destination/recipient station in uCode's station table */ u8 sta_id;u8 reserved1; -__le16 control; +__le16 control;/* not used */ struct iwl4965_link_qual_general_params general_params;struct iwl4965_link_qual_agg_params agg_params; + +/* +* Rate info; when using rate-scaling, Tx command's initial_rate_index +* specifies 1st Tx rate attempted, via index into this table. +* 4965 works its way through table when retrying Tx. +*/ struct { -__le32 rate_n_flags; +__le32 rate_n_flags;/* RATE_MCS_*, IWL_RATE_* */ } rs_table[LINK_QUAL_MAX_RETRY_NUM ];__le32 reserved2; } __attribute__ ((packed));
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 31/34 iwlwifi: enhance WPA authenication stability
From: Mohamed Abbas <[email protected]>
This patch enhanced WPA authenication stability by avoiding scan immediately followed by association. We don't do any scanning right after association in next several seconds. This will allow WPA authentication to take place without any interruption.
--- drivers/net/wireless/iwlwifi/iwl-3945.c | 9 +++++++++ drivers/net/wireless/iwlwifi/iwl-3945.h | 1 + drivers/net/wireless/iwlwifi/iwl-4965.c | 8 ++++++++ drivers/net/wireless/iwlwifi/iwl-4965.h | 1 + drivers/net/wireless/iwlwifi/iwl3945-base.c | 24 +++++++++++++++++------- drivers/net/wireless/iwlwifi/iwl4965-base.c | 24 +++++++++++++++++------- 6 files changed, 53 insertions(+), 14 deletions(-)
drivers/net/wireless/iwlwifi/iwl-3945.c +9 -0
@@ -285,6 +285,8 @@ static void iwl3945_handle_data_packet(struct iwl3945_priv *priv, int is_data, rxb->skb =NULL ; } +#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) +static void iwl3945_rx_reply_rx (struct iwl3945_priv *priv,struct iwl3945_rx_mem_buffer *rxb) {
@@ -442,6 +444,13 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,case IEEE80211_STYPE_REASSOC_RESP :{struct ieee80211_mgmt *mgnt = (struct ieee80211_mgmt *)header; + +/* We have just associated, give some +* time for the 4-way handshake if +* any. Don't start scan too early. */ + priv->next_scan_jiffies = jiffies + +IWL_DELAY_NEXT_SCAN_AFTER_ASSOC ; + priv->assoc_id = (~((1 <<15 ) | (1 <<14 )) &le16_to_cpu (mgnt->u. assoc_resp.aid));
drivers/net/wireless/iwlwifi/iwl-3945.h +1 -0
@@ -754,6 +754,7 @@ struct iwl3945_priv {/* Scan related variables */ unsigned long last_scan_jiffies; +unsigned long next_scan_jiffies;unsigned long scan_start;unsigned long scan_pass_start;unsigned long scan_start_tsf;
drivers/net/wireless/iwlwifi/iwl-4965.c +8 -0
@@ -3840,6 +3840,8 @@ static void iwl4965_update_ps_mode(struct iwl4965_priv *priv, u16 ps_bit, u8 *ad } } +#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) +/* Called for REPLY_4965_RX (legacy ABG frames), or * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
@@ -4011,6 +4013,12 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,struct ieee80211_mgmt *mgnt = (struct ieee80211_mgmt *)header; +/* We have just associated, give some +* time for the 4-way handshake if +* any. Don't start scan too early. */ + priv->next_scan_jiffies = jiffies + +IWL_DELAY_NEXT_SCAN_AFTER_ASSOC ; + priv->assoc_id = (~((1 <<15 ) | (1 <<14 )) &le16_to_cpu (mgnt->u.assoc_resp.aid)); priv->assoc_capability =
drivers/net/wireless/iwlwifi/iwl-4965.h +1 -0
@@ -1085,6 +1085,7 @@ struct iwl4965_priv {/* Scan related variables */ unsigned long last_scan_jiffies; +unsigned long next_scan_jiffies;unsigned long scan_start;unsigned long scan_pass_start;unsigned long scan_start_tsf;
drivers/net/wireless/iwlwifi/iwl3945-base.c +17 -7
@@ -2800,7 +2800,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,IWL_DEBUG_TX ("Sending REASSOC frame\n" );#endif -if (!iwl3945_is_associated (priv) && +/* drop all data frame if we are not associated */ +if (!iwl3945_is_associated (priv) && !priv->assoc_id && ((fc &IEEE80211_FCTL_FTYPE ) ==IEEE80211_FTYPE_DATA )) {IWL_DEBUG_DROP ("Dropping - !iwl3945_is_associated\n" ); goto drop_unlock;
@@ -3737,6 +3738,7 @@ static void iwl3945_rx_scan_results_notif(struct iwl3945_priv *priv, (priv->last_scan_jiffies, jiffies))); priv->last_scan_jiffies = jiffies; + priv->next_scan_jiffies =0 ; }/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
@@ -3779,6 +3781,7 @@ static void iwl3945_rx_scan_complete_notif(struct iwl3945_priv *priv, } priv->last_scan_jiffies = jiffies; + priv->next_scan_jiffies =0 ;IWL_DEBUG_INFO ("Setting scan to off\n" );clear_bit (STATUS_SCANNING , &priv->status);
@@ -6798,6 +6801,8 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)mutex_unlock (&priv->mutex); } +#define IWL_DELAY_NEXT_SCAN (HZ*2) +static void iwl3945_bg_post_associate (struct work_struct *data) { struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv,
@@ -6898,6 +6903,8 @@ static void iwl3945_bg_post_associate(struct work_struct *data)#ifdef CONFIG_IWL3945_QOS iwl3945_activate_qos (priv,0 );#endif /* CONFIG_IWL3945_QOS */ +/* we have just associated, don't start scan too early */ + priv->next_scan_jiffies = jiffies +IWL_DELAY_NEXT_SCAN ;mutex_unlock (&priv->mutex); }
@@ -7352,7 +7359,6 @@ static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw, } -#define IWL_DELAY_NEXT_SCAN (HZ*2)static int iwl3945_mac_hw_scan (struct ieee80211_hw *hw,u8 *ssid,size_t len) {int rc =0 ;
@@ -7376,16 +7382,20 @@ static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) goto out_unlock; } +/* we don't schedule scan within next_scan_jiffies period */ +if (priv->next_scan_jiffies && +time_after (priv->next_scan_jiffies, jiffies)) { + rc = -EAGAIN ; + goto out_unlock; + }/* if we just finished scan ask for delay */ -if (priv->last_scan_jiffies && -time_after (priv->last_scan_jiffies +IWL_DELAY_NEXT_SCAN , - jiffies)) { +if (priv->last_scan_jiffies &&time_after (priv->last_scan_jiffies + +IWL_DELAY_NEXT_SCAN , jiffies)) { rc = -EAGAIN ; goto out_unlock; }if (len) { -IWL_DEBUG_SCAN ("direct scan for " -"%s [%d]\n " , +IWL_DEBUG_SCAN ("direct scan for %s [%d]\n " ,iwl3945_escape_essid (ssid, len), (int )len); priv->one_direct_scan =1 ;
drivers/net/wireless/iwlwifi/iwl4965-base.c +17 -7
@@ -2921,7 +2921,8 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv,IWL_DEBUG_TX ("Sending REASSOC frame\n" );#endif -if (!iwl4965_is_associated (priv) && +/* drop all data frame if we are not associated */ +if (!iwl4965_is_associated (priv) && !priv->assoc_id && ((fc &IEEE80211_FCTL_FTYPE ) ==IEEE80211_FTYPE_DATA )) {IWL_DEBUG_DROP ("Dropping - !iwl4965_is_associated\n" ); goto drop_unlock;
@@ -4071,6 +4072,7 @@ static void iwl4965_rx_scan_results_notif(struct iwl4965_priv *priv, (priv->last_scan_jiffies, jiffies))); priv->last_scan_jiffies = jiffies; + priv->next_scan_jiffies =0 ; }/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
@@ -4113,6 +4115,7 @@ static void iwl4965_rx_scan_complete_notif(struct iwl4965_priv *priv, } priv->last_scan_jiffies = jiffies; + priv->next_scan_jiffies =0 ;IWL_DEBUG_INFO ("Setting scan to off\n" );clear_bit (STATUS_SCANNING , &priv->status);
@@ -7230,6 +7233,8 @@ static void iwl4965_bg_rx_replenish(struct work_struct *data)mutex_unlock (&priv->mutex); } +#define IWL_DELAY_NEXT_SCAN (HZ*2) +static void iwl4965_bg_post_associate (struct work_struct *data) { struct iwl4965_priv *priv = container_of(data, struct iwl4965_priv,
@@ -7340,6 +7345,8 @@ static void iwl4965_bg_post_associate(struct work_struct *data)#ifdef CONFIG_IWL4965_QOS iwl4965_activate_qos (priv,0 );#endif /* CONFIG_IWL4965_QOS */ +/* we have just associated, don't start scan too early */ + priv->next_scan_jiffies = jiffies +IWL_DELAY_NEXT_SCAN ;mutex_unlock (&priv->mutex); }
@@ -7830,7 +7837,6 @@ static void iwl4965_mac_erp_ie_changed(struct ieee80211_hw *hw,iwl4965_send_rxon_assoc (priv); } -#define IWL_DELAY_NEXT_SCAN (HZ*2)static int iwl4965_mac_hw_scan (struct ieee80211_hw *hw,u8 *ssid,size_t len) {int rc =0 ;
@@ -7854,16 +7860,20 @@ static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) goto out_unlock; } +/* we don't schedule scan within next_scan_jiffies period */ +if (priv->next_scan_jiffies && +time_after (priv->next_scan_jiffies, jiffies)) { + rc = -EAGAIN ; + goto out_unlock; + }/* if we just finished scan ask for delay */ -if (priv->last_scan_jiffies && -time_after (priv->last_scan_jiffies +IWL_DELAY_NEXT_SCAN , - jiffies)) { +if (priv->last_scan_jiffies &&time_after (priv->last_scan_jiffies + +IWL_DELAY_NEXT_SCAN , jiffies)) { rc = -EAGAIN ; goto out_unlock; }if (len) { -IWL_DEBUG_SCAN ("direct scan for " -"%s [%d]\n " , +IWL_DEBUG_SCAN ("direct scan for %s [%d]\n " ,iwl4965_escape_essid (ssid, len), (int )len); priv->one_direct_scan =1 ;
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 32/34 iwlwifi: fix ucode assertion for RX queue overrun
From: Mohamed Abbas <[email protected]>
This patch allows the driver to restock the RX queue early if the RX queue is almost empty. This will help on avoiding any ucode assert for the RX overrun problem.
--- drivers/net/wireless/iwlwifi/iwl3945-base.c | 37 ++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl4965-base.c | 38 +++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 4 deletions(-)
drivers/net/wireless/iwlwifi/iwl3945-base.c +35 -2
@@ -4123,9 +4123,8 @@ static int iwl3945_rx_queue_restock(struct iwl3945_priv *priv)* Also restock the Rx queue via iwl3945_rx_queue_restock. * This is called as a scheduled work item (except for during initialization) */ -void iwl3945_rx_replenish (void *data) +static void iwl3945_rx_allocate (struct iwl3945_priv *priv) { -struct iwl3945_priv *priv = data;struct iwl3945_rx_queue *rxq = &priv->rxq;struct list_head *element;struct iwl3945_rx_mem_buffer *rxb;
@@ -4158,6 +4157,26 @@ void iwl3945_rx_replenish(void *data) rxq->free_count++; }spin_unlock_irqrestore (&rxq->lock, flags); +} + +/* +* this should be called while priv->lock is locked +*/ +static void __iwl3945_rx_replenish (void *data) +{ +struct iwl3945_priv *priv = data; + +iwl3945_rx_allocate (priv); +iwl3945_rx_queue_restock (priv); +} + + +void iwl3945_rx_replenish (void *data) +{ +struct iwl3945_priv *priv = data; +unsigned long flags; + +iwl3945_rx_allocate (priv);spin_lock_irqsave (&priv->lock, flags);iwl3945_rx_queue_restock (priv);
@@ -4335,12 +4354,16 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)u32 r, i;int reclaim;unsigned long flags; +u8 fill_rx =0 ; +u32 count =0 ;/* uCode's read index (stored in shared DRAM) indicates the last Rx * buffer that the driver may process (last buffer filled by ucode). */ r =iwl3945_hw_get_rx_read (priv); i = rxq->read; +if (iwl3945_rx_queue_space (rxq) > (RX_QUEUE_SIZE /2 )) + fill_rx =1 ;/* Rx interrupt, but nothing sent from uCode */ if (i == r)IWL_DEBUG (IWL_DL_RX |IWL_DL_ISR ,"r = %d, i = %d\n" , r, i);
@@ -4411,6 +4434,16 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)list_add_tail (&rxb->list, &priv->rxq.rx_used);spin_unlock_irqrestore (&rxq->lock, flags); i = (i +1 ) &RX_QUEUE_MASK ; +/* If there are a lot of unused frames, +* restock the Rx queue so ucode won't assert. */ +if (fill_rx) { + count++; +if (count >=8 ) { + priv->rxq.read = i; +__iwl3945_rx_replenish (priv); + count =0 ; + } + } }/* Backtrack one entry */
drivers/net/wireless/iwlwifi/iwl4965-base.c +36 -2
@@ -4493,9 +4493,8 @@ static int iwl4965_rx_queue_restock(struct iwl4965_priv *priv)* Also restock the Rx queue via iwl4965_rx_queue_restock. * This is called as a scheduled work item (except for during initialization) */ -void iwl4965_rx_replenish (void *data) +static void iwl4965_rx_allocate (struct iwl4965_priv *priv) { -struct iwl4965_priv *priv = data;struct iwl4965_rx_queue *rxq = &priv->rxq;struct list_head *element;struct iwl4965_rx_mem_buffer *rxb;
@@ -4529,6 +4528,26 @@ void iwl4965_rx_replenish(void *data) rxq->free_count++; }spin_unlock_irqrestore (&rxq->lock, flags); +} + +/* +* this should be called while priv->lock is locked +*/ +static void __iwl4965_rx_replenish (void *data) +{ +struct iwl4965_priv *priv = data; + +iwl4965_rx_allocate (priv); +iwl4965_rx_queue_restock (priv); +} + + +void iwl4965_rx_replenish (void *data) +{ +struct iwl4965_priv *priv = data; +unsigned long flags; + +iwl4965_rx_allocate (priv);spin_lock_irqsave (&priv->lock, flags);iwl4965_rx_queue_restock (priv);
@@ -4708,6 +4727,8 @@ static void iwl4965_rx_handle(struct iwl4965_priv *priv)u32 r, i;int reclaim;unsigned long flags; +u8 fill_rx =0 ; +u32 count =0 ;/* uCode's read index (stored in shared DRAM) indicates the last Rx * buffer that the driver may process (last buffer filled by ucode). */
@@ -4718,6 +4739,9 @@ static void iwl4965_rx_handle(struct iwl4965_priv *priv)if (i == r)IWL_DEBUG (IWL_DL_RX |IWL_DL_ISR ,"r = %d, i = %d\n" , r, i); +if (iwl4965_rx_queue_space (rxq) > (RX_QUEUE_SIZE /2 )) + fill_rx =1 ; +while (i != r) { rxb = rxq->queue[i];
@@ -4788,6 +4812,16 @@ static void iwl4965_rx_handle(struct iwl4965_priv *priv)list_add_tail (&rxb->list, &priv->rxq.rx_used);spin_unlock_irqrestore (&rxq->lock, flags); i = (i +1 ) &RX_QUEUE_MASK ; +/* If there are a lot of unused frames, +* restock the Rx queue so ucode wont assert. */ +if (fill_rx) { + count++; +if (count >=8 ) { + priv->rxq.read = i; +__iwl4965_rx_replenish (priv); + count =0 ; + } + } }/* Backtrack one entry */
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 33/34 iwlwifi: avoid firmware command sending if rfkill is enabled
From: Mohamed Abbas <[email protected]>
This patch fixed a ucode timeout issue and worked code with suspend to disk.
--- drivers/net/wireless/iwlwifi/iwl3945-base.c | 54 ++++++++++++++++---------- drivers/net/wireless/iwlwifi/iwl4965-base.c | 54 ++++++++++++++++---------- 2 files changed, 66 insertions(+), 42 deletions(-)
drivers/net/wireless/iwlwifi/iwl3945-base.c +33 -21
@@ -2546,9 +2546,6 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv)static int iwl3945_set_mode (struct iwl3945_priv *priv,int mode) { -if (!iwl3945_is_ready_rf (priv)) -return -EAGAIN ; -if (mode ==IEEE80211_IF_TYPE_IBSS ) {const struct iwl3945_channel_info *ch_info;
@@ -2563,13 +2560,6 @@ static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode) } } -cancel_delayed_work (&priv->scan_check); -if (iwl3945_scan_cancel_timeout (priv,100 )) { -IWL_WARNING ("Aborted scan still in progress after 100ms\n" ); -IWL_DEBUG_MAC80211 ("leaving - scan abort failed.\n" ); -return -EAGAIN ; - } - priv->iw_mode = mode;iwl3945_connection_init_rx_config (priv);
@@ -2577,6 +2567,17 @@ static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode)iwl3945_clear_stations_table (priv); +/* dont commit rxon if rf-kill is on*/ +if (!iwl3945_is_ready_rf (priv)) +return -EAGAIN ; + +cancel_delayed_work (&priv->scan_check); +if (iwl3945_scan_cancel_timeout (priv,100 )) { +IWL_WARNING ("Aborted scan still in progress after 100ms\n" ); +IWL_DEBUG_MAC80211 ("leaving - scan abort failed.\n" ); +return -EAGAIN ; + } +iwl3945_commit_rxon (priv);return 0 ;
@@ -7017,6 +7018,12 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw)* RXON_FILTER_ASSOC_MSK BIT */ priv->is_open =0 ; +if (!iwl3945_is_ready_rf (priv)) { +IWL_DEBUG_MAC80211 ("leave - RF not ready\n" ); +mutex_unlock (&priv->mutex); +return ; + } +iwl3945_scan_cancel_timeout (priv,100 );cancel_delayed_work (&priv->post_associate); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK ;
@@ -7305,6 +7312,9 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, int if_id, priv->ibss_beacon = conf->beacon; } +if (iwl3945_is_rfkill (priv)) + goto done; +if (conf->bssid && !is_zero_ether_addr (conf->bssid) && !is_multicast_ether_addr (conf->bssid)) {/* If there is currently a HW scan going on in the background
@@ -7339,6 +7349,7 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, int if_id,iwl3945_commit_rxon (priv); } + done:spin_lock_irqsave (&priv->lock, flags);if (!conf->ssid_len)memset (priv->essid,0 ,IW_ESSID_MAX_SIZE );
@@ -7375,11 +7386,12 @@ static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw,mutex_lock (&priv->mutex); -iwl3945_scan_cancel_timeout (priv,100 ); -cancel_delayed_work (&priv->post_associate); - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK ; -iwl3945_commit_rxon (priv); - +if (iwl3945_is_ready_rf (priv)) { +iwl3945_scan_cancel_timeout (priv,100 ); +cancel_delayed_work (&priv->post_associate); + priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK ; +iwl3945_commit_rxon (priv); + }if (priv->interface_id == conf->if_id) { priv->interface_id =0 ;memset (priv->bssid,0 ,ETH_ALEN );
@@ -7650,6 +7662,12 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)spin_unlock_irqrestore (&priv->lock, flags); +if (!iwl3945_is_ready_rf (priv)) { +IWL_DEBUG_MAC80211 ("leave - not ready\n" ); +mutex_unlock (&priv->mutex); +return ; + } +/* we are restarting association process * clear RXON_FILTER_ASSOC_MSK bit */
@@ -7667,12 +7685,6 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)return ; } -if (!iwl3945_is_ready_rf (priv)) { -IWL_DEBUG_MAC80211 ("leave - not ready\n" ); -mutex_unlock (&priv->mutex); -return ; - } - priv->only_active_channel =0 ;iwl3945_set_rate (priv);
drivers/net/wireless/iwlwifi/iwl4965-base.c +33 -21
108 lines not on this page · raw message
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v2 34/34 iwlwifi: update version number to 1.2.22
From: Zhu Yi <[email protected]>
--- drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 +- drivers/net/wireless/iwlwifi/iwl4965-base.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/iwlwifi/iwl3945-base.c +1 -1
@@ -91,7 +91,7 @@ int iwl3945_param_queues_num = IWL_MAX_NUM_QUEUES; /* def: 8 Tx queues */#define VS #endif -#define IWLWIFI_VERSION "1.1.19k" VD VS +#define IWLWIFI_VERSION "1.2.22k" VD VS#define DRV_COPYRIGHT "Copyright(c) 2003-2007 Intel Corporation"#define DRV_VERSION IWLWIFI_VERSION
drivers/net/wireless/iwlwifi/iwl4965-base.c +1 -1
@@ -91,7 +91,7 @@ int iwl4965_param_amsdu_size_8K; /* def: enable 8K amsdu size */#define VS #endif -#define IWLWIFI_VERSION "1.1.19k" VD VS +#define IWLWIFI_VERSION "1.2.22k" VD VS#define DRV_COPYRIGHT "Copyright(c) 2003-2007 Intel Corporation"#define DRV_VERSION IWLWIFI_VERSION
Signature · 8 lines
1.5.2.2 --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.