rpms/kernel/devel linux-2.6-iwlwifi-fixes.patch, NONE, 1.1 kernel.spec, 1.194, 1.195 linux-2.6-ath5k.patch, 1.1, 1.2

John W. Linville (linville) fedora-extras-commits at redhat.com
Thu Sep 27 23:49:43 UTC 2007


Author: linville

Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv32737

Modified Files:
	kernel.spec linux-2.6-ath5k.patch 
Added Files:
	linux-2.6-iwlwifi-fixes.patch 
Log Message:
A few iwlwifi and ath5k fixes

linux-2.6-iwlwifi-fixes.patch:

--- NEW FILE linux-2.6-iwlwifi-fixes.patch ---
diff -up linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-4965-rs.c.orig linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
--- linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-4965-rs.c.orig	2007-09-27 19:08:16.000000000 -0400
+++ linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-4965-rs.c	2007-09-27 19:09:01.000000000 -0400
@@ -115,24 +115,38 @@ struct iwl_rate_scale_priv {
 	u8 is_dup;
 	u8 phymode;
 	u8 ibss_sta_added;
+	u32 supp_rates;
 	u16 active_rate;
 	u16 active_siso_rate;
 	u16 active_mimo_rate;
 	u16 active_rate_basic;
 	struct iwl_link_quality_cmd lq;
 	struct iwl_scale_tbl_info lq_info[LQ_SIZE];
+#ifdef CONFIG_MAC80211_DEBUGFS
+	struct dentry *rs_sta_dbgfs_scale_table_file;
+	struct dentry *rs_sta_dbgfs_stats_table_file;
+	struct iwl_rate dbg_fixed;
+	struct iwl_priv *drv;
+#endif
 };
 
 static void rs_rate_scale_perform(struct iwl_priv *priv,
 				   struct net_device *dev,
 				   struct ieee80211_hdr *hdr,
 				   struct sta_info *sta);
-static int rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data,
+static void rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data,
 			     struct iwl_rate *tx_mcs,
-			     struct iwl_link_quality_cmd *tbl,
-			     struct sta_info *sta);
+			     struct iwl_link_quality_cmd *tbl);
 
 
+#ifdef CONFIG_MAC80211_DEBUGFS
+static void rs_dbgfs_set_mcs(struct iwl_rate_scale_priv *rs_priv,
+				struct iwl_rate *mcs, int index);
+#else
+static void rs_dbgfs_set_mcs(struct iwl_rate_scale_priv *rs_priv,
+				struct iwl_rate *mcs, int index)
+{}
+#endif
 static s32 expected_tpt_A[IWL_RATE_COUNT] = {
 	0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186, 186
 };
@@ -539,14 +553,13 @@ static u16 rs_get_adjacent_rate(u8 index
 
 static int rs_get_lower_rate(struct iwl_rate_scale_priv *lq_data,
 			     struct iwl_scale_tbl_info *tbl, u8 scale_index,
-			     u8 ht_possible, struct iwl_rate *mcs_rate,
-			     struct sta_info *sta)
+			     u8 ht_possible, struct iwl_rate *mcs_rate)
 {
-	u8 is_green = lq_data->is_green;
 	s32 low;
 	u16 rate_mask;
 	u16 high_low;
 	u8 switch_to_legacy = 0;
+	u8 is_green = lq_data->is_green;
 
 	/* check if we need to switch from HT to legacy rates.
 	 * assumption is that mandatory rates (1Mbps or 6Mbps)
@@ -573,9 +586,9 @@ static int rs_get_lower_rate(struct iwl_
 	if (is_legacy(tbl->lq_type)) {
 		if (lq_data->phymode == (u8) MODE_IEEE80211A)
 			rate_mask  = (u16)(rate_mask &
-			   (sta->supp_rates << IWL_FIRST_OFDM_RATE));
+			   (lq_data->supp_rates << IWL_FIRST_OFDM_RATE));
 		else
-			rate_mask = (u16)(rate_mask & sta->supp_rates);
+			rate_mask = (u16)(rate_mask & lq_data->supp_rates);
 	}
 
 	/* if we did switched from HT to legacy check current rate */
@@ -619,7 +632,7 @@ static void rs_tx_status(void *priv_rate
 	u16 fc = le16_to_cpu(hdr->frame_control);
 	s32 tpt = 0;
 
-	IWL_DEBUG_RATE("get frame ack response, update rate scale window\n");
+	IWL_DEBUG_RATE_LIMIT("get frame ack response, update rate scale window\n");
 
 	if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1))
 		return;
@@ -1388,10 +1401,10 @@ static void rs_rate_scale_perform(struct
 	if (is_legacy(tbl->lq_type)) {
 		if (lq_data->phymode == (u8) MODE_IEEE80211A)
 			rate_scale_index_msk = (u16) (rate_mask &
-				(sta->supp_rates << IWL_FIRST_OFDM_RATE));
+				(lq_data->supp_rates << IWL_FIRST_OFDM_RATE));
 		else
 			rate_scale_index_msk = (u16) (rate_mask &
-						      sta->supp_rates);
+						      lq_data->supp_rates);
 
 	} else
 		rate_scale_index_msk = rate_mask;
@@ -1431,7 +1444,7 @@ static void rs_rate_scale_perform(struct
 		rs_stay_in_table(lq_data);
 		if (update_lq) {
 			rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green);
-			rs_fill_link_cmd(lq_data, &mcs_rate, &lq_data->lq, sta);
+			rs_fill_link_cmd(lq_data, &mcs_rate, &lq_data->lq);
 			rs_send_lq_cmd(priv, &lq_data->lq, CMD_ASYNC);
 		}
 		goto out;
@@ -1555,7 +1568,7 @@ static void rs_rate_scale_perform(struct
  lq_update:
 	if (update_lq) {
 		rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green);
-		rs_fill_link_cmd(lq_data, &mcs_rate, &lq_data->lq, sta);
+		rs_fill_link_cmd(lq_data, &mcs_rate, &lq_data->lq);
 		rs_send_lq_cmd(priv, &lq_data->lq, CMD_ASYNC);
 	}
 	rs_stay_in_table(lq_data);
@@ -1581,7 +1594,7 @@ static void rs_rate_scale_perform(struct
 			IWL_DEBUG_HT("Switch current  mcs: %X index: %d\n",
 				     tbl->current_rate.rate_n_flags, index);
 			rs_fill_link_cmd(lq_data, &tbl->current_rate,
-					 &(lq_data->lq), sta);
+					 &lq_data->lq);
 			rs_send_lq_cmd(priv, &lq_data->lq, CMD_ASYNC);
 		}
 		tbl1 = &(lq_data->lq_info[lq_data->active_tbl]);
@@ -1672,12 +1685,12 @@ static void rs_initialize_lq(struct iwl_
 	tbl->antenna_type = ANT_AUX;
 	rs_get_tbl_info_from_mcs(&mcs_rate, priv->phymode, tbl, &rate_idx);
 	if (!rs_is_ant_connected(priv->valid_antenna, tbl->antenna_type))
-	    rs_toggle_antenna(&mcs_rate, tbl),
+	    rs_toggle_antenna(&mcs_rate, tbl);
 
 	rs_mcs_from_tbl(&mcs_rate, tbl, rate_idx, use_green);
 	tbl->current_rate.rate_n_flags = mcs_rate.rate_n_flags;
 	rs_get_expected_tpt_table(lq, tbl);
-	rs_fill_link_cmd(lq, &mcs_rate, &(lq->lq), sta);
+	rs_fill_link_cmd(lq, &mcs_rate, &lq->lq);
 	rs_send_lq_cmd(priv, &lq->lq, CMD_ASYNC);
  out:
 	return;
@@ -1714,7 +1727,7 @@ static struct ieee80211_rate *rs_get_rat
 	struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
 	struct iwl_rate_scale_priv *lq;
 
-	IWL_DEBUG_RATE("rate scale calculate new rate for skb\n");
+	IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
 
 	memset(extra, 0, sizeof(*extra));
 
@@ -1775,10 +1788,9 @@ static void *rs_alloc_sta(void *priv, gf
 
 	if (crl == NULL)
 		return NULL;
-
-	memset(crl, 0, sizeof(struct iwl_rate_scale_priv));
 	crl->lq.sta_id = 0xff;
 
+
 	for (j = 0; j < LQ_SIZE; j++)
 		for (i = 0; i < IWL_RATE_COUNT; i++)
 			rs_rate_scale_clear_window(&(crl->lq_info[j].win[i]));
@@ -1795,10 +1807,8 @@ static void rs_rate_init(void *priv_rate
 	struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
 	struct iwl_rate_scale_priv *crl = priv_sta;
 
-	memset(crl, 0, sizeof(struct iwl_rate_scale_priv));
-
-	crl->lq.sta_id = 0xff;
 	crl->flush_timer = 0;
+	crl->supp_rates = sta->supp_rates;
 	sta->txrate = 3;
 	for (j = 0; j < LQ_SIZE; j++)
 		for (i = 0; i < IWL_RATE_COUNT; i++)
@@ -1864,6 +1874,9 @@ static void rs_rate_init(void *priv_rate
 	IWL_DEBUG_HT("MIMO RATE 0x%X SISO MASK 0x%X\n", crl->active_siso_rate,
 		     crl->active_mimo_rate);
 #endif /*CONFIG_IWLWIFI_HT*/
+#ifdef CONFIG_MAC80211_DEBUGFS
+	crl->drv = priv;
+#endif
 
 	if (priv->assoc_station_added)
 		priv->lq_mngr.lq_ready = 1;
@@ -1871,28 +1884,28 @@ static void rs_rate_init(void *priv_rate
 	rs_initialize_lq(priv, sta);
 }
 
-static int rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data,
+static void rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data,
 			    struct iwl_rate *tx_mcs,
-			    struct iwl_link_quality_cmd *lq_cmd,
-			    struct sta_info *sta)
+			    struct iwl_link_quality_cmd *lq_cmd)
 {
 	int index = 0;
-	int rc = 0;
 	int rate_idx;
+	int repeat_rate = 0;
 	u8 ant_toggle_count = 0;
 	u8 use_ht_possible = 1;
-	u8 repeat_cur_rate = 0;
 	struct iwl_rate new_rate;
 	struct iwl_scale_tbl_info tbl_type = { 0 };
 
+	rs_dbgfs_set_mcs(lq_data, tx_mcs, index);
+
 	rs_get_tbl_info_from_mcs(tx_mcs, lq_data->phymode,
 				  &tbl_type, &rate_idx);
 
 	if (is_legacy(tbl_type.lq_type)) {
 		ant_toggle_count = 1;
-		repeat_cur_rate = IWL_NUMBER_TRY;
+		repeat_rate = IWL_NUMBER_TRY;
 	} else
-		repeat_cur_rate = IWL_HT_NUMBER_TRY;
+		repeat_rate = IWL_HT_NUMBER_TRY;
 
 	lq_cmd->general_params.mimo_delimiter =
 			is_mimo(tbl_type.lq_type) ? 1 : 0;
@@ -1906,10 +1919,10 @@ static int rs_fill_link_cmd(struct iwl_r
 		lq_cmd->general_params.single_stream_ant_msk = 2;
 
 	index++;
-	repeat_cur_rate--;
+	repeat_rate--;
 
 	while (index < LINK_QUAL_MAX_RETRY_NUM) {
-		while (repeat_cur_rate && (index < LINK_QUAL_MAX_RETRY_NUM)) {
+		while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) {
 			if (is_legacy(tbl_type.lq_type)) {
 				if (ant_toggle_count <
 				    NUM_TRY_BEFORE_ANTENNA_TOGGLE)
@@ -1919,9 +1932,11 @@ static int rs_fill_link_cmd(struct iwl_r
 					ant_toggle_count = 1;
 				}
 			}
+
+			rs_dbgfs_set_mcs(lq_data, &new_rate, index);
 			lq_cmd->rs_table[index].rate_n_flags =
 					cpu_to_le32(new_rate.rate_n_flags);
-			repeat_cur_rate--;
+			repeat_rate--;
 			index++;
 		}
 
@@ -1932,7 +1947,7 @@ static int rs_fill_link_cmd(struct iwl_r
 			lq_cmd->general_params.mimo_delimiter = index;
 
 		rs_get_lower_rate(lq_data, &tbl_type, rate_idx,
-				  use_ht_possible, &new_rate, sta);
+				  use_ht_possible, &new_rate);
 
 		if (is_legacy(tbl_type.lq_type)) {
 			if (ant_toggle_count < NUM_TRY_BEFORE_ANTENNA_TOGGLE)
@@ -1941,26 +1956,23 @@ static int rs_fill_link_cmd(struct iwl_r
 				rs_toggle_antenna(&new_rate, &tbl_type);
 				ant_toggle_count = 1;
 			}
-			repeat_cur_rate = IWL_NUMBER_TRY;
+			repeat_rate = IWL_NUMBER_TRY;
 		} else
-			repeat_cur_rate = IWL_HT_NUMBER_TRY;
+			repeat_rate = IWL_HT_NUMBER_TRY;
 
 		use_ht_possible = 0;
 
+		rs_dbgfs_set_mcs(lq_data, &new_rate, index);
 		lq_cmd->rs_table[index].rate_n_flags =
 				cpu_to_le32(new_rate.rate_n_flags);
-		/* lq_cmd->rs_table[index].rate_n_flags = 0x800d; */
 
 		index++;
-		repeat_cur_rate--;
+		repeat_rate--;
 	}
 
-	/* lq_cmd->rs_table[0].rate_n_flags = 0x800d; */
-
 	lq_cmd->general_params.dual_stream_ant_msk = 3;
 	lq_cmd->agg_params.agg_dis_start_th = 3;
 	lq_cmd->agg_params.agg_time_limit = cpu_to_le16(4000);
-	return rc;
 }
 
 static void *rs_alloc(struct ieee80211_local *local)
@@ -2000,6 +2012,162 @@ static void rs_free_sta(void *priv, void
 }
 
 
+#ifdef CONFIG_MAC80211_DEBUGFS
+static int open_file_generic(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+static void rs_dbgfs_set_mcs(struct iwl_rate_scale_priv *rs_priv,
+				struct iwl_rate *mcs, int index)
+{
+	const u32 cck_rate = 0x820A;
+	if (rs_priv->dbg_fixed.rate_n_flags) {
+		if (index < 12)
+			mcs->rate_n_flags = rs_priv->dbg_fixed.rate_n_flags;
+		else
+			mcs->rate_n_flags = cck_rate;
+		IWL_DEBUG_RATE("Fixed rate ON\n");
+		return;
+	}
+
+	IWL_DEBUG_RATE("Fixed rate OFF\n");
+}
+
+static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
+			const char __user *user_buf, size_t count, loff_t *ppos)
+{
+	struct iwl_rate_scale_priv *rs_priv = file->private_data;
+	char buf[64];
+	int buf_size;
+	u32 parsed_rate;
+
+	memset(buf, 0, sizeof(buf));
+	buf_size = min(count, sizeof(buf) -  1);
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+
+	if (sscanf(buf, "%x", &parsed_rate) == 1)
+		rs_priv->dbg_fixed.rate_n_flags = parsed_rate;
+	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;
+
+	IWL_DEBUG_RATE("sta_id %d rate 0x%X\n",
+		rs_priv->lq.sta_id, rs_priv->dbg_fixed.rate_n_flags);
+
+	if (rs_priv->dbg_fixed.rate_n_flags) {
+		rs_fill_link_cmd(rs_priv, &rs_priv->dbg_fixed, &rs_priv->lq);
+		rs_send_lq_cmd(rs_priv->drv, &rs_priv->lq, CMD_ASYNC);
+	}
+
+	return count;
+}
+
+static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
+			char __user *user_buf, size_t count, loff_t *ppos)
+{
+	char buff[1024];
+	int desc = 0;
+	int i = 0;
+
+	struct iwl_rate_scale_priv *rs_priv = file->private_data;
+
+	desc += sprintf(buff+desc, "sta_id %d\n", rs_priv->lq.sta_id);
+	desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n",
+			rs_priv->total_failed, rs_priv->total_success,
+			rs_priv->active_rate);
+	desc += sprintf(buff+desc, "fixed rate 0x%X\n",
+			rs_priv->dbg_fixed.rate_n_flags);
+	desc += sprintf(buff+desc, "general:"
+		"flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n",
+		rs_priv->lq.general_params.flags,
+		rs_priv->lq.general_params.mimo_delimiter,
+		rs_priv->lq.general_params.single_stream_ant_msk,
+		rs_priv->lq.general_params.dual_stream_ant_msk);
+
+	desc += sprintf(buff+desc, "agg:"
+			"time_limit=%d dist_start_th=%d frame_cnt_limit=%d\n",
+			le16_to_cpu(rs_priv->lq.agg_params.agg_time_limit),
+			rs_priv->lq.agg_params.agg_dis_start_th,
+			rs_priv->lq.agg_params.agg_frame_cnt_limit);
+
+	desc += sprintf(buff+desc,
+			"Start idx [0]=0x%x [1]=0x%x [2]=0x%x [3]=0x%x\n",
+			rs_priv->lq.general_params.start_rate_index[0],
+			rs_priv->lq.general_params.start_rate_index[1],
+			rs_priv->lq.general_params.start_rate_index[2],
+			rs_priv->lq.general_params.start_rate_index[3]);
+
+
+	for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
+		desc += sprintf(buff+desc, " rate[%d] 0x%X\n",
+			i, le32_to_cpu(rs_priv->lq.rs_table[i].rate_n_flags));
+
+	return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+}
+
+static const struct file_operations rs_sta_dbgfs_scale_table_ops = {
+	.write = rs_sta_dbgfs_scale_table_write,
+	.read = rs_sta_dbgfs_scale_table_read,
+	.open = open_file_generic,
+};
+static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
+			char __user *user_buf, size_t count, loff_t *ppos)
+{
+	char buff[1024];
+	int desc = 0;
+	int i, j;
+
+	struct iwl_rate_scale_priv *rs_priv = file->private_data;
+	for (i = 0; i < LQ_SIZE; i++) {
+		desc += sprintf(buff+desc, "%s type=%d SGI=%d FAT=%d DUP=%d\n"
+				"rate=0x%X\n",
+				rs_priv->active_tbl == i?"*":"x",
+				rs_priv->lq_info[i].lq_type,
+				rs_priv->lq_info[i].is_SGI,
+				rs_priv->lq_info[i].is_fat,
+				rs_priv->lq_info[i].is_dup,
+				rs_priv->lq_info[i].current_rate.rate_n_flags);
+		for (j = 0; j < IWL_RATE_COUNT; j++) {
+			desc += sprintf(buff+desc,
+					"counter=%d success=%d %%=%d\n",
+					rs_priv->lq_info[i].win[j].counter,
+					rs_priv->lq_info[i].win[j].success_counter,
+					rs_priv->lq_info[i].win[j].success_ratio);
+		}
+	}
+	return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+}
+
+static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
+	.read = rs_sta_dbgfs_stats_table_read,
+	.open = open_file_generic,
+};
+
+static void rs_add_debugfs(void *priv, void *priv_sta,
+					struct dentry *dir)
+{
+	struct iwl_rate_scale_priv *rs_priv = priv_sta;
+	rs_priv->rs_sta_dbgfs_scale_table_file =
+		debugfs_create_file("rate_scale_table", 0600, dir,
+				rs_priv, &rs_sta_dbgfs_scale_table_ops);
+	rs_priv->rs_sta_dbgfs_stats_table_file =
+		debugfs_create_file("rate_stats_table", 0600, dir,
+			rs_priv, &rs_sta_dbgfs_stats_table_ops);
+}
+
+static void rs_remove_debugfs(void *priv, void *priv_sta)
+{
+	struct iwl_rate_scale_priv *rs_priv = priv_sta;
+	debugfs_remove(rs_priv->rs_sta_dbgfs_scale_table_file);
+	debugfs_remove(rs_priv->rs_sta_dbgfs_stats_table_file);
+}
+#endif
+
 static struct rate_control_ops rs_ops = {
 	.module = NULL,
 	.name = RS_NAME,
@@ -2011,6 +2179,10 @@ static struct rate_control_ops rs_ops = 
 	.free = rs_free,
 	.alloc_sta = rs_alloc_sta,
 	.free_sta = rs_free_sta,
+#ifdef CONFIG_MAC80211_DEBUGFS
+	.add_sta_debugfs = rs_add_debugfs,
+	.remove_sta_debugfs = rs_remove_debugfs,
+#endif
 };
 
 int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
diff -up linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl4965-base.c.orig linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl4965-base.c
--- linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl4965-base.c.orig	2007-09-27 19:08:16.000000000 -0400
+++ linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl4965-base.c	2007-09-27 19:09:01.000000000 -0400
@@ -102,7 +102,7 @@ int iwl_param_queues_num = IWL_MAX_NUM_Q
 #define VS
 #endif
 
-#define IWLWIFI_VERSION "0.1.15k" VD VS
+#define IWLWIFI_VERSION "1.1.17k" VD VS
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2007 Intel Corporation"
 #define DRV_VERSION     IWLWIFI_VERSION
 
@@ -203,7 +203,7 @@ static void iwl_print_hex_dump(int level
  * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
  * Tx queue resumed.
  *
- * The IPW operates with six queues, one receive queue in the device's
+ * 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.
  ***************************************************/
@@ -407,6 +407,7 @@ const u8 BROADCAST_ADDR[ETH_ALEN] = { 0x
 
 /**************************************************************/
 
+#if 0 /* temparary disable till we add real remove station */
 static u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
 {
 	int index = IWL_INVALID_STATION;
@@ -442,6 +443,7 @@ out:
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
 	return 0;
 }
+#endif
 
 static void iwl_clear_stations_table(struct iwl_priv *priv)
 {
@@ -851,16 +853,12 @@ int iwl_send_statistics_request(struct i
 static int iwl_rxon_add_station(struct iwl_priv *priv,
 				const u8 *addr, int is_ap)
 {
-	u8 rc;
-
-	/* Remove this station if it happens to already exist */
-	iwl_remove_station(priv, addr, is_ap);
-
-	rc = iwl_add_station(priv, addr, is_ap, 0);
+	u8 sta_id;
 
+	sta_id = iwl_add_station(priv, addr, is_ap, 0);
 	iwl4965_add_station(priv, addr, is_ap);
 
-	return rc;
+	return sta_id;
 }
 
 /**
@@ -1147,16 +1145,6 @@ static int iwl_commit_rxon(struct iwl_pr
 				  "configuration (%d).\n", rc);
 			return rc;
 		}
-
-		/* The RXON bit toggling will have cleared out the
-		 * station table in the uCode, so blank it in the driver
-		 * as well */
-		iwl_clear_stations_table(priv);
-	} else if (priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) {
-		/* When switching from non-associated to associated, the
-		 * uCode clears out the station table; so clear it in the
-		 * driver as well */
-		iwl_clear_stations_table(priv);
 	}
 
 	IWL_DEBUG_INFO("Sending RXON\n"
@@ -1176,6 +1164,8 @@ static int iwl_commit_rxon(struct iwl_pr
 		return rc;
 	}
 
+	iwl_clear_stations_table(priv);
+
 #ifdef CONFIG_IWLWIFI_SENSITIVITY
 	if (!priv->error_recovering)
 		priv->start_calib = 0;
@@ -4608,6 +4598,7 @@ static void iwl_rx_handle(struct iwl_pri
 		reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
 			(pkt->hdr.cmd != REPLY_RX_PHY_CMD) &&
 			(pkt->hdr.cmd != REPLY_4965_RX) &&
+			(pkt->hdr.cmd != REPLY_COMPRESSED_BA) &&
 			(pkt->hdr.cmd != STATISTICS_NOTIFICATION) &&
 			(pkt->hdr.cmd != REPLY_TX);
 
@@ -4893,12 +4884,12 @@ static void iwl_dump_nic_event_log(struc
 
 	/* bail out if nothing in log */
 	if (size == 0) {
-		IWL_ERROR("Start IPW Event Log Dump: nothing in log\n");
+		IWL_ERROR("Start IWL Event Log Dump: nothing in log\n");
 		iwl_release_restricted_access(priv);
 		return;
 	}
 
-	IWL_ERROR("Start IPW Event Log Dump: display count %d, wraps %d\n",
+	IWL_ERROR("Start IWL Event Log Dump: display count %d, wraps %d\n",
 		  size, num_wraps);
 
 	/* if uCode has wrapped back to top of log, start at the oldest entry,
@@ -7483,9 +7474,8 @@ static void iwl_config_ap(struct iwl_pri
 		iwl_activate_qos(priv, 1);
 #endif
 		iwl_rxon_add_station(priv, BROADCAST_ADDR, 0);
-		iwl_send_beacon_cmd(priv);
-	} else
-		iwl_send_beacon_cmd(priv);
+	}
+	iwl_send_beacon_cmd(priv);
 
 	/* FIXME - we need to add code here to detect a totally new
 	 * configuration, reset the AP, unassoc, rxon timing, assoc,
diff -up linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-4965.c.orig linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-4965.c
--- linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-4965.c.orig	2007-09-27 19:08:16.000000000 -0400
+++ linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-4965.c	2007-09-27 19:10:39.000000000 -0400
@@ -183,7 +183,7 @@ u8 iwl_hw_find_station(struct iwl_priv *
 			goto out;
 		}
 
-	IWL_DEBUG_ASSOC("can not find STA " MAC_FMT " total %d\n",
+	IWL_DEBUG_ASSOC_LIMIT("can not find STA " MAC_FMT " total %d\n",
 			MAC_ARG(addr), priv->num_stations);
 
  out:
diff -up linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-debug.h.orig linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-debug.h
--- linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-debug.h.orig	2007-09-27 19:08:16.000000000 -0400
+++ linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-debug.h	2007-09-27 19:09:01.000000000 -0400
@@ -136,8 +136,11 @@ static inline void IWL_DEBUG_LIMIT(int l
 #define IWL_DEBUG_TXPOWER(f, a...) IWL_DEBUG(IWL_DL_TXPOWER, f, ## a)
 #define IWL_DEBUG_IO(f, a...) IWL_DEBUG(IWL_DL_IO, f, ## a)
 #define IWL_DEBUG_RATE(f, a...) IWL_DEBUG(IWL_DL_RATE, f, ## a)
+#define IWL_DEBUG_RATE_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_RATE, f, ## a)
 #define IWL_DEBUG_NOTIF(f, a...) IWL_DEBUG(IWL_DL_NOTIF, f, ## a)
 #define IWL_DEBUG_ASSOC(f, a...) IWL_DEBUG(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
+#define IWL_DEBUG_ASSOC_LIMIT(f, a...) \
+	IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
 #define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a)
 #define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a)
 #define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a)
diff -up linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl3945-base.c.orig linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl3945-base.c
--- linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl3945-base.c.orig	2007-09-27 19:08:16.000000000 -0400
+++ linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl3945-base.c	2007-09-27 19:10:13.000000000 -0400
@@ -103,7 +103,7 @@ int iwl_param_queues_num = IWL_MAX_NUM_Q
 #define VS
 #endif
 
-#define IWLWIFI_VERSION "0.1.15k" VD VS
+#define IWLWIFI_VERSION "1.1.17k" VD VS
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2007 Intel Corporation"
 #define DRV_VERSION     IWLWIFI_VERSION
 
@@ -204,7 +204,7 @@ static void iwl_print_hex_dump(int level
  * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
  * Tx queue resumed.
  *
- * The IPW operates with six queues, one receive queue in the device's
+ * 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.
  ***************************************************/
@@ -407,6 +407,7 @@ const u8 BROADCAST_ADDR[ETH_ALEN] = { 0x
  */
 
 /**************************************************************/
+#if 0 /* temparary disable till we add real remove station */
 static u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
 {
 	int index = IWL_INVALID_STATION;
@@ -442,7 +443,7 @@ out:
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
 	return 0;
 }
-
+#endif
 static void iwl_clear_stations_table(struct iwl_priv *priv)
 {
 	unsigned long flags;
@@ -462,6 +463,7 @@ u8 iwl_add_station(struct iwl_priv *priv
 	int index = IWL_INVALID_STATION;
 	struct iwl_station_entry *station;
 	unsigned long flags_spin;
+	u8 rate;
 
 	spin_lock_irqsave(&priv->sta_lock, flags_spin);
 	if (is_ap)
@@ -505,6 +507,15 @@ u8 iwl_add_station(struct iwl_priv *priv
 	station->sta.sta.sta_id = index;
 	station->sta.station_flags = 0;
 
+	rate = (priv->phymode == MODE_IEEE80211A) ? IWL_RATE_6M_PLCP :
+				IWL_RATE_1M_PLCP | priv->hw_setting.cck_flag;
+
+	/* Turn on both antennas for the station... */
+	station->sta.rate_n_flags =
+			iwl_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK);
+	station->current_rate.rate_n_flags =
+			le16_to_cpu(station->sta.rate_n_flags);
+
 	spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
 	iwl_send_add_station(priv, &station->sta, flags);
 	return index;
@@ -834,25 +845,6 @@ int iwl_send_statistics_request(struct i
 }
 
 /**
- * iwl_rxon_add_station - add station into station table.
- *
- * there is only one AP station with id= IWL_AP_ID
- * NOTE: mutex must be held before calling the this fnction
-*/
-static int iwl_rxon_add_station(struct iwl_priv *priv,
-				const u8 *addr, int is_ap)
-{
-	u8 rc;
-
-	/* Remove this station if it happens to already exist */
-	iwl_remove_station(priv, addr, is_ap);
-
-	rc = iwl_add_station(priv, addr, is_ap, 0);
-
-	return rc;
-}
-
-/**
  * iwl_set_rxon_channel - Set the phymode and channel values in staging RXON
  * @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz
  * @channel: Any channel valid for the requested phymode
@@ -1121,16 +1113,6 @@ static int iwl_commit_rxon(struct iwl_pr
 				  "configuration (%d).\n", rc);
 			return rc;
 		}
-
-		/* The RXON bit toggling will have cleared out the
-		 * station table in the uCode, so blank it in the driver
-		 * as well */
-		iwl_clear_stations_table(priv);
-	} else if (priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) {
-		/* When switching from non-associated to associated, the
-		 * uCode clears out the station table; so clear it in the
-		 * driver as well */
-		iwl_clear_stations_table(priv);
 	}
 
 	IWL_DEBUG_INFO("Sending RXON\n"
@@ -1152,6 +1134,8 @@ static int iwl_commit_rxon(struct iwl_pr
 
 	memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
 
+	iwl_clear_stations_table(priv);
+
 	/* If we issue a new RXON command which required a tune then we must
 	 * send a new TXPOWER command or we won't be able to Tx any frames */
 	rc = iwl_hw_reg_send_txpower(priv);
@@ -1161,7 +1145,7 @@ static int iwl_commit_rxon(struct iwl_pr
 	}
 
 	/* Add the broadcast address so we can send broadcast frames */
-	if (iwl_rxon_add_station(priv, BROADCAST_ADDR, 0) ==
+	if (iwl_add_station(priv, BROADCAST_ADDR, 0, 0) ==
 	    IWL_INVALID_STATION) {
 		IWL_ERROR("Error adding BROADCAST address for transmit.\n");
 		return -EIO;
@@ -1171,7 +1155,7 @@ static int iwl_commit_rxon(struct iwl_pr
 	 * add the IWL_AP_ID to the station rate table */
 	if (iwl_is_associated(priv) &&
 	    (priv->iw_mode == IEEE80211_IF_TYPE_STA))
-		if (iwl_rxon_add_station(priv, priv->active_rxon.bssid_addr, 1)
+		if (iwl_add_station(priv, priv->active_rxon.bssid_addr, 1, 0)
 		    == IWL_INVALID_STATION) {
 			IWL_ERROR("Error adding AP address for transmit.\n");
 			return -EIO;
@@ -4583,12 +4567,12 @@ static void iwl_dump_nic_event_log(struc
 
 	/* bail out if nothing in log */
 	if (size == 0) {
-		IWL_ERROR("Start IPW Event Log Dump: nothing in log\n");
+		IWL_ERROR("Start IWL Event Log Dump: nothing in log\n");
 		iwl_release_restricted_access(priv);
 		return;
 	}
 
-	IWL_ERROR("Start IPW Event Log Dump: display count %d, wraps %d\n",
+	IWL_ERROR("Start IWL Event Log Dump: display count %d, wraps %d\n",
 		  size, num_wraps);
 
 	/* if uCode has wrapped back to top of log, start at the oldest entry,
@@ -4650,7 +4634,7 @@ static void iwl_error_recovery(struct iw
 	priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 	iwl_commit_rxon(priv);
 
-	iwl_rxon_add_station(priv, priv->bssid, 1);
+	iwl_add_station(priv, priv->bssid, 1, 0);
 
 	spin_lock_irqsave(&priv->lock, flags);
 	priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id);
@@ -6793,8 +6777,8 @@ static void iwl_bg_post_associate(struct
 		/* clear out the station table */
 		iwl_clear_stations_table(priv);
 
-		iwl_rxon_add_station(priv, BROADCAST_ADDR, 0);
-		iwl_rxon_add_station(priv, priv->bssid, 0);
+		iwl_add_station(priv, BROADCAST_ADDR, 0, 0);
+		iwl_add_station(priv, priv->bssid, 0, 0);
 		iwl3945_sync_sta(priv, IWL_STA_ID,
 				 (priv->phymode == MODE_IEEE80211A)?
 				 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,
@@ -7082,10 +7066,9 @@ static void iwl_config_ap(struct iwl_pri
 		/* restore RXON assoc */
 		priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
 		iwl_commit_rxon(priv);
-		iwl_rxon_add_station(priv, BROADCAST_ADDR, 0);
-		iwl_send_beacon_cmd(priv);
-	} else
-		iwl_send_beacon_cmd(priv);
+		iwl_add_station(priv, BROADCAST_ADDR, 0, 0);
+	}
+	iwl_send_beacon_cmd(priv);
 
 	/* FIXME - we need to add code here to detect a totally new
 	 * configuration, reset the AP, unassoc, rxon timing, assoc,
@@ -7168,8 +7151,8 @@ static int iwl_mac_config_interface(stru
 						RXON_FILTER_ASSOC_MSK;
 			rc = iwl_commit_rxon(priv);
 			if ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && rc)
-				iwl_rxon_add_station(
-					priv, priv->active_rxon.bssid_addr, 1);
+				iwl_add_station(priv,
+					priv->active_rxon.bssid_addr, 1, 0);
 		}
 
 	} else {


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.194
retrieving revision 1.195
diff -u -r1.194 -r1.195
--- kernel.spec	27 Sep 2007 16:33:17 -0000	1.194
+++ kernel.spec	27 Sep 2007 23:49:10 -0000	1.195
@@ -632,6 +632,7 @@
 Patch662: linux-2.6-libata-pata-dma-disable-option.patch
 Patch670: linux-2.6-ata-quirk.patch
 Patch681: linux-2.6-wireless-pending.patch
+Patch682: linux-2.6-iwlwifi-fixes.patch
 Patch690: linux-2.6-at76.patch
 Patch691: linux-2.6-ath5k.patch
 Patch692: linux-2.6-zd1211rw-mac80211.patch
@@ -1143,6 +1144,8 @@
 # wireless patches headed for 2.6.23
 # wireless patches staged for 2.6.24
 ApplyPatch linux-2.6-wireless-pending.patch
+# late-breaking iwlwifi fixes (will be rolled into wireless-pending patch)
+ApplyPatch linux-2.6-iwlwifi-fixes.patch
 # Add misc wireless bits from upstream wireless tree
 ApplyPatch linux-2.6-at76.patch
 ApplyPatch linux-2.6-ath5k.patch
@@ -1809,6 +1812,9 @@
 
 
 %changelog
+* Thu Sep 27 2007 John W. Linville <linville at redhat.com>
+- A few iwlwifi and ath5k fixes
+
 * Thu Sep 27 2007 Chuck Ebbert <cebbert at redhat.com>
 - Linux 2.6.23-rc8-git2
 - Re-add AMD timer fix removed from upstream

linux-2.6-ath5k.patch:

View full diff with command:
/usr/bin/cvs -f diff  -kk -u -N -r 1.1 -r 1.2 linux-2.6-ath5k.patch
Index: linux-2.6-ath5k.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-ath5k.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- linux-2.6-ath5k.patch	27 Sep 2007 00:43:34 -0000	1.1
+++ linux-2.6-ath5k.patch	27 Sep 2007 23:49:10 -0000	1.2
@@ -1,6 +1,6 @@
 diff -up linux-2.6.22.noarch/MAINTAINERS.orig linux-2.6.22.noarch/MAINTAINERS
---- linux-2.6.22.noarch/MAINTAINERS.orig	2007-09-26 19:59:33.000000000 -0400
-+++ linux-2.6.22.noarch/MAINTAINERS	2007-09-26 20:00:12.000000000 -0400
+--- linux-2.6.22.noarch/MAINTAINERS.orig	2007-09-27 19:25:02.000000000 -0400
++++ linux-2.6.22.noarch/MAINTAINERS	2007-09-27 19:26:44.000000000 -0400
 @@ -642,6 +642,14 @@ M:	ecashin at coraid.com
  W:	http://www.coraid.com/support/linux
  S:	Supported
@@ -16,14050 +16,13915 @@
  ATL1 ETHERNET DRIVER
  P:	Jay Cliburn
  M:	jcliburn at gmail.com
-diff -up /dev/null linux-2.6.22.noarch/drivers/net/wireless/ath5k.h
---- /dev/null	2007-09-25 08:26:55.562976333 -0400
-+++ linux-2.6.22.noarch/drivers/net/wireless/ath5k.h	2007-09-26 20:00:12.000000000 -0400
-@@ -0,0 +1,1104 @@
+diff -up linux-2.6.22.noarch/drivers/net/wireless/Makefile.orig linux-2.6.22.noarch/drivers/net/wireless/Makefile
+--- linux-2.6.22.noarch/drivers/net/wireless/Makefile.orig	2007-09-27 19:25:02.000000000 -0400
++++ linux-2.6.22.noarch/drivers/net/wireless/Makefile	2007-09-27 19:27:03.000000000 -0400
+@@ -61,3 +61,5 @@ obj-$(CONFIG_RT2X00)		+= rt2x00/
+ obj-$(CONFIG_P54_COMMON)	+= p54common.o
+ obj-$(CONFIG_P54_USB)		+= p54usb.o
+ obj-$(CONFIG_P54_PCI)		+= p54pci.o
++
++obj-$(CONFIG_ATH5K)	+= ath5k/
+diff -up linux-2.6.22.noarch/drivers/net/wireless/Kconfig.orig linux-2.6.22.noarch/drivers/net/wireless/Kconfig
+--- linux-2.6.22.noarch/drivers/net/wireless/Kconfig.orig	2007-09-27 19:25:02.000000000 -0400
++++ linux-2.6.22.noarch/drivers/net/wireless/Kconfig	2007-09-27 19:26:44.000000000 -0400
+@@ -598,6 +598,19 @@ config P54_PCI
+ 	tristate "Prism54 PCI support"
+ 	depends on P54_COMMON && PCI
+ 
++config ATH5K
++	tristate "Atheros 5xxx wireless cards support"
++	depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
++	default m
++	---help---
++	  This module adds support for atheros 5xxx (e.g. 5212) wireless
++	  cards. If you have this card in your PC, select this to be build.
++
++	  This driver uses the kernel's mac80211 subsystem.
++
++	  If you choose to build a module, it'll be called ath5k. Say M if
++	  unsure.
++
+ source "drivers/net/wireless/hostap/Kconfig"
+ source "drivers/net/wireless/bcm43xx/Kconfig"
+ source "drivers/net/wireless/b43/Kconfig"
+diff -up /dev/null linux-2.6.22.noarch/drivers/net/wireless/ath5k/phy.c
+--- /dev/null	2007-09-27 08:31:24.563724082 -0400
++++ linux-2.6.22.noarch/drivers/net/wireless/ath5k/phy.c	2007-09-27 19:26:44.000000000 -0400
+@@ -0,0 +1,1704 @@
 +/*
-+ * Copyright (c) 2004-2007 Reyk Floeter <reyk at openbsd.org>
-+ * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm at gmail.com>
++ * PHY functions
 + *
-+ * Permission to use, copy, modify, and distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
++ * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm at gmail.com>
 + *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ *  This file is free software: you can copy, redistribute and/or modify
++ *  it under the terms of the GNU General Public License as published by
++ *  the Free Software Foundation, either version 2 of the License, or (at
++ *  your option) any later version.
++ *
++ *  This file is distributed in the hope that it will be useful, but
++ *  WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ *  General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
++ *
++ * This file incorporates work covered by the following copyright and
++ * permission notice:
++ *
++ *     Copyright (c) 2007 Jiri Slaby <jirislaby at gmail.com>
++ *     Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk at openbsd.org>
++ *
++ *     Permission to use, copy, modify, and distribute this software for
++ *     any purpose with or without fee is hereby granted, provided that
++ *     the above copyright notice and this permission notice appear in all
++ *     copies.
++ *
++ *     THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
++ *     WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
++ *     WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
++ *     AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
++ *     CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
++ *     OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
++ *     NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ *     CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 + */
 +
-+#ifndef _ATH5K_H
-+#define _ATH5K_H
++#include <linux/delay.h>
 +
-+/* Set this to 1 to disable regulatory domain restrictions for channel tests.
-+ * WARNING: This is for debuging only and has side effects (eg. scan takes too
-+ * long and results timeouts). It's also illegal to tune to some of the
-+ * supported frequencies in some countries, so use this at your own risk,
-+ * you've been warned. */
-+#define CHAN_DEBUG	0
++#include "ath5k.h"
++#include "reg.h"
 +
-+/* Uncomment this for debuging (warning that it results in TOO much output) */
-+/*#define AR5K_DEBUG	1 */
++/* Struct to hold initial RF register values (RF Banks) */
++struct ath5k_ini_rf {
++	u8	rf_bank;	/* check out ath5k_reg.h */
++	u16	rf_register;	/* register address */
++	u32	rf_value[5];	/* register value for different modes (above) */
++};
 +
-+#include <linux/types.h>
-+#include <net/mac80211.h>
++/*
++ * Mode-specific RF Gain table (64bytes) for RF5111/5112
++ * (RF5110 only comes with AR5210 and only supports a/turbo a mode so initial
++ * RF Gain values are included in AR5K_AR5210_INI)
++ */
++struct ath5k_ini_rfgain {
++	u16	rfg_register;	/* RF Gain register address */
++	u32	rfg_value[2];	/* [freq (see below)] */
++};
 +
-+#include "ath5k_hw.h"
-+#include "ath5k_regdom.h"
++struct ath5k_gain_opt {
++	u32			go_default;
++	u32			go_steps_count;
++	const struct ath5k_gain_opt_step	go_step[AR5K_GAIN_STEP_COUNT];
++};
 +
-+/* PCI IDs */
-+#define PCI_DEVICE_ID_ATHEROS_AR5210 		0x0007 /* AR5210 */
-+#define PCI_DEVICE_ID_ATHEROS_AR5311 		0x0011 /* AR5311 */
-+#define PCI_DEVICE_ID_ATHEROS_AR5211 		0x0012 /* AR5211 */
-+#define PCI_DEVICE_ID_ATHEROS_AR5212 		0x0013 /* AR5212 */
-+#define PCI_DEVICE_ID_3COM_3CRDAG675 		0x0013 /* 3CRDAG675 (Atheros AR5212) */
-+#define PCI_DEVICE_ID_3COM_2_3CRPAG175 		0x0013 /* 3CRPAG175 (Atheros AR5212) */
-+#define PCI_DEVICE_ID_ATHEROS_AR5210_AP 	0x0207 /* AR5210 (Early) */
-+#define PCI_DEVICE_ID_ATHEROS_AR5212_IBM	0x1014 /* AR5212 (IBM MiniPCI) */
-+#define PCI_DEVICE_ID_ATHEROS_AR5210_DEFAULT 	0x1107 /* AR5210 (no eeprom) */
-+#define PCI_DEVICE_ID_ATHEROS_AR5212_DEFAULT 	0x1113 /* AR5212 (no eeprom) */
-+#define PCI_DEVICE_ID_ATHEROS_AR5211_DEFAULT 	0x1112 /* AR5211 (no eeprom) */
-+#define PCI_DEVICE_ID_ATHEROS_AR5212_FPGA 	0xf013 /* AR5212 (emulation board) */
-+#define PCI_DEVICE_ID_ATHEROS_AR5211_LEGACY 	0xff12 /* AR5211 (emulation board) */
-+#define PCI_DEVICE_ID_ATHEROS_AR5211_FPGA11B 	0xf11b /* AR5211 (emulation board) */
-+#define PCI_DEVICE_ID_ATHEROS_AR5212_REV2 	0x0052 /* AR5312 WMAC (AP31) */
-+#define PCI_DEVICE_ID_ATHEROS_AR5212_REV7 	0x0057 /* AR5312 WMAC (AP30-040) */
-+#define PCI_DEVICE_ID_ATHEROS_AR5212_REV8 	0x0058 /* AR5312 WMAC (AP43-030) */
-+#define PCI_DEVICE_ID_ATHEROS_AR5212_0014 	0x0014 /* AR5212 compatible */
-+#define PCI_DEVICE_ID_ATHEROS_AR5212_0015 	0x0015 /* AR5212 compatible */
-+#define PCI_DEVICE_ID_ATHEROS_AR5212_0016 	0x0016 /* AR5212 compatible */
-+#define PCI_DEVICE_ID_ATHEROS_AR5212_0017 	0x0017 /* AR5212 compatible */
-+#define PCI_DEVICE_ID_ATHEROS_AR5212_0018 	0x0018 /* AR5212 compatible */
-+#define PCI_DEVICE_ID_ATHEROS_AR5212_0019 	0x0019 /* AR5212 compatible */
-+#define PCI_DEVICE_ID_ATHEROS_AR2413 		0x001a /* AR2413 (Griffin-lite) */
-+#define PCI_DEVICE_ID_ATHEROS_AR5413 		0x001b /* AR5413 (Eagle) */
-+#define PCI_DEVICE_ID_ATHEROS_AR5424 		0x001c /* AR5424 (Condor PCI-E) */
++/* RF5111 mode-specific init registers */
++static const struct ath5k_ini_rf rfregs_5111[] = {
++	{ 0, 0x989c,
++	/*    mode a/XR   mode aTurbo mode b      mode g      mode gTurbo */
++	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
++	{ 0, 0x989c,
++	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
++	{ 0, 0x989c,
++	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
++	{ 0, 0x989c,
++	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
++	{ 0, 0x989c,
++	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
++	{ 0, 0x989c,
++	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
++	{ 0, 0x989c,
++	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
++	{ 0, 0x989c,
++	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
[...25702 lines suppressed...]
-+/*
-+ * PHY current RSSI register [5111+]
-+ */
-+#define	AR5K_PHY_CURRENT_RSSI		0x9c1c
++	ret = pci_register_driver(&ath_pci_drv_id);
++	if (ret) {
++		printk(KERN_ERR "ath_pci: can't register pci driver\n");
++		return ret;
++	}
++	ath_sysctl_header = register_sysctl_table(ath_root_table);
 +
-+/*
-+ * PHY PCDAC TX power table
-+ */
-+#define	AR5K_PHY_PCDAC_TXPOWER_BASE	0xa180
-+#define	AR5K_PHY_PCDAC_TXPOWER(_n)	(AR5K_PHY_PCDAC_TXPOWER_BASE + ((_n) << 2))
++	return 0;
++}
 +
-+/*
-+ * PHY mode register [5111+]
-+ */
-+#define	AR5K_PHY_MODE			0x0a200		/* Register address */
-+#define	AR5K_PHY_MODE_MOD		0x00000001	/* PHY Modulation mask*/
-+#define AR5K_PHY_MODE_MOD_OFDM		0
-+#define AR5K_PHY_MODE_MOD_CCK		1
-+#define AR5K_PHY_MODE_FREQ		0x00000002	/* Freq mode mask */
-+#define	AR5K_PHY_MODE_FREQ_5GHZ		0
-+#define	AR5K_PHY_MODE_FREQ_2GHZ		2
-+#define AR5K_PHY_MODE_MOD_DYN		0x00000004	/* Dynamic OFDM/CCK mode mask [5112+] */
-+#define AR5K_PHY_MODE_RAD		0x00000008	/* [5212+] */
-+#define AR5K_PHY_MODE_RAD_RF5111	0
-+#define AR5K_PHY_MODE_RAD_RF5112	8
-+#define AR5K_PHY_MODE_XR		0x00000010	/* [5112+] */
++static void __exit exit_ath_pci(void)
++{
++	if (ath_sysctl_header)
++		unregister_sysctl_table(ath_sysctl_header);
++	pci_unregister_driver(&ath_pci_drv_id);
++}
 +
-+/*
-+ * PHY CCK transmit control register [5111+ (?)]
-+ */
-+#define AR5K_PHY_CCKTXCTL		0xa204
-+#define AR5K_PHY_CCKTXCTL_WORLD		0x00000000
-+#define AR5K_PHY_CCKTXCTL_JAPAN		0x00000010
++module_init(init_ath_pci);
++module_exit(exit_ath_pci);
 +
-+/*
-+ * PHY 2GHz gain register [5111+]
-+ */
-+#define	AR5K_PHY_GAIN_2GHZ		0xa20c
-+#define	AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX	0x00fc0000
-+#define	AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX_S	18
-+#define	AR5K_PHY_GAIN_2GHZ_INI_5111	0x6480416c
-diff -up /dev/null linux-2.6.22.noarch/drivers/net/wireless/ath5k_base.h
---- /dev/null	2007-09-25 08:26:55.562976333 -0400
-+++ linux-2.6.22.noarch/drivers/net/wireless/ath5k_base.h	2007-09-26 20:00:12.000000000 -0400
++MODULE_AUTHOR("Jiri Slaby");
++MODULE_DESCRIPTION("Support for Atheros 802.11 wireless LAN cards.");
++MODULE_SUPPORTED_DEVICE("Atheros WLAN cards");
++MODULE_LICENSE("Dual BSD/GPL");
++MODULE_VERSION(ATH_PCI_VERSION " (EXPERIMENTAL)");
+diff -up /dev/null linux-2.6.22.noarch/drivers/net/wireless/ath5k/base.h
+--- /dev/null	2007-09-27 08:31:24.563724082 -0400
++++ linux-2.6.22.noarch/drivers/net/wireless/ath5k/base.h	2007-09-27 19:26:44.000000000 -0400
 @@ -0,0 +1,204 @@
 +/*-
 + * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting
@@ -14265,3 +14130,128 @@
 +	(ath5k_hw_get_capability(_ah, AR5K_CAP_VEOL, 0, NULL) == 0)
 +
 +#endif
+diff -up /dev/null linux-2.6.22.noarch/drivers/net/wireless/ath5k/regdom.c
+--- /dev/null	2007-09-27 08:31:24.563724082 -0400
++++ linux-2.6.22.noarch/drivers/net/wireless/ath5k/regdom.c	2007-09-27 19:26:44.000000000 -0400
+@@ -0,0 +1,121 @@
++/*
++ * Copyright (c) 2004, 2005 Reyk Floeter <reyk at vantronix.net>
++ *
++ * Permission to use, copy, modify, and distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++/*
++ * Basic regulation domain extensions for the IEEE 802.11 stack
++ */
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++
++#include "regdom.h"
++
++static const struct ath5k_regdommap {
++	enum ath5k_regdom dmn;
++	enum ath5k_regdom dmn5;
++	enum ath5k_regdom dmn2;
++} r_map[] = {
++	{ DMN_DEFAULT,		DMN_DEBUG,	DMN_DEBUG },
++	{ DMN_NULL_WORLD,	DMN_NULL,	DMN_WORLD },
++	{ DMN_NULL_ETSIB,	DMN_NULL,	DMN_ETSIB },
++	{ DMN_NULL_ETSIC,	DMN_NULL,	DMN_ETSIC },
++	{ DMN_FCC1_FCCA,	DMN_FCC1,	DMN_FCCA },
++	{ DMN_FCC1_WORLD,	DMN_FCC1,	DMN_WORLD },
++	{ DMN_FCC2_FCCA,	DMN_FCC2,	DMN_FCCA },
++	{ DMN_FCC2_WORLD,	DMN_FCC2,	DMN_WORLD },
++	{ DMN_FCC2_ETSIC,	DMN_FCC2,	DMN_ETSIC },
++	{ DMN_FRANCE_NULL,	DMN_ETSI3,	DMN_ETSI3 },
++	{ DMN_FCC3_FCCA,	DMN_FCC3,	DMN_WORLD },
++	{ DMN_ETSI1_WORLD,	DMN_ETSI1,	DMN_WORLD },
++	{ DMN_ETSI3_ETSIA,	DMN_ETSI3,	DMN_WORLD },
++	{ DMN_ETSI2_WORLD,	DMN_ETSI2,	DMN_WORLD },
++	{ DMN_ETSI3_WORLD,	DMN_ETSI3,	DMN_WORLD },
++	{ DMN_ETSI4_WORLD,	DMN_ETSI4,	DMN_WORLD },
++	{ DMN_ETSI4_ETSIC,	DMN_ETSI4,	DMN_ETSIC },
++	{ DMN_ETSI5_WORLD,	DMN_ETSI5,	DMN_WORLD },
++	{ DMN_ETSI6_WORLD,	DMN_ETSI6,	DMN_WORLD },
++	{ DMN_ETSI_NULL,	DMN_ETSI1,	DMN_ETSI1 },
++	{ DMN_MKK1_MKKA,	DMN_MKK1,	DMN_MKKA },
++	{ DMN_MKK1_MKKB,	DMN_MKK1,	DMN_MKKA },
++	{ DMN_APL4_WORLD,	DMN_APL4,	DMN_WORLD },
++	{ DMN_MKK2_MKKA,	DMN_MKK2,	DMN_MKKA },
++	{ DMN_APL_NULL,		DMN_APL1,	DMN_NULL },
++	{ DMN_APL2_WORLD,	DMN_APL2,	DMN_WORLD },
++	{ DMN_APL2_APLC,	DMN_APL2,	DMN_WORLD },
++	{ DMN_APL3_WORLD,	DMN_APL3,	DMN_WORLD },
++	{ DMN_MKK1_FCCA,	DMN_MKK1,	DMN_FCCA },
++	{ DMN_APL2_APLD,	DMN_APL2,	DMN_APLD },
++	{ DMN_MKK1_MKKA1,	DMN_MKK1,	DMN_MKKA },
++	{ DMN_MKK1_MKKA2,	DMN_MKK1,	DMN_MKKA },
++	{ DMN_APL1_WORLD,	DMN_APL1,	DMN_WORLD },
++	{ DMN_APL1_FCCA,	DMN_APL1,	DMN_FCCA },
++	{ DMN_APL1_APLA,	DMN_APL1,	DMN_WORLD },
++	{ DMN_APL1_ETSIC,	DMN_APL1,	DMN_ETSIC },
++	{ DMN_APL2_ETSIC,	DMN_APL2,	DMN_ETSIC },
++	{ DMN_APL5_WORLD,	DMN_APL5,	DMN_WORLD },
++	{ DMN_WOR0_WORLD,	DMN_WORLD,	DMN_WORLD },
++	{ DMN_WOR1_WORLD,	DMN_WORLD,	DMN_WORLD },
++	{ DMN_WOR2_WORLD,	DMN_WORLD,	DMN_WORLD },
++	{ DMN_WOR3_WORLD,	DMN_WORLD,	DMN_WORLD },
++	{ DMN_WOR4_WORLD,	DMN_WORLD,	DMN_WORLD },
++	{ DMN_WOR5_ETSIC,	DMN_WORLD,	DMN_WORLD },
++	{ DMN_WOR01_WORLD,	DMN_WORLD,	DMN_WORLD },
++	{ DMN_WOR02_WORLD,	DMN_WORLD,	DMN_WORLD },
++	{ DMN_EU1_WORLD,	DMN_ETSI1,	DMN_WORLD },
++	{ DMN_WOR9_WORLD,	DMN_WORLD,	DMN_WORLD },
++	{ DMN_WORA_WORLD,	DMN_WORLD,	DMN_WORLD },
++};
++
++enum ath5k_regdom ath5k_regdom2flag(enum ath5k_regdom dmn, u16 mhz)
++{
++	unsigned int i;
++
++	for (i = 0; i < ARRAY_SIZE(r_map); i++) {
++		if (r_map[i].dmn == dmn) {
++			if (mhz >= 2000 && mhz <= 3000)
++				return r_map[i].dmn2;
++			if (mhz >= IEEE80211_CHANNELS_5GHZ_MIN &&
++					mhz <= IEEE80211_CHANNELS_5GHZ_MAX)
++				return r_map[i].dmn5;
++		}
++	}
++
++	return DMN_DEBUG;
++}
++
++u16 ath5k_regdom_from_ieee(enum ath5k_regdom ieee)
++{
++	u32 regdomain = (u32)ieee;
++
++	/*
++	 * Use the default regulation domain if the value is empty
++	 * or not supported by the net80211 regulation code.
++	 */
++	if (ath5k_regdom2flag(regdomain, IEEE80211_CHANNELS_5GHZ_MIN) ==
++			DMN_DEBUG)
++		return (u16)AR5K_TUNE_REGDOMAIN;
++
++	/* It is supported, just return the value */
++	return regdomain;
++}
++
++enum ath5k_regdom ath5k_regdom_to_ieee(u16 regdomain)
++{
++	enum ath5k_regdom ieee = (enum ath5k_regdom)regdomain;
++
++	return ieee;
++}
++




More information about the fedora-extras-commits mailing list