eeprom.c 34.3 KB
Newer Older
1 2 3 4 5 6 7
/******************************************************************************
 *
 * This file is provided under a dual BSD/GPLv2 license.  When using or
 * redistributing this file, you may do so under either license.
 *
 * GPL LICENSE SUMMARY
 *
W
Wey-Yi Guy 已提交
8
 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
 * USA
 *
 * The full GNU General Public License is included in this distribution
 * in the file called LICENSE.GPL.
 *
 * Contact Information:
28
 *  Intel Linux Wireless <ilw@linux.intel.com>
29 30 31 32
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 *
 * BSD LICENSE
 *
W
Wey-Yi Guy 已提交
33
 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name Intel Corporation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *****************************************************************************/


#include <linux/kernel.h>
#include <linux/module.h>
66
#include <linux/slab.h>
67 68
#include <linux/init.h>
#include <net/mac80211.h>
69
#include "iwl-io.h"
70
#include "iwl-prph.h"
71 72 73 74
#include "iwl-debug.h"
#include "dev.h"
#include "agn.h"
#include "eeprom.h"
75

76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
/************************** EEPROM BANDS ****************************
 *
 * The iwl_eeprom_band definitions below provide the mapping from the
 * EEPROM contents to the specific channel number supported for each
 * band.
 *
 * For example, iwl_priv->eeprom.band_3_channels[4] from the band_3
 * definition below maps to physical channel 42 in the 5.2GHz spectrum.
 * The specific geography and calibration information for that channel
 * is contained in the eeprom map itself.
 *
 * During init, we copy the eeprom information and channel map
 * information into priv->channel_info_24/52 and priv->channel_map_24/52
 *
 * channel_map_24/52 provides the index in the channel_info array for a
 * given channel.  We have to have two separate maps as there is channel
 * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and
 * band_2
 *
 * A value of 0xff stored in the channel_map indicates that the channel
 * is not supported by the hardware at all.
 *
 * A value of 0xfe in the channel_map indicates that the channel is not
 * valid for Tx with the current hardware.  This means that
 * while the system can tune and receive on a given channel, it may not
 * be able to associate or transmit any frames on that
 * channel.  There is no corresponding channel information for that
 * entry.
 *
 *********************************************************************/

/* 2.4 GHz */
const u8 iwl_eeprom_band_1[14] = {
	1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
};

/* 5.2 GHz bands */
static const u8 iwl_eeprom_band_2[] = {	/* 4915-5080MHz */
	183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16
};

static const u8 iwl_eeprom_band_3[] = {	/* 5170-5320MHz */
	34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64
};

static const u8 iwl_eeprom_band_4[] = {	/* 5500-5700MHz */
	100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
};

static const u8 iwl_eeprom_band_5[] = {	/* 5725-5825MHz */
	145, 149, 153, 157, 161, 165
};

129
static const u8 iwl_eeprom_band_6[] = {       /* 2.4 ht40 channel */
130 131 132
	1, 2, 3, 4, 5, 6, 7
};

133
static const u8 iwl_eeprom_band_7[] = {       /* 5.2 ht40 channel */
134 135 136
	36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157
};

137 138
/******************************************************************************
 *
139
 * generic NVM functions
140 141 142
 *
******************************************************************************/

D
Don Fry 已提交
143 144 145 146 147 148
/*
 * 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.
 */
149 150 151 152

#define	EEPROM_SEM_TIMEOUT 10		/* milliseconds */
#define EEPROM_SEM_RETRY_LIMIT 1000	/* number of attempts (not time) */

153
static int iwl_eeprom_acquire_semaphore(struct iwl_trans *trans)
D
Don Fry 已提交
154 155 156 157 158 159
{
	u16 count;
	int ret;

	for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
		/* Request semaphore */
160
		iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
D
Don Fry 已提交
161 162 163
			    CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);

		/* See if we got it */
164
		ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG,
D
Don Fry 已提交
165 166 167 168
				CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
				CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
				EEPROM_SEM_TIMEOUT);
		if (ret >= 0) {
169
			IWL_DEBUG_EEPROM(trans,
D
Don Fry 已提交
170 171 172 173 174 175 176 177 178
				"Acquired semaphore after %d tries.\n",
				count+1);
			return ret;
		}
	}

	return ret;
}

179
static void iwl_eeprom_release_semaphore(struct iwl_trans *trans)
D
Don Fry 已提交
180
{
181
	iwl_clear_bit(trans, CSR_HW_IF_CONFIG_REG,
D
Don Fry 已提交
182 183 184 185
		CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);

}

J
Johannes Berg 已提交
186
static int iwl_eeprom_verify_signature(struct iwl_priv *priv)
187
{
188
	u32 gp = iwl_read32(priv->trans, CSR_EEPROM_GP) &
189
			   CSR_EEPROM_GP_VALID_MSK;
190 191
	int ret = 0;

J
Johannes Berg 已提交
192
	IWL_DEBUG_EEPROM(priv, "EEPROM signature=0x%08x\n", gp);
193 194
	switch (gp) {
	case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP:
J
Johannes Berg 已提交
195 196
		if (priv->nvm_device_type != NVM_DEVICE_TYPE_OTP) {
			IWL_ERR(priv, "EEPROM with bad signature: 0x%08x\n",
197 198 199 200 201 202
				gp);
			ret = -ENOENT;
		}
		break;
	case CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K:
	case CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K:
J
Johannes Berg 已提交
203 204
		if (priv->nvm_device_type != NVM_DEVICE_TYPE_EEPROM) {
			IWL_ERR(priv, "OTP with bad signature: 0x%08x\n", gp);
205 206 207 208 209
			ret = -ENOENT;
		}
		break;
	case CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP:
	default:
J
Johannes Berg 已提交
210
		IWL_ERR(priv, "bad EEPROM/OTP signature, type=%s, "
211
			"EEPROM_GP=0x%08x\n",
J
Johannes Berg 已提交
212
			(priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
213 214 215
			? "OTP" : "EEPROM", gp);
		ret = -ENOENT;
		break;
216
	}
217
	return ret;
218 219
}

J
Johannes Berg 已提交
220
u16 iwl_eeprom_query16(struct iwl_priv *priv, size_t offset)
221
{
J
Johannes Berg 已提交
222
	if (!priv->eeprom)
223
		return 0;
J
Johannes Berg 已提交
224
	return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8);
225 226 227 228 229 230 231
}

int iwl_eeprom_check_version(struct iwl_priv *priv)
{
	u16 eeprom_ver;
	u16 calib_ver;

J
Johannes Berg 已提交
232 233
	eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
	calib_ver = iwl_eeprom_calib_version(priv);
234

235 236
	if (eeprom_ver < priv->cfg->eeprom_ver ||
	    calib_ver < priv->cfg->eeprom_calib_ver)
237 238 239 240 241 242 243 244 245
		goto err;

	IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n",
		 eeprom_ver, calib_ver);

	return 0;
err:
	IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x "
		  "CALIB=0x%x < 0x%x\n",
246 247
		  eeprom_ver, priv->cfg->eeprom_ver,
		  calib_ver,  priv->cfg->eeprom_calib_ver);
248 249 250 251
	return -EINVAL;

}

J
Johannes Berg 已提交
252
int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
253 254 255
{
	u16 radio_cfg;

J
Johannes Berg 已提交
256
	priv->hw_params.sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP);
257
	if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE &&
258
	    !priv->cfg->ht_params) {
J
Johannes Berg 已提交
259 260
		IWL_ERR(priv, "Invalid 11n configuration\n");
		return -EINVAL;
261
	}
J
Johannes Berg 已提交
262

263
	if (!priv->hw_params.sku) {
264 265 266 267
		IWL_ERR(priv, "Invalid device sku\n");
		return -EINVAL;
	}

268
	IWL_INFO(priv, "Device SKU: 0x%X\n", priv->hw_params.sku);
269

J
Johannes Berg 已提交
270
	radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
271

272 273
	priv->hw_params.valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg);
	priv->hw_params.valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg);
274 275

	/* check overrides (some devices have wrong EEPROM) */
276 277 278 279
	if (priv->cfg->valid_tx_ant)
		priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
	if (priv->cfg->valid_rx_ant)
		priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
280

281
	if (!priv->hw_params.valid_tx_ant || !priv->hw_params.valid_rx_ant) {
282
		IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n",
283 284
			priv->hw_params.valid_tx_ant,
			priv->hw_params.valid_rx_ant);
285
		return -EINVAL;
286
	}
287

288 289 290 291 292 293 294 295
	priv->hw_params.tx_chains_num =
		num_of_ant(priv->hw_params.valid_tx_ant);
	if (priv->cfg->rx_with_siso_diversity)
		priv->hw_params.rx_chains_num = 1;
	else
		priv->hw_params.rx_chains_num =
			num_of_ant(priv->hw_params.valid_rx_ant);

296
	IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n",
297
		 priv->hw_params.valid_tx_ant, priv->hw_params.valid_rx_ant);
298

299 300 301
	return 0;
}

J
Johannes Berg 已提交
302
u16 iwl_eeprom_calib_version(struct iwl_priv *priv)
303
{
J
Johannes Berg 已提交
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355
	struct iwl_eeprom_calib_hdr *hdr;

	hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv,
							EEPROM_CALIB_ALL);
	return hdr->version;
}

static u32 eeprom_indirect_address(struct iwl_priv *priv, u32 address)
{
	u16 offset = 0;

	if ((address & INDIRECT_ADDRESS) == 0)
		return address;

	switch (address & INDIRECT_TYPE_MSK) {
	case INDIRECT_HOST:
		offset = iwl_eeprom_query16(priv, EEPROM_LINK_HOST);
		break;
	case INDIRECT_GENERAL:
		offset = iwl_eeprom_query16(priv, EEPROM_LINK_GENERAL);
		break;
	case INDIRECT_REGULATORY:
		offset = iwl_eeprom_query16(priv, EEPROM_LINK_REGULATORY);
		break;
	case INDIRECT_TXP_LIMIT:
		offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT);
		break;
	case INDIRECT_TXP_LIMIT_SIZE:
		offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT_SIZE);
		break;
	case INDIRECT_CALIBRATION:
		offset = iwl_eeprom_query16(priv, EEPROM_LINK_CALIBRATION);
		break;
	case INDIRECT_PROCESS_ADJST:
		offset = iwl_eeprom_query16(priv, EEPROM_LINK_PROCESS_ADJST);
		break;
	case INDIRECT_OTHERS:
		offset = iwl_eeprom_query16(priv, EEPROM_LINK_OTHERS);
		break;
	default:
		IWL_ERR(priv, "illegal indirect type: 0x%X\n",
		address & INDIRECT_TYPE_MSK);
		break;
	}

	/* translate the offset from words to byte */
	return (address & ADDRESS_MSK) + (offset << 1);
}

const u8 *iwl_eeprom_query_addr(struct iwl_priv *priv, size_t offset)
{
	u32 address = eeprom_indirect_address(priv, offset);
356
	BUG_ON(address >= priv->cfg->base_params->eeprom_size);
J
Johannes Berg 已提交
357 358 359 360 361 362
	return &priv->eeprom[address];
}

void iwl_eeprom_get_mac(struct iwl_priv *priv, u8 *mac)
{
	const u8 *addr = iwl_eeprom_query_addr(priv,
363 364 365 366 367 368 369 370 371 372
					EEPROM_MAC_ADDRESS);
	memcpy(mac, addr, ETH_ALEN);
}

/******************************************************************************
 *
 * OTP related functions
 *
******************************************************************************/

373 374
static void iwl_set_otp_access(struct iwl_trans *trans,
			       enum iwl_access_mode mode)
375
{
376
	iwl_read32(trans, CSR_OTP_GP_REG);
377 378

	if (mode == IWL_OTP_ACCESS_ABSOLUTE)
379
		iwl_clear_bit(trans, CSR_OTP_GP_REG,
380
			      CSR_OTP_GP_REG_OTP_ACCESS_MODE);
381
	else
382
		iwl_set_bit(trans, CSR_OTP_GP_REG,
383
			    CSR_OTP_GP_REG_OTP_ACCESS_MODE);
384 385
}

386
static int iwl_get_nvm_type(struct iwl_trans *trans, u32 hw_rev)
387 388 389 390 391
{
	u32 otpgp;
	int nvm_type;

	/* OTP only valid for CP/PP and after */
J
Johannes Berg 已提交
392
	switch (hw_rev & CSR_HW_REV_TYPE_MSK) {
W
Wey-Yi Guy 已提交
393
	case CSR_HW_REV_TYPE_NONE:
394
		IWL_ERR(trans, "Unknown hardware type\n");
W
Wey-Yi Guy 已提交
395
		return -ENOENT;
396 397 398 399 400 401 402
	case CSR_HW_REV_TYPE_5300:
	case CSR_HW_REV_TYPE_5350:
	case CSR_HW_REV_TYPE_5100:
	case CSR_HW_REV_TYPE_5150:
		nvm_type = NVM_DEVICE_TYPE_EEPROM;
		break;
	default:
403
		otpgp = iwl_read32(trans, CSR_OTP_GP_REG);
404 405 406 407 408 409 410 411 412
		if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT)
			nvm_type = NVM_DEVICE_TYPE_OTP;
		else
			nvm_type = NVM_DEVICE_TYPE_EEPROM;
		break;
	}
	return  nvm_type;
}

413
static int iwl_init_otp_access(struct iwl_trans *trans)
414 415 416 417
{
	int ret;

	/* Enable 40MHz radio clock */
418 419
	iwl_write32(trans, CSR_GP_CNTRL,
		    iwl_read32(trans, CSR_GP_CNTRL) |
420
		    CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
421 422

	/* wait for clock to be ready */
423
	ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
424 425 426
				 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
				 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
				 25000);
427
	if (ret < 0)
428
		IWL_ERR(trans, "Time out access OTP\n");
429
	else {
430
		iwl_set_bits_prph(trans, APMG_PS_CTRL_REG,
R
Reinette Chatre 已提交
431 432
				  APMG_PS_CTRL_VAL_RESET_REQ);
		udelay(5);
433
		iwl_clear_bits_prph(trans, APMG_PS_CTRL_REG,
R
Reinette Chatre 已提交
434
				    APMG_PS_CTRL_VAL_RESET_REQ);
435 436 437 438 439

		/*
		 * CSR auto clock gate disable bit -
		 * this is only applicable for HW with OTP shadow RAM
		 */
440
		if (trans->cfg->base_params->shadow_ram_support)
441
			iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
442
				CSR_RESET_LINK_PWR_MGMT_DISABLED);
443 444 445 446
	}
	return ret;
}

447 448
static int iwl_read_otp_word(struct iwl_trans *trans, u16 addr,
			     __le16 *eeprom_data)
449 450 451 452 453
{
	int ret = 0;
	u32 r;
	u32 otpgp;

454
	iwl_write32(trans, CSR_EEPROM_REG,
455
		    CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
456
	ret = iwl_poll_bit(trans, CSR_EEPROM_REG,
457 458 459
				 CSR_EEPROM_REG_READ_VALID_MSK,
				 CSR_EEPROM_REG_READ_VALID_MSK,
				 IWL_EEPROM_ACCESS_TIMEOUT);
460
	if (ret < 0) {
461
		IWL_ERR(trans, "Time out reading OTP[%d]\n", addr);
462 463
		return ret;
	}
464
	r = iwl_read32(trans, CSR_EEPROM_REG);
465
	/* check for ECC errors: */
466
	otpgp = iwl_read32(trans, CSR_OTP_GP_REG);
467 468 469
	if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) {
		/* stop in this case */
		/* set the uncorrectable OTP ECC bit for acknowledgement */
470
		iwl_set_bit(trans, CSR_OTP_GP_REG,
471
			CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
472
		IWL_ERR(trans, "Uncorrectable OTP ECC error, abort OTP read\n");
473 474 475 476 477
		return -EINVAL;
	}
	if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) {
		/* continue in this case */
		/* set the correctable OTP ECC bit for acknowledgement */
478
		iwl_set_bit(trans, CSR_OTP_GP_REG,
479
				CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK);
480
		IWL_ERR(trans, "Correctable OTP ECC error, continue read\n");
481
	}
482
	*eeprom_data = cpu_to_le16(r >> 16);
483 484 485 486 487 488
	return 0;
}

/*
 * iwl_is_otp_empty: check for empty OTP
 */
489
static bool iwl_is_otp_empty(struct iwl_trans *trans)
490
{
491 492
	u16 next_link_addr = 0;
	__le16 link_value;
493 494 495
	bool is_empty = false;

	/* locate the beginning of OTP link list */
496
	if (!iwl_read_otp_word(trans, next_link_addr, &link_value)) {
497
		if (!link_value) {
498
			IWL_ERR(trans, "OTP is empty\n");
499 500 501
			is_empty = true;
		}
	} else {
502
		IWL_ERR(trans, "Unable to read first block of OTP list.\n");
503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518
		is_empty = true;
	}

	return is_empty;
}


/*
 * iwl_find_otp_image: find EEPROM image in OTP
 *   finding the OTP block that contains the EEPROM image.
 *   the last valid block on the link list (the block _before_ the last block)
 *   is the block we should read and used to configure the device.
 *   If all the available OTP blocks are full, the last block will be the block
 *   we should read and used to configure the device.
 *   only perform this operation if shadow RAM is disabled
 */
519
static int iwl_find_otp_image(struct iwl_trans *trans,
520 521
					u16 *validblockaddr)
{
522 523
	u16 next_link_addr = 0, valid_addr;
	__le16 link_value = 0;
524 525 526
	int usedblocks = 0;

	/* set addressing mode to absolute to traverse the link list */
527
	iwl_set_otp_access(trans, IWL_OTP_ACCESS_ABSOLUTE);
528 529

	/* checking for empty OTP or error */
530
	if (iwl_is_otp_empty(trans))
531 532 533 534 535 536 537 538 539 540 541 542
		return -EINVAL;

	/*
	 * start traverse link list
	 * until reach the max number of OTP blocks
	 * different devices have different number of OTP blocks
	 */
	do {
		/* save current valid block address
		 * check for more block on the link list
		 */
		valid_addr = next_link_addr;
543
		next_link_addr = le16_to_cpu(link_value) * sizeof(u16);
544
		IWL_DEBUG_EEPROM(trans, "OTP blocks %d addr 0x%x\n",
545
			       usedblocks, next_link_addr);
546
		if (iwl_read_otp_word(trans, next_link_addr, &link_value))
547 548 549
			return -EINVAL;
		if (!link_value) {
			/*
550
			 * reach the end of link list, return success and
551 552 553
			 * set address point to the starting address
			 * of the image
			 */
554 555 556 557
			*validblockaddr = valid_addr;
			/* skip first 2 bytes (link list pointer) */
			*validblockaddr += 2;
			return 0;
558 559 560
		}
		/* more in the link list, continue */
		usedblocks++;
561
	} while (usedblocks <= trans->cfg->base_params->max_ll_items);
562 563

	/* OTP has no valid blocks */
564
	IWL_DEBUG_EEPROM(trans, "OTP has no valid blocks\n");
565
	return -EINVAL;
566 567
}

568 569 570 571 572 573 574 575 576
/******************************************************************************
 *
 * Tx Power related functions
 *
******************************************************************************/
/**
 * iwl_get_max_txpower_avg - get the highest tx power from all chains.
 *     find the highest tx power from all chains for the channel
 */
J
Johannes Berg 已提交
577
static s8 iwl_get_max_txpower_avg(const struct iwl_cfg *cfg,
578 579
		struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
		int element, s8 *max_txpower_in_half_dbm)
580
{
581 582 583
	s8 max_txpower_avg = 0; /* (dBm) */

	/* Take the highest tx power from any valid chains */
584
	if ((cfg->valid_tx_ant & ANT_A) &&
585 586
	    (enhanced_txpower[element].chain_a_max > max_txpower_avg))
		max_txpower_avg = enhanced_txpower[element].chain_a_max;
587
	if ((cfg->valid_tx_ant & ANT_B) &&
588 589
	    (enhanced_txpower[element].chain_b_max > max_txpower_avg))
		max_txpower_avg = enhanced_txpower[element].chain_b_max;
590
	if ((cfg->valid_tx_ant & ANT_C) &&
591 592
	    (enhanced_txpower[element].chain_c_max > max_txpower_avg))
		max_txpower_avg = enhanced_txpower[element].chain_c_max;
593 594 595
	if (((cfg->valid_tx_ant == ANT_AB) |
	    (cfg->valid_tx_ant == ANT_BC) |
	    (cfg->valid_tx_ant == ANT_AC)) &&
596 597
	    (enhanced_txpower[element].mimo2_max > max_txpower_avg))
		max_txpower_avg =  enhanced_txpower[element].mimo2_max;
598
	if ((cfg->valid_tx_ant == ANT_ABC) &&
599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652
	    (enhanced_txpower[element].mimo3_max > max_txpower_avg))
		max_txpower_avg = enhanced_txpower[element].mimo3_max;

	/*
	 * max. tx power in EEPROM is in 1/2 dBm format
	 * convert from 1/2 dBm to dBm (round-up convert)
	 * but we also do not want to loss 1/2 dBm resolution which
	 * will impact performance
	 */
	*max_txpower_in_half_dbm = max_txpower_avg;
	return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1);
}

static void
iwl_eeprom_enh_txp_read_element(struct iwl_priv *priv,
				    struct iwl_eeprom_enhanced_txpwr *txp,
				    s8 max_txpower_avg)
{
	int ch_idx;
	bool is_ht40 = txp->flags & IWL_EEPROM_ENH_TXP_FL_40MHZ;
	enum ieee80211_band band;

	band = txp->flags & IWL_EEPROM_ENH_TXP_FL_BAND_52G ?
		IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ;

	for (ch_idx = 0; ch_idx < priv->channel_count; ch_idx++) {
		struct iwl_channel_info *ch_info = &priv->channel_info[ch_idx];

		/* update matching channel or from common data only */
		if (txp->channel != 0 && ch_info->channel != txp->channel)
			continue;

		/* update matching band only */
		if (band != ch_info->band)
			continue;

		if (ch_info->max_power_avg < max_txpower_avg && !is_ht40) {
			ch_info->max_power_avg = max_txpower_avg;
			ch_info->curr_txpow = max_txpower_avg;
			ch_info->scan_power = max_txpower_avg;
		}

		if (is_ht40 && ch_info->ht40_max_power_avg < max_txpower_avg)
			ch_info->ht40_max_power_avg = max_txpower_avg;
	}
}

#define EEPROM_TXP_OFFS	(0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT)
#define EEPROM_TXP_ENTRY_LEN sizeof(struct iwl_eeprom_enhanced_txpwr)
#define EEPROM_TXP_SZ_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT_SIZE)

#define TXP_CHECK_AND_PRINT(x) ((txp->flags & IWL_EEPROM_ENH_TXP_FL_##x) \
			    ? # x " " : "")

653
static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv)
654 655 656 657 658 659 660 661 662
{
	struct iwl_eeprom_enhanced_txpwr *txp_array, *txp;
	int idx, entries;
	__le16 *txp_len;
	s8 max_txp_avg, max_txp_avg_halfdbm;

	BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8);

	/* the length is in 16-bit words, but we want entries */
J
Johannes Berg 已提交
663
	txp_len = (__le16 *) iwl_eeprom_query_addr(priv, EEPROM_TXP_SZ_OFFS);
664 665
	entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN;

J
Johannes Berg 已提交
666
	txp_array = (void *) iwl_eeprom_query_addr(priv, EEPROM_TXP_OFFS);
667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699

	for (idx = 0; idx < entries; idx++) {
		txp = &txp_array[idx];
		/* skip invalid entries */
		if (!(txp->flags & IWL_EEPROM_ENH_TXP_FL_VALID))
			continue;

		IWL_DEBUG_EEPROM(priv, "%s %d:\t %s%s%s%s%s%s%s%s (0x%02x)\n",
				 (txp->channel && (txp->flags &
					IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE)) ?
					"Common " : (txp->channel) ?
					"Channel" : "Common",
				 (txp->channel),
				 TXP_CHECK_AND_PRINT(VALID),
				 TXP_CHECK_AND_PRINT(BAND_52G),
				 TXP_CHECK_AND_PRINT(OFDM),
				 TXP_CHECK_AND_PRINT(40MHZ),
				 TXP_CHECK_AND_PRINT(HT_AP),
				 TXP_CHECK_AND_PRINT(RES1),
				 TXP_CHECK_AND_PRINT(RES2),
				 TXP_CHECK_AND_PRINT(COMMON_TYPE),
				 txp->flags);
		IWL_DEBUG_EEPROM(priv, "\t\t chain_A: 0x%02x "
				 "chain_B: 0X%02x chain_C: 0X%02x\n",
				 txp->chain_a_max, txp->chain_b_max,
				 txp->chain_c_max);
		IWL_DEBUG_EEPROM(priv, "\t\t MIMO2: 0x%02x "
				 "MIMO3: 0x%02x High 20_on_40: 0x%02x "
				 "Low 20_on_40: 0x%02x\n",
				 txp->mimo2_max, txp->mimo3_max,
				 ((txp->delta_20_in_40 & 0xf0) >> 4),
				 (txp->delta_20_in_40 & 0x0f));

700
		max_txp_avg = iwl_get_max_txpower_avg(priv->cfg, txp_array, idx,
701 702 703 704 705 706 707 708 709 710 711 712 713
						      &max_txp_avg_halfdbm);

		/*
		 * Update the user limit values values to the highest
		 * power supported by any channel
		 */
		if (max_txp_avg > priv->tx_power_user_lmt)
			priv->tx_power_user_lmt = max_txp_avg;
		if (max_txp_avg_halfdbm > priv->tx_power_lmt_in_half_dbm)
			priv->tx_power_lmt_in_half_dbm = max_txp_avg_halfdbm;

		iwl_eeprom_enh_txp_read_element(priv, txp, max_txp_avg);
	}
714 715
}

716 717 718
/**
 * iwl_eeprom_init - read EEPROM contents
 *
J
Johannes Berg 已提交
719
 * Load the EEPROM contents from adapter into priv->eeprom
720 721 722
 *
 * NOTE:  This routine uses the non-debug IO access functions.
 */
J
Johannes Berg 已提交
723
int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
724
{
725
	__le16 *e;
726
	u32 gp = iwl_read32(priv->trans, CSR_EEPROM_GP);
727
	int sz;
728 729
	int ret;
	u16 addr;
730 731
	u16 validblockaddr = 0;
	u16 cache_addr = 0;
732

733
	priv->nvm_device_type = iwl_get_nvm_type(priv->trans, hw_rev);
J
Johannes Berg 已提交
734
	if (priv->nvm_device_type == -ENOENT)
W
Wey-Yi Guy 已提交
735
		return -ENOENT;
736
	/* allocate eeprom */
737
	sz = priv->cfg->base_params->eeprom_size;
J
Johannes Berg 已提交
738 739 740
	IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz);
	priv->eeprom = kzalloc(sz, GFP_KERNEL);
	if (!priv->eeprom) {
741 742 743
		ret = -ENOMEM;
		goto alloc_err;
	}
J
Johannes Berg 已提交
744
	e = (__le16 *)priv->eeprom;
745

J
Johannes Berg 已提交
746
	ret = iwl_eeprom_verify_signature(priv);
747
	if (ret < 0) {
J
Johannes Berg 已提交
748
		IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
749 750
		ret = -ENOENT;
		goto err;
751 752 753
	}

	/* Make sure driver (instead of uCode) is allowed to read EEPROM */
754
	ret = iwl_eeprom_acquire_semaphore(priv->trans);
755
	if (ret < 0) {
J
Johannes Berg 已提交
756
		IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n");
757 758
		ret = -ENOENT;
		goto err;
759
	}
760

J
Johannes Berg 已提交
761
	if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) {
762

763
		ret = iwl_init_otp_access(priv->trans);
764
		if (ret) {
J
Johannes Berg 已提交
765
			IWL_ERR(priv, "Failed to initialize OTP access.\n");
766
			ret = -ENOENT;
767
			goto done;
768
		}
769 770
		iwl_write32(priv->trans, CSR_EEPROM_GP,
			    iwl_read32(priv->trans, CSR_EEPROM_GP) &
771
			    ~CSR_EEPROM_GP_IF_OWNER_MSK);
772

773
		iwl_set_bit(priv->trans, CSR_OTP_GP_REG,
774 775
			     CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
			     CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
776
		/* traversing the linked list if no shadow ram supported */
777
		if (!priv->cfg->base_params->shadow_ram_support) {
778
			if (iwl_find_otp_image(priv->trans, &validblockaddr)) {
779
				ret = -ENOENT;
780 781
				goto done;
			}
782 783 784
		}
		for (addr = validblockaddr; addr < validblockaddr + sz;
		     addr += sizeof(u16)) {
785
			__le16 eeprom_data;
786

787
			ret = iwl_read_otp_word(priv->trans, addr,
J
Johannes Berg 已提交
788
						&eeprom_data);
789
			if (ret)
790
				goto done;
791 792
			e[cache_addr / 2] = eeprom_data;
			cache_addr += sizeof(u16);
793 794 795 796 797 798
		}
	} else {
		/* eeprom is an array of 16bit values */
		for (addr = 0; addr < sz; addr += sizeof(u16)) {
			u32 r;

799
			iwl_write32(priv->trans, CSR_EEPROM_REG,
800
				    CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
801

802
			ret = iwl_poll_bit(priv->trans, CSR_EEPROM_REG,
803
						  CSR_EEPROM_REG_READ_VALID_MSK,
804 805 806
						  CSR_EEPROM_REG_READ_VALID_MSK,
						  IWL_EEPROM_ACCESS_TIMEOUT);
			if (ret < 0) {
J
Johannes Berg 已提交
807
				IWL_ERR(priv,
808
					"Time out reading EEPROM[%d]\n", addr);
809 810
				goto done;
			}
811
			r = iwl_read32(priv->trans, CSR_EEPROM_REG);
812
			e[addr / 2] = cpu_to_le16(r >> 16);
813 814
		}
	}
815

J
Johannes Berg 已提交
816 817
	IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n",
		       (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
818
		       ? "OTP" : "EEPROM",
J
Johannes Berg 已提交
819
		       iwl_eeprom_query16(priv, EEPROM_VERSION));
820

821 822
	ret = 0;
done:
823
	iwl_eeprom_release_semaphore(priv->trans);
824

825 826
err:
	if (ret)
J
Johannes Berg 已提交
827
		iwl_eeprom_free(priv);
828
alloc_err:
829 830 831
	return ret;
}

J
Johannes Berg 已提交
832
void iwl_eeprom_free(struct iwl_priv *priv)
833
{
J
Johannes Berg 已提交
834 835
	kfree(priv->eeprom);
	priv->eeprom = NULL;
836 837
}

J
Johannes Berg 已提交
838
static void iwl_init_band_reference(struct iwl_priv *priv,
839 840 841
			int eep_band, int *eeprom_ch_count,
			const struct iwl_eeprom_channel **eeprom_ch_info,
			const u8 **eeprom_ch_index)
842
{
843
	u32 offset = priv->lib->
844 845
			eeprom_ops.regulatory_bands[eep_band - 1];
	switch (eep_band) {
846 847
	case 1:		/* 2.4GHz band */
		*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1);
848
		*eeprom_ch_info = (struct iwl_eeprom_channel *)
J
Johannes Berg 已提交
849
				iwl_eeprom_query_addr(priv, offset);
850 851 852 853
		*eeprom_ch_index = iwl_eeprom_band_1;
		break;
	case 2:		/* 4.9GHz band */
		*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2);
854
		*eeprom_ch_info = (struct iwl_eeprom_channel *)
J
Johannes Berg 已提交
855
				iwl_eeprom_query_addr(priv, offset);
856 857 858 859
		*eeprom_ch_index = iwl_eeprom_band_2;
		break;
	case 3:		/* 5.2GHz band */
		*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3);
860
		*eeprom_ch_info = (struct iwl_eeprom_channel *)
J
Johannes Berg 已提交
861
				iwl_eeprom_query_addr(priv, offset);
862 863 864 865
		*eeprom_ch_index = iwl_eeprom_band_3;
		break;
	case 4:		/* 5.5GHz band */
		*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4);
866
		*eeprom_ch_info = (struct iwl_eeprom_channel *)
J
Johannes Berg 已提交
867
				iwl_eeprom_query_addr(priv, offset);
868 869 870 871
		*eeprom_ch_index = iwl_eeprom_band_4;
		break;
	case 5:		/* 5.7GHz band */
		*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5);
872
		*eeprom_ch_info = (struct iwl_eeprom_channel *)
J
Johannes Berg 已提交
873
				iwl_eeprom_query_addr(priv, offset);
874 875
		*eeprom_ch_index = iwl_eeprom_band_5;
		break;
876
	case 6:		/* 2.4GHz ht40 channels */
877
		*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_6);
878
		*eeprom_ch_info = (struct iwl_eeprom_channel *)
J
Johannes Berg 已提交
879
				iwl_eeprom_query_addr(priv, offset);
880 881
		*eeprom_ch_index = iwl_eeprom_band_6;
		break;
882
	case 7:		/* 5 GHz ht40 channels */
883
		*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_7);
884
		*eeprom_ch_info = (struct iwl_eeprom_channel *)
J
Johannes Berg 已提交
885
				iwl_eeprom_query_addr(priv, offset);
886 887 888 889 890 891 892 893 894 895 896
		*eeprom_ch_index = iwl_eeprom_band_7;
		break;
	default:
		BUG();
		return;
	}
}

#define CHECK_AND_PRINT(x) ((eeprom_ch->flags & EEPROM_CHANNEL_##x) \
			    ? # x " " : "")
/**
897
 * iwl_mod_ht40_chan_info - Copy ht40 channel info into driver's priv.
898 899 900
 *
 * Does not set up a command, or touch hardware.
 */
901
static int iwl_mod_ht40_chan_info(struct iwl_priv *priv,
902
			      enum ieee80211_band band, u16 channel,
903
			      const struct iwl_eeprom_channel *eeprom_ch,
904
			      u8 clear_ht40_extension_channel)
905 906 907 908
{
	struct iwl_channel_info *ch_info;

	ch_info = (struct iwl_channel_info *)
909
			iwl_get_channel_info(priv, band, channel);
910 911 912 913

	if (!is_channel_valid(ch_info))
		return -1;

914
	IWL_DEBUG_EEPROM(priv, "HT40 Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):"
915
			" Ad-Hoc %ssupported\n",
916 917 918 919 920 921 922 923 924 925 926 927 928 929
			ch_info->channel,
			is_channel_a_band(ch_info) ?
			"5.2" : "2.4",
			CHECK_AND_PRINT(IBSS),
			CHECK_AND_PRINT(ACTIVE),
			CHECK_AND_PRINT(RADAR),
			CHECK_AND_PRINT(WIDE),
			CHECK_AND_PRINT(DFS),
			eeprom_ch->flags,
			eeprom_ch->max_power_avg,
			((eeprom_ch->flags & EEPROM_CHANNEL_IBSS)
			 && !(eeprom_ch->flags & EEPROM_CHANNEL_RADAR)) ?
			"" : "not ");

930 931 932
	ch_info->ht40_eeprom = *eeprom_ch;
	ch_info->ht40_max_power_avg = eeprom_ch->max_power_avg;
	ch_info->ht40_flags = eeprom_ch->flags;
933 934
	if (eeprom_ch->flags & EEPROM_CHANNEL_VALID)
		ch_info->ht40_extension_channel &= ~clear_ht40_extension_channel;
935 936 937 938 939 940 941 942 943 944 945 946 947 948

	return 0;
}

#define CHECK_AND_PRINT_I(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \
			    ? # x " " : "")

/**
 * iwl_init_channel_map - Set up driver's info for all possible channels
 */
int iwl_init_channel_map(struct iwl_priv *priv)
{
	int eeprom_ch_count = 0;
	const u8 *eeprom_ch_index = NULL;
949
	const struct iwl_eeprom_channel *eeprom_ch_info = NULL;
950 951 952 953
	int band, ch;
	struct iwl_channel_info *ch_info;

	if (priv->channel_count) {
954
		IWL_DEBUG_EEPROM(priv, "Channel map already initialized.\n");
955 956 957
		return 0;
	}

958
	IWL_DEBUG_EEPROM(priv, "Initializing regulatory info from EEPROM\n");
959 960 961 962 963 964 965 966

	priv->channel_count =
	    ARRAY_SIZE(iwl_eeprom_band_1) +
	    ARRAY_SIZE(iwl_eeprom_band_2) +
	    ARRAY_SIZE(iwl_eeprom_band_3) +
	    ARRAY_SIZE(iwl_eeprom_band_4) +
	    ARRAY_SIZE(iwl_eeprom_band_5);

967 968
	IWL_DEBUG_EEPROM(priv, "Parsing data for %d channels.\n",
			priv->channel_count);
969

970 971 972
	priv->channel_info = kcalloc(priv->channel_count,
				     sizeof(struct iwl_channel_info),
				     GFP_KERNEL);
973
	if (!priv->channel_info) {
974
		IWL_ERR(priv, "Could not allocate channel_info\n");
975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001
		priv->channel_count = 0;
		return -ENOMEM;
	}

	ch_info = priv->channel_info;

	/* Loop through the 5 EEPROM bands adding them in order to the
	 * channel map we maintain (that contains additional information than
	 * what just in the EEPROM) */
	for (band = 1; band <= 5; band++) {

		iwl_init_band_reference(priv, band, &eeprom_ch_count,
					&eeprom_ch_info, &eeprom_ch_index);

		/* Loop through each band adding each of the channels */
		for (ch = 0; ch < eeprom_ch_count; ch++) {
			ch_info->channel = eeprom_ch_index[ch];
			ch_info->band = (band == 1) ? IEEE80211_BAND_2GHZ :
			    IEEE80211_BAND_5GHZ;

			/* permanently store EEPROM's channel regulatory flags
			 *   and max power in channel info database. */
			ch_info->eeprom = eeprom_ch_info[ch];

			/* Copy the run-time flags so they are there even on
			 * invalid channels */
			ch_info->flags = eeprom_ch_info[ch].flags;
1002
			/* First write that ht40 is not enabled, and then enable
1003
			 * one by one */
1004
			ch_info->ht40_extension_channel =
1005
					IEEE80211_CHAN_NO_HT40;
1006 1007

			if (!(is_channel_valid(ch_info))) {
1008 1009
				IWL_DEBUG_EEPROM(priv,
					       "Ch. %d Flags %x [%sGHz] - "
1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024
					       "No traffic\n",
					       ch_info->channel,
					       ch_info->flags,
					       is_channel_a_band(ch_info) ?
					       "5.2" : "2.4");
				ch_info++;
				continue;
			}

			/* Initialize regulatory-based run-time data */
			ch_info->max_power_avg = ch_info->curr_txpow =
			    eeprom_ch_info[ch].max_power_avg;
			ch_info->scan_power = eeprom_ch_info[ch].max_power_avg;
			ch_info->min_power = 0;

1025 1026
			IWL_DEBUG_EEPROM(priv, "Ch. %d [%sGHz] "
				       "%s%s%s%s%s%s(0x%02x %ddBm):"
1027
				       " Ad-Hoc %ssupported\n",
1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048
				       ch_info->channel,
				       is_channel_a_band(ch_info) ?
				       "5.2" : "2.4",
				       CHECK_AND_PRINT_I(VALID),
				       CHECK_AND_PRINT_I(IBSS),
				       CHECK_AND_PRINT_I(ACTIVE),
				       CHECK_AND_PRINT_I(RADAR),
				       CHECK_AND_PRINT_I(WIDE),
				       CHECK_AND_PRINT_I(DFS),
				       eeprom_ch_info[ch].flags,
				       eeprom_ch_info[ch].max_power_avg,
				       ((eeprom_ch_info[ch].
					 flags & EEPROM_CHANNEL_IBSS)
					&& !(eeprom_ch_info[ch].
					     flags & EEPROM_CHANNEL_RADAR))
				       ? "" : "not ");

			ch_info++;
		}
	}

1049
	/* Check if we do have HT40 channels */
1050
	if (priv->lib->eeprom_ops.regulatory_bands[5] ==
1051
	    EEPROM_REGULATORY_BAND_NO_HT40 &&
1052
	    priv->lib->eeprom_ops.regulatory_bands[6] ==
1053
	    EEPROM_REGULATORY_BAND_NO_HT40)
1054 1055
		return 0;

1056
	/* Two additional EEPROM bands for 2.4 and 5 GHz HT40 channels */
1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069
	for (band = 6; band <= 7; band++) {
		enum ieee80211_band ieeeband;

		iwl_init_band_reference(priv, band, &eeprom_ch_count,
					&eeprom_ch_info, &eeprom_ch_index);

		/* EEPROM band 6 is 2.4, band 7 is 5 GHz */
		ieeeband =
			(band == 6) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;

		/* Loop through each band adding each of the channels */
		for (ch = 0; ch < eeprom_ch_count; ch++) {
			/* Set up driver's info for lower half */
1070
			iwl_mod_ht40_chan_info(priv, ieeeband,
1071
						eeprom_ch_index[ch],
1072 1073
						&eeprom_ch_info[ch],
						IEEE80211_CHAN_NO_HT40PLUS);
1074 1075

			/* Set up driver's info for upper half */
1076 1077 1078 1079
			iwl_mod_ht40_chan_info(priv, ieeeband,
						eeprom_ch_index[ch] + 4,
						&eeprom_ch_info[ch],
						IEEE80211_CHAN_NO_HT40MINUS);
1080 1081 1082
		}
	}

1083 1084 1085 1086 1087
	/* for newer device (6000 series and up)
	 * EEPROM contain enhanced tx power information
	 * driver need to process addition information
	 * to determine the max channel tx power limits
	 */
1088
	if (priv->lib->eeprom_ops.enhanced_txpower)
1089
		iwl_eeprom_enhanced_txpower(priv);
1090

1091 1092 1093 1094
	return 0;
}

/*
1095
 * iwl_free_channel_map - undo allocations in iwl_init_channel_map
1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107
 */
void iwl_free_channel_map(struct iwl_priv *priv)
{
	kfree(priv->channel_info);
	priv->channel_count = 0;
}

/**
 * iwl_get_channel_info - Find driver's private channel info
 *
 * Based on band and channel number.
 */
1108 1109
const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv,
					enum ieee80211_band band, u16 channel)
1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129
{
	int i;

	switch (band) {
	case IEEE80211_BAND_5GHZ:
		for (i = 14; i < priv->channel_count; i++) {
			if (priv->channel_info[i].channel == channel)
				return &priv->channel_info[i];
		}
		break;
	case IEEE80211_BAND_2GHZ:
		if (channel >= 1 && channel <= 14)
			return &priv->channel_info[channel - 1];
		break;
	default:
		BUG();
	}

	return NULL;
}
1130 1131 1132 1133 1134

void iwl_rf_config(struct iwl_priv *priv)
{
	u16 radio_cfg;

J
Johannes Berg 已提交
1135
	radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
1136 1137 1138

	/* write radio config values to register */
	if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) {
1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151
		u32 reg_val =
			EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <<
				CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE |
			EEPROM_RF_CFG_STEP_MSK(radio_cfg) <<
				CSR_HW_IF_CONFIG_REG_POS_PHY_STEP |
			EEPROM_RF_CFG_DASH_MSK(radio_cfg) <<
				CSR_HW_IF_CONFIG_REG_POS_PHY_DASH;

		iwl_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG,
				  CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE |
				  CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP |
				  CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH, reg_val);

1152 1153 1154 1155 1156 1157 1158 1159
		IWL_INFO(priv, "Radio type=0x%x-0x%x-0x%x\n",
			 EEPROM_RF_CFG_TYPE_MSK(radio_cfg),
			 EEPROM_RF_CFG_STEP_MSK(radio_cfg),
			 EEPROM_RF_CFG_DASH_MSK(radio_cfg));
	} else
		WARN_ON(1);

	/* set CSR_HW_CONFIG_REG for uCode use */
1160
	iwl_set_bit(priv->trans, CSR_HW_IF_CONFIG_REG,
1161 1162 1163
		    CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
		    CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
}