| Wey-Yi Guy | 278fc73 | 2010-06-14 17:09:53 -0700 | [diff] [blame] | 1 | /****************************************************************************** | 
 | 2 |  * | 
 | 3 |  * GPL LICENSE SUMMARY | 
 | 4 |  * | 
 | 5 |  * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. | 
 | 6 |  * | 
 | 7 |  * This program is free software; you can redistribute it and/or modify | 
 | 8 |  * it under the terms of version 2 of the GNU General Public License as | 
 | 9 |  * published by the Free Software Foundation. | 
 | 10 |  * | 
 | 11 |  * This program is distributed in the hope that it will be useful, but | 
 | 12 |  * WITHOUT ANY WARRANTY; without even the implied warranty of | 
 | 13 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
 | 14 |  * General Public License for more details. | 
 | 15 |  * | 
 | 16 |  * You should have received a copy of the GNU General Public License | 
 | 17 |  * along with this program; if not, write to the Free Software | 
 | 18 |  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | 
 | 19 |  * USA | 
 | 20 |  * | 
 | 21 |  * The full GNU General Public License is included in this distribution | 
 | 22 |  * in the file called LICENSE.GPL. | 
 | 23 |  * | 
 | 24 |  * Contact Information: | 
 | 25 |  *  Intel Linux Wireless <ilw@linux.intel.com> | 
 | 26 |  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | 
 | 27 |  * | 
 | 28 |  *****************************************************************************/ | 
 | 29 |  | 
 | 30 | #include <linux/kernel.h> | 
 | 31 | #include <linux/module.h> | 
 | 32 | #include <linux/init.h> | 
 | 33 | #include <linux/sched.h> | 
 | 34 |  | 
 | 35 | #include "iwl-dev.h" | 
 | 36 | #include "iwl-core.h" | 
 | 37 | #include "iwl-calib.h" | 
 | 38 | #include "iwl-sta.h" | 
 | 39 | #include "iwl-io.h" | 
 | 40 | #include "iwl-helpers.h" | 
 | 41 | #include "iwl-agn-hw.h" | 
 | 42 | #include "iwl-agn.h" | 
 | 43 |  | 
 | 44 | void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, | 
 | 45 | 				struct iwl_rx_mem_buffer *rxb) | 
 | 46 |  | 
 | 47 | { | 
 | 48 | 	struct iwl_rx_packet *pkt = rxb_addr(rxb); | 
 | 49 | 	struct iwl_missed_beacon_notif *missed_beacon; | 
 | 50 |  | 
 | 51 | 	missed_beacon = &pkt->u.missed_beacon; | 
 | 52 | 	if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) > | 
 | 53 | 	    priv->missed_beacon_threshold) { | 
 | 54 | 		IWL_DEBUG_CALIB(priv, | 
 | 55 | 		    "missed bcn cnsq %d totl %d rcd %d expctd %d\n", | 
 | 56 | 		    le32_to_cpu(missed_beacon->consecutive_missed_beacons), | 
 | 57 | 		    le32_to_cpu(missed_beacon->total_missed_becons), | 
 | 58 | 		    le32_to_cpu(missed_beacon->num_recvd_beacons), | 
 | 59 | 		    le32_to_cpu(missed_beacon->num_expected_beacons)); | 
 | 60 | 		if (!test_bit(STATUS_SCANNING, &priv->status)) | 
 | 61 | 			iwl_init_sensitivity(priv); | 
 | 62 | 	} | 
 | 63 | } | 
 | 64 |  | 
 | 65 | /* Calculate noise level, based on measurements during network silence just | 
 | 66 |  *   before arriving beacon.  This measurement can be done only if we know | 
 | 67 |  *   exactly when to expect beacons, therefore only when we're associated. */ | 
 | 68 | static void iwl_rx_calc_noise(struct iwl_priv *priv) | 
 | 69 | { | 
| Wey-Yi Guy | 7980fba | 2010-07-14 08:08:57 -0700 | [diff] [blame] | 70 | 	struct statistics_rx_non_phy *rx_info; | 
| Wey-Yi Guy | 278fc73 | 2010-06-14 17:09:53 -0700 | [diff] [blame] | 71 | 	int num_active_rx = 0; | 
 | 72 | 	int total_silence = 0; | 
| Wey-Yi Guy | 7980fba | 2010-07-14 08:08:57 -0700 | [diff] [blame] | 73 | 	int bcn_silence_a, bcn_silence_b, bcn_silence_c; | 
| Wey-Yi Guy | 278fc73 | 2010-06-14 17:09:53 -0700 | [diff] [blame] | 74 | 	int last_rx_noise; | 
 | 75 |  | 
| Wey-Yi Guy | 7980fba | 2010-07-14 08:08:57 -0700 | [diff] [blame] | 76 | 	if (priv->cfg->bt_statistics) | 
 | 77 | 		rx_info = &(priv->_agn.statistics_bt.rx.general.common); | 
 | 78 | 	else | 
 | 79 | 		rx_info = &(priv->_agn.statistics.rx.general); | 
 | 80 | 	bcn_silence_a = | 
 | 81 | 		le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER; | 
 | 82 | 	bcn_silence_b = | 
 | 83 | 		le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER; | 
 | 84 | 	bcn_silence_c = | 
 | 85 | 		le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER; | 
 | 86 |  | 
| Wey-Yi Guy | 278fc73 | 2010-06-14 17:09:53 -0700 | [diff] [blame] | 87 | 	if (bcn_silence_a) { | 
 | 88 | 		total_silence += bcn_silence_a; | 
 | 89 | 		num_active_rx++; | 
 | 90 | 	} | 
 | 91 | 	if (bcn_silence_b) { | 
 | 92 | 		total_silence += bcn_silence_b; | 
 | 93 | 		num_active_rx++; | 
 | 94 | 	} | 
 | 95 | 	if (bcn_silence_c) { | 
 | 96 | 		total_silence += bcn_silence_c; | 
 | 97 | 		num_active_rx++; | 
 | 98 | 	} | 
 | 99 |  | 
 | 100 | 	/* Average among active antennas */ | 
 | 101 | 	if (num_active_rx) | 
 | 102 | 		last_rx_noise = (total_silence / num_active_rx) - 107; | 
 | 103 | 	else | 
 | 104 | 		last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; | 
 | 105 |  | 
 | 106 | 	IWL_DEBUG_CALIB(priv, "inband silence a %u, b %u, c %u, dBm %d\n", | 
 | 107 | 			bcn_silence_a, bcn_silence_b, bcn_silence_c, | 
 | 108 | 			last_rx_noise); | 
 | 109 | } | 
 | 110 |  | 
 | 111 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 
 | 112 | /* | 
 | 113 |  *  based on the assumption of all statistics counter are in DWORD | 
 | 114 |  *  FIXME: This function is for debugging, do not deal with | 
 | 115 |  *  the case of counters roll-over. | 
 | 116 |  */ | 
 | 117 | static void iwl_accumulative_statistics(struct iwl_priv *priv, | 
 | 118 | 					__le32 *stats) | 
 | 119 | { | 
| Wey-Yi Guy | 7980fba | 2010-07-14 08:08:57 -0700 | [diff] [blame] | 120 | 	int i, size; | 
| Wey-Yi Guy | 278fc73 | 2010-06-14 17:09:53 -0700 | [diff] [blame] | 121 | 	__le32 *prev_stats; | 
 | 122 | 	u32 *accum_stats; | 
 | 123 | 	u32 *delta, *max_delta; | 
| Wey-Yi Guy | 7980fba | 2010-07-14 08:08:57 -0700 | [diff] [blame] | 124 | 	struct statistics_general_common *general, *accum_general; | 
 | 125 | 	struct statistics_tx *tx, *accum_tx; | 
| Wey-Yi Guy | 278fc73 | 2010-06-14 17:09:53 -0700 | [diff] [blame] | 126 |  | 
| Wey-Yi Guy | 7980fba | 2010-07-14 08:08:57 -0700 | [diff] [blame] | 127 | 	if (priv->cfg->bt_statistics) { | 
 | 128 | 		prev_stats = (__le32 *)&priv->_agn.statistics_bt; | 
 | 129 | 		accum_stats = (u32 *)&priv->_agn.accum_statistics_bt; | 
 | 130 | 		size = sizeof(struct iwl_bt_notif_statistics); | 
 | 131 | 		general = &priv->_agn.statistics_bt.general.common; | 
 | 132 | 		accum_general = &priv->_agn.accum_statistics_bt.general.common; | 
 | 133 | 		tx = &priv->_agn.statistics_bt.tx; | 
 | 134 | 		accum_tx = &priv->_agn.accum_statistics_bt.tx; | 
 | 135 | 		delta = (u32 *)&priv->_agn.delta_statistics_bt; | 
 | 136 | 		max_delta = (u32 *)&priv->_agn.max_delta_bt; | 
 | 137 | 	} else { | 
 | 138 | 		prev_stats = (__le32 *)&priv->_agn.statistics; | 
 | 139 | 		accum_stats = (u32 *)&priv->_agn.accum_statistics; | 
 | 140 | 		size = sizeof(struct iwl_notif_statistics); | 
 | 141 | 		general = &priv->_agn.statistics.general.common; | 
 | 142 | 		accum_general = &priv->_agn.accum_statistics.general.common; | 
 | 143 | 		tx = &priv->_agn.statistics.tx; | 
 | 144 | 		accum_tx = &priv->_agn.accum_statistics.tx; | 
 | 145 | 		delta = (u32 *)&priv->_agn.delta_statistics; | 
 | 146 | 		max_delta = (u32 *)&priv->_agn.max_delta; | 
 | 147 | 	} | 
 | 148 | 	for (i = sizeof(__le32); i < size; | 
| Wey-Yi Guy | 278fc73 | 2010-06-14 17:09:53 -0700 | [diff] [blame] | 149 | 	     i += sizeof(__le32), stats++, prev_stats++, delta++, | 
 | 150 | 	     max_delta++, accum_stats++) { | 
 | 151 | 		if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { | 
 | 152 | 			*delta = (le32_to_cpu(*stats) - | 
 | 153 | 				le32_to_cpu(*prev_stats)); | 
 | 154 | 			*accum_stats += *delta; | 
 | 155 | 			if (*delta > *max_delta) | 
 | 156 | 				*max_delta = *delta; | 
 | 157 | 		} | 
 | 158 | 	} | 
 | 159 |  | 
 | 160 | 	/* reset accumulative statistics for "no-counter" type statistics */ | 
| Wey-Yi Guy | 7980fba | 2010-07-14 08:08:57 -0700 | [diff] [blame] | 161 | 	accum_general->temperature = general->temperature; | 
 | 162 | 	accum_general->temperature_m = general->temperature_m; | 
 | 163 | 	accum_general->ttl_timestamp = general->ttl_timestamp; | 
 | 164 | 	accum_tx->tx_power.ant_a = tx->tx_power.ant_a; | 
 | 165 | 	accum_tx->tx_power.ant_b = tx->tx_power.ant_b; | 
 | 166 | 	accum_tx->tx_power.ant_c = tx->tx_power.ant_c; | 
| Wey-Yi Guy | 278fc73 | 2010-06-14 17:09:53 -0700 | [diff] [blame] | 167 | } | 
 | 168 | #endif | 
 | 169 |  | 
 | 170 | #define REG_RECALIB_PERIOD (60) | 
 | 171 |  | 
 | 172 | /** | 
 | 173 |  * iwl_good_plcp_health - checks for plcp error. | 
 | 174 |  * | 
 | 175 |  * When the plcp error is exceeding the thresholds, reset the radio | 
 | 176 |  * to improve the throughput. | 
 | 177 |  */ | 
 | 178 | bool iwl_good_plcp_health(struct iwl_priv *priv, | 
 | 179 | 				struct iwl_rx_packet *pkt) | 
 | 180 | { | 
 | 181 | 	bool rc = true; | 
 | 182 | 	int combined_plcp_delta; | 
 | 183 | 	unsigned int plcp_msec; | 
 | 184 | 	unsigned long plcp_received_jiffies; | 
 | 185 |  | 
| Wey-Yi Guy | 680788a | 2010-06-17 15:25:00 -0700 | [diff] [blame] | 186 | 	if (priv->cfg->plcp_delta_threshold == | 
 | 187 | 	    IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { | 
 | 188 | 		IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); | 
 | 189 | 		return rc; | 
 | 190 | 	} | 
 | 191 |  | 
| Wey-Yi Guy | 278fc73 | 2010-06-14 17:09:53 -0700 | [diff] [blame] | 192 | 	/* | 
 | 193 | 	 * check for plcp_err and trigger radio reset if it exceeds | 
 | 194 | 	 * the plcp error threshold plcp_delta. | 
 | 195 | 	 */ | 
 | 196 | 	plcp_received_jiffies = jiffies; | 
 | 197 | 	plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - | 
 | 198 | 					(long) priv->plcp_jiffies); | 
 | 199 | 	priv->plcp_jiffies = plcp_received_jiffies; | 
 | 200 | 	/* | 
 | 201 | 	 * check to make sure plcp_msec is not 0 to prevent division | 
 | 202 | 	 * by zero. | 
 | 203 | 	 */ | 
 | 204 | 	if (plcp_msec) { | 
| Wey-Yi Guy | 7980fba | 2010-07-14 08:08:57 -0700 | [diff] [blame] | 205 | 		struct statistics_rx_phy *ofdm; | 
 | 206 | 		struct statistics_rx_ht_phy *ofdm_ht; | 
 | 207 |  | 
 | 208 | 		if (priv->cfg->bt_statistics) { | 
 | 209 | 			ofdm = &pkt->u.stats_bt.rx.ofdm; | 
 | 210 | 			ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht; | 
 | 211 | 			combined_plcp_delta = | 
 | 212 | 			   (le32_to_cpu(ofdm->plcp_err) - | 
 | 213 | 			   le32_to_cpu(priv->_agn.statistics_bt. | 
 | 214 | 				       rx.ofdm.plcp_err)) + | 
 | 215 | 			   (le32_to_cpu(ofdm_ht->plcp_err) - | 
 | 216 | 			   le32_to_cpu(priv->_agn.statistics_bt. | 
 | 217 | 				       rx.ofdm_ht.plcp_err)); | 
 | 218 | 		} else { | 
 | 219 | 			ofdm = &pkt->u.stats.rx.ofdm; | 
 | 220 | 			ofdm_ht = &pkt->u.stats.rx.ofdm_ht; | 
 | 221 | 			combined_plcp_delta = | 
 | 222 | 			    (le32_to_cpu(ofdm->plcp_err) - | 
 | 223 | 			    le32_to_cpu(priv->_agn.statistics. | 
 | 224 | 					rx.ofdm.plcp_err)) + | 
 | 225 | 			    (le32_to_cpu(ofdm_ht->plcp_err) - | 
 | 226 | 			    le32_to_cpu(priv->_agn.statistics. | 
 | 227 | 					rx.ofdm_ht.plcp_err)); | 
 | 228 | 		} | 
| Wey-Yi Guy | 278fc73 | 2010-06-14 17:09:53 -0700 | [diff] [blame] | 229 |  | 
 | 230 | 		if ((combined_plcp_delta > 0) && | 
 | 231 | 		    ((combined_plcp_delta * 100) / plcp_msec) > | 
 | 232 | 			priv->cfg->plcp_delta_threshold) { | 
 | 233 | 			/* | 
 | 234 | 			 * if plcp_err exceed the threshold, | 
 | 235 | 			 * the following data is printed in csv format: | 
 | 236 | 			 *    Text: plcp_err exceeded %d, | 
 | 237 | 			 *    Received ofdm.plcp_err, | 
 | 238 | 			 *    Current ofdm.plcp_err, | 
 | 239 | 			 *    Received ofdm_ht.plcp_err, | 
 | 240 | 			 *    Current ofdm_ht.plcp_err, | 
 | 241 | 			 *    combined_plcp_delta, | 
 | 242 | 			 *    plcp_msec | 
 | 243 | 			 */ | 
 | 244 | 			IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " | 
| Wey-Yi Guy | 7980fba | 2010-07-14 08:08:57 -0700 | [diff] [blame] | 245 | 				    "%u, %u, %u, %u, %d, %u mSecs\n", | 
 | 246 | 				    priv->cfg->plcp_delta_threshold, | 
 | 247 | 				    le32_to_cpu(ofdm->plcp_err), | 
 | 248 | 				    le32_to_cpu(ofdm->plcp_err), | 
 | 249 | 				    le32_to_cpu(ofdm_ht->plcp_err), | 
 | 250 | 				    le32_to_cpu(ofdm_ht->plcp_err), | 
 | 251 | 				    combined_plcp_delta, plcp_msec); | 
 | 252 |  | 
| Wey-Yi Guy | 278fc73 | 2010-06-14 17:09:53 -0700 | [diff] [blame] | 253 | 			rc = false; | 
 | 254 | 		} | 
 | 255 | 	} | 
 | 256 | 	return rc; | 
 | 257 | } | 
 | 258 |  | 
 | 259 | void iwl_rx_statistics(struct iwl_priv *priv, | 
 | 260 | 			      struct iwl_rx_mem_buffer *rxb) | 
 | 261 | { | 
 | 262 | 	int change; | 
 | 263 | 	struct iwl_rx_packet *pkt = rxb_addr(rxb); | 
 | 264 |  | 
| Wey-Yi Guy | 7980fba | 2010-07-14 08:08:57 -0700 | [diff] [blame] | 265 | 	if (priv->cfg->bt_statistics) { | 
 | 266 | 		IWL_DEBUG_RX(priv, | 
 | 267 | 			     "Statistics notification received (%d vs %d).\n", | 
 | 268 | 			     (int)sizeof(struct iwl_bt_notif_statistics), | 
 | 269 | 			     le32_to_cpu(pkt->len_n_flags) & | 
 | 270 | 			     FH_RSCSR_FRAME_SIZE_MSK); | 
| Wey-Yi Guy | 278fc73 | 2010-06-14 17:09:53 -0700 | [diff] [blame] | 271 |  | 
| Wey-Yi Guy | 7980fba | 2010-07-14 08:08:57 -0700 | [diff] [blame] | 272 | 		change = ((priv->_agn.statistics_bt.general.common.temperature != | 
 | 273 | 			   pkt->u.stats_bt.general.common.temperature) || | 
 | 274 | 			   ((priv->_agn.statistics_bt.flag & | 
 | 275 | 			   STATISTICS_REPLY_FLG_HT40_MODE_MSK) != | 
 | 276 | 			   (pkt->u.stats_bt.flag & | 
 | 277 | 			   STATISTICS_REPLY_FLG_HT40_MODE_MSK))); | 
| Wey-Yi Guy | 278fc73 | 2010-06-14 17:09:53 -0700 | [diff] [blame] | 278 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 
| Wey-Yi Guy | 7980fba | 2010-07-14 08:08:57 -0700 | [diff] [blame] | 279 | 		iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt); | 
| Wey-Yi Guy | 278fc73 | 2010-06-14 17:09:53 -0700 | [diff] [blame] | 280 | #endif | 
| Wey-Yi Guy | 7980fba | 2010-07-14 08:08:57 -0700 | [diff] [blame] | 281 |  | 
 | 282 | 	} else { | 
 | 283 | 		IWL_DEBUG_RX(priv, | 
 | 284 | 			     "Statistics notification received (%d vs %d).\n", | 
 | 285 | 			     (int)sizeof(struct iwl_notif_statistics), | 
 | 286 | 			     le32_to_cpu(pkt->len_n_flags) & | 
 | 287 | 			     FH_RSCSR_FRAME_SIZE_MSK); | 
 | 288 |  | 
 | 289 | 		change = ((priv->_agn.statistics.general.common.temperature != | 
 | 290 | 			   pkt->u.stats.general.common.temperature) || | 
 | 291 | 			   ((priv->_agn.statistics.flag & | 
 | 292 | 			   STATISTICS_REPLY_FLG_HT40_MODE_MSK) != | 
 | 293 | 			   (pkt->u.stats.flag & | 
 | 294 | 			   STATISTICS_REPLY_FLG_HT40_MODE_MSK))); | 
 | 295 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 
 | 296 | 		iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); | 
 | 297 | #endif | 
 | 298 |  | 
 | 299 | 	} | 
 | 300 |  | 
| Wey-Yi Guy | 278fc73 | 2010-06-14 17:09:53 -0700 | [diff] [blame] | 301 | 	iwl_recover_from_statistics(priv, pkt); | 
 | 302 |  | 
| Wey-Yi Guy | 7980fba | 2010-07-14 08:08:57 -0700 | [diff] [blame] | 303 | 	if (priv->cfg->bt_statistics) | 
 | 304 | 		memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt, | 
 | 305 | 			sizeof(priv->_agn.statistics_bt)); | 
 | 306 | 	else | 
 | 307 | 		memcpy(&priv->_agn.statistics, &pkt->u.stats, | 
 | 308 | 			sizeof(priv->_agn.statistics)); | 
| Wey-Yi Guy | 278fc73 | 2010-06-14 17:09:53 -0700 | [diff] [blame] | 309 |  | 
 | 310 | 	set_bit(STATUS_STATISTICS, &priv->status); | 
 | 311 |  | 
 | 312 | 	/* Reschedule the statistics timer to occur in | 
 | 313 | 	 * REG_RECALIB_PERIOD seconds to ensure we get a | 
 | 314 | 	 * thermal update even if the uCode doesn't give | 
 | 315 | 	 * us one */ | 
 | 316 | 	mod_timer(&priv->statistics_periodic, jiffies + | 
 | 317 | 		  msecs_to_jiffies(REG_RECALIB_PERIOD * 1000)); | 
 | 318 |  | 
 | 319 | 	if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && | 
 | 320 | 	    (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { | 
 | 321 | 		iwl_rx_calc_noise(priv); | 
 | 322 | 		queue_work(priv->workqueue, &priv->run_time_calib_work); | 
 | 323 | 	} | 
 | 324 | 	if (priv->cfg->ops->lib->temp_ops.temperature && change) | 
 | 325 | 		priv->cfg->ops->lib->temp_ops.temperature(priv); | 
 | 326 | } | 
 | 327 |  | 
 | 328 | void iwl_reply_statistics(struct iwl_priv *priv, | 
 | 329 | 			      struct iwl_rx_mem_buffer *rxb) | 
 | 330 | { | 
 | 331 | 	struct iwl_rx_packet *pkt = rxb_addr(rxb); | 
 | 332 |  | 
 | 333 | 	if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { | 
 | 334 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 
| Wey-Yi Guy | f3aebee | 2010-06-14 17:09:54 -0700 | [diff] [blame] | 335 | 		memset(&priv->_agn.accum_statistics, 0, | 
| Wey-Yi Guy | 278fc73 | 2010-06-14 17:09:53 -0700 | [diff] [blame] | 336 | 			sizeof(struct iwl_notif_statistics)); | 
| Wey-Yi Guy | f3aebee | 2010-06-14 17:09:54 -0700 | [diff] [blame] | 337 | 		memset(&priv->_agn.delta_statistics, 0, | 
| Wey-Yi Guy | 278fc73 | 2010-06-14 17:09:53 -0700 | [diff] [blame] | 338 | 			sizeof(struct iwl_notif_statistics)); | 
| Wey-Yi Guy | f3aebee | 2010-06-14 17:09:54 -0700 | [diff] [blame] | 339 | 		memset(&priv->_agn.max_delta, 0, | 
| Wey-Yi Guy | 278fc73 | 2010-06-14 17:09:53 -0700 | [diff] [blame] | 340 | 			sizeof(struct iwl_notif_statistics)); | 
| Wey-Yi Guy | 7980fba | 2010-07-14 08:08:57 -0700 | [diff] [blame] | 341 | 		memset(&priv->_agn.accum_statistics_bt, 0, | 
 | 342 | 			sizeof(struct iwl_bt_notif_statistics)); | 
 | 343 | 		memset(&priv->_agn.delta_statistics_bt, 0, | 
 | 344 | 			sizeof(struct iwl_bt_notif_statistics)); | 
 | 345 | 		memset(&priv->_agn.max_delta_bt, 0, | 
 | 346 | 			sizeof(struct iwl_bt_notif_statistics)); | 
| Wey-Yi Guy | 278fc73 | 2010-06-14 17:09:53 -0700 | [diff] [blame] | 347 | #endif | 
 | 348 | 		IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); | 
 | 349 | 	} | 
 | 350 | 	iwl_rx_statistics(priv, rxb); | 
 | 351 | } |