1/****************************************************************************** 2 * 3 * This file is provided under a dual BSD/GPLv2 license. When using or 4 * redistributing this file, you may do so under either license. 5 * 6 * GPL LICENSE SUMMARY 7 * 8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of version 2 of the GNU General Public License as 12 * published by the Free Software Foundation. 13 * 14 * This program is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, 22 * USA 23 * 24 * The full GNU General Public License is included in this distribution 25 * in the file called LICENSE.GPL. 26 * 27 * Contact Information: 28 * Intel Linux Wireless <ilw@linux.intel.com> 29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 30 * 31 * BSD LICENSE 32 * 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 34 * All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 40 * * Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * * Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in 44 * the documentation and/or other materials provided with the 45 * distribution. 46 * * Neither the name Intel Corporation nor the names of its 47 * contributors may be used to endorse or promote products derived 48 * from this software without specific prior written permission. 49 * 50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 61 *****************************************************************************/ 62 63 64#include <linux/kernel.h> 65#include <linux/module.h> 66#include <linux/slab.h> 67#include <linux/init.h> 68 69#include <net/mac80211.h> 70 71#include "iwl-commands.h" 72#include "iwl-dev.h" 73#include "iwl-core.h" 74#include "iwl-debug.h" 75#include "iwl-eeprom.h" 76#include "iwl-io.h" 77 78/************************** EEPROM BANDS **************************** 79 * 80 * The iwl_eeprom_band definitions below provide the mapping from the 81 * EEPROM contents to the specific channel number supported for each 82 * band. 83 * 84 * For example, iwl_priv->eeprom.band_3_channels[4] from the band_3 85 * definition below maps to physical channel 42 in the 5.2GHz spectrum. 86 * The specific geography and calibration information for that channel 87 * is contained in the eeprom map itself. 88 * 89 * During init, we copy the eeprom information and channel map 90 * information into priv->channel_info_24/52 and priv->channel_map_24/52 91 * 92 * channel_map_24/52 provides the index in the channel_info array for a 93 * given channel. We have to have two separate maps as there is channel 94 * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and 95 * band_2 96 * 97 * A value of 0xff stored in the channel_map indicates that the channel 98 * is not supported by the hardware at all. 99 * 100 * A value of 0xfe in the channel_map indicates that the channel is not 101 * valid for Tx with the current hardware. This means that 102 * while the system can tune and receive on a given channel, it may not 103 * be able to associate or transmit any frames on that 104 * channel. There is no corresponding channel information for that 105 * entry. 106 * 107 *********************************************************************/ 108 109/* 2.4 GHz */ 110const u8 iwl_eeprom_band_1[14] = { 111 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 112}; 113 114/* 5.2 GHz bands */ 115static const u8 iwl_eeprom_band_2[] = { /* 4915-5080MHz */ 116 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 117}; 118 119static const u8 iwl_eeprom_band_3[] = { /* 5170-5320MHz */ 120 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 121}; 122 123static const u8 iwl_eeprom_band_4[] = { /* 5500-5700MHz */ 124 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 125}; 126 127static const u8 iwl_eeprom_band_5[] = { /* 5725-5825MHz */ 128 145, 149, 153, 157, 161, 165 129}; 130 131static const u8 iwl_eeprom_band_6[] = { /* 2.4 ht40 channel */ 132 1, 2, 3, 4, 5, 6, 7 133}; 134 135static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */ 136 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 137}; 138 139/** 140 * struct iwl_txpwr_section: eeprom section information 141 * @offset: indirect address into eeprom image 142 * @count: number of "struct iwl_eeprom_enhanced_txpwr" in this section 143 * @band: band type for the section 144 * @is_common - true: common section, false: channel section 145 * @is_cck - true: cck section, false: not cck section 146 * @is_ht_40 - true: all channel in the section are HT40 channel, 147 * false: legacy or HT 20 MHz 148 * ignore if it is common section 149 * @iwl_eeprom_section_channel: channel array in the section, 150 * ignore if common section 151 */ 152struct iwl_txpwr_section { 153 u32 offset; 154 u8 count; 155 enum ieee80211_band band; 156 bool is_common; 157 bool is_cck; 158 bool is_ht40; 159 u8 iwl_eeprom_section_channel[EEPROM_MAX_TXPOWER_SECTION_ELEMENTS]; 160}; 161 162/** 163 * section 1 - 3 are regulatory tx power apply to all channels based on 164 * modulation: CCK, OFDM 165 * Band: 2.4GHz, 5.2GHz 166 * section 4 - 10 are regulatory tx power apply to specified channels 167 * For example: 168 * 1L - Channel 1 Legacy 169 * 1HT - Channel 1 HT 170 * (1,+1) - Channel 1 HT40 "_above_" 171 * 172 * Section 1: all CCK channels 173 * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40) channels 174 * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels 175 * Section 4: 2.4 GHz 20MHz channels: 1L, 1HT, 2L, 2HT, 10L, 10HT, 11L, 11HT 176 * Section 5: 2.4 GHz 40MHz channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1) 177 * Section 6: 5.2 GHz 20MHz channels: 36L, 64L, 100L, 36HT, 64HT, 100HT 178 * Section 7: 5.2 GHz 40MHz channels: (36,+1) (60,+1) (100,+1) 179 * Section 8: 2.4 GHz channel: 13L, 13HT 180 * Section 9: 2.4 GHz channel: 140L, 140HT 181 * Section 10: 2.4 GHz 40MHz channels: (132,+1) (44,+1) 182 * 183 */ 184static const struct iwl_txpwr_section enhinfo[] = { 185 { EEPROM_LB_CCK_20_COMMON, 1, IEEE80211_BAND_2GHZ, true, true, false }, 186 { EEPROM_LB_OFDM_COMMON, 3, IEEE80211_BAND_2GHZ, true, false, false }, 187 { EEPROM_HB_OFDM_COMMON, 3, IEEE80211_BAND_5GHZ, true, false, false }, 188 { EEPROM_LB_OFDM_20_BAND, 8, IEEE80211_BAND_2GHZ, 189 false, false, false, 190 {1, 1, 2, 2, 10, 10, 11, 11 } }, 191 { EEPROM_LB_OFDM_HT40_BAND, 5, IEEE80211_BAND_2GHZ, 192 false, false, true, 193 { 1, 2, 6, 7, 9 } }, 194 { EEPROM_HB_OFDM_20_BAND, 6, IEEE80211_BAND_5GHZ, 195 false, false, false, 196 { 36, 64, 100, 36, 64, 100 } }, 197 { EEPROM_HB_OFDM_HT40_BAND, 3, IEEE80211_BAND_5GHZ, 198 false, false, true, 199 { 36, 60, 100 } }, 200 { EEPROM_LB_OFDM_20_CHANNEL_13, 2, IEEE80211_BAND_2GHZ, 201 false, false, false, 202 { 13, 13 } }, 203 { EEPROM_HB_OFDM_20_CHANNEL_140, 2, IEEE80211_BAND_5GHZ, 204 false, false, false, 205 { 140, 140 } }, 206 { EEPROM_HB_OFDM_HT40_BAND_1, 2, IEEE80211_BAND_5GHZ, 207 false, false, true, 208 { 132, 44 } }, 209}; 210 211/****************************************************************************** 212 * 213 * EEPROM related functions 214 * 215******************************************************************************/ 216 217int iwlcore_eeprom_verify_signature(struct iwl_priv *priv) 218{ 219 u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; 220 int ret = 0; 221 222 IWL_DEBUG_INFO(priv, "EEPROM signature=0x%08x\n", gp); 223 switch (gp) { 224 case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP: 225 if (priv->nvm_device_type != NVM_DEVICE_TYPE_OTP) { 226 IWL_ERR(priv, "EEPROM with bad signature: 0x%08x\n", 227 gp); 228 ret = -ENOENT; 229 } 230 break; 231 case CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K: 232 case CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K: 233 if (priv->nvm_device_type != NVM_DEVICE_TYPE_EEPROM) { 234 IWL_ERR(priv, "OTP with bad signature: 0x%08x\n", gp); 235 ret = -ENOENT; 236 } 237 break; 238 case CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP: 239 default: 240 IWL_ERR(priv, "bad EEPROM/OTP signature, type=%s, " 241 "EEPROM_GP=0x%08x\n", 242 (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) 243 ? "OTP" : "EEPROM", gp); 244 ret = -ENOENT; 245 break; 246 } 247 return ret; 248} 249EXPORT_SYMBOL(iwlcore_eeprom_verify_signature); 250 251static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode) 252{ 253 u32 otpgp; 254 255 otpgp = iwl_read32(priv, CSR_OTP_GP_REG); 256 if (mode == IWL_OTP_ACCESS_ABSOLUTE) 257 iwl_clear_bit(priv, CSR_OTP_GP_REG, 258 CSR_OTP_GP_REG_OTP_ACCESS_MODE); 259 else 260 iwl_set_bit(priv, CSR_OTP_GP_REG, 261 CSR_OTP_GP_REG_OTP_ACCESS_MODE); 262} 263 264static int iwlcore_get_nvm_type(struct iwl_priv *priv) 265{ 266 u32 otpgp; 267 int nvm_type; 268 269 /* OTP only valid for CP/PP and after */ 270 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { 271 case CSR_HW_REV_TYPE_NONE: 272 IWL_ERR(priv, "Unknown hardware type\n"); 273 return -ENOENT; 274 case CSR_HW_REV_TYPE_3945: 275 case CSR_HW_REV_TYPE_4965: 276 case CSR_HW_REV_TYPE_5300: 277 case CSR_HW_REV_TYPE_5350: 278 case CSR_HW_REV_TYPE_5100: 279 case CSR_HW_REV_TYPE_5150: 280 nvm_type = NVM_DEVICE_TYPE_EEPROM; 281 break; 282 default: 283 otpgp = iwl_read32(priv, CSR_OTP_GP_REG); 284 if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT) 285 nvm_type = NVM_DEVICE_TYPE_OTP; 286 else 287 nvm_type = NVM_DEVICE_TYPE_EEPROM; 288 break; 289 } 290 return nvm_type; 291} 292 293/* 294 * The device's EEPROM semaphore prevents conflicts between driver and uCode 295 * when accessing the EEPROM; each access is a series of pulses to/from the 296 * EEPROM chip, not a single event, so even reads could conflict if they 297 * weren't arbitrated by the semaphore. 298 */ 299int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv) 300{ 301 u16 count; 302 int ret; 303 304 for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { 305 /* Request semaphore */ 306 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, 307 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); 308 309 /* See if we got it */ 310 ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG, 311 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, 312 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, 313 EEPROM_SEM_TIMEOUT); 314 if (ret >= 0) { 315 IWL_DEBUG_IO(priv, "Acquired semaphore after %d tries.\n", 316 count+1); 317 return ret; 318 } 319 } 320 321 return ret; 322} 323EXPORT_SYMBOL(iwlcore_eeprom_acquire_semaphore); 324 325void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv) 326{ 327 iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG, 328 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); 329 330} 331EXPORT_SYMBOL(iwlcore_eeprom_release_semaphore); 332 333const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) 334{ 335 BUG_ON(offset >= priv->cfg->eeprom_size); 336 return &priv->eeprom[offset]; 337} 338EXPORT_SYMBOL(iwlcore_eeprom_query_addr); 339 340static int iwl_init_otp_access(struct iwl_priv *priv) 341{ 342 int ret; 343 344 /* Enable 40MHz radio clock */ 345 _iwl_write32(priv, CSR_GP_CNTRL, 346 _iwl_read32(priv, CSR_GP_CNTRL) | 347 CSR_GP_CNTRL_REG_FLAG_INIT_DONE); 348 349 /* wait for clock to be ready */ 350 ret = iwl_poll_bit(priv, CSR_GP_CNTRL, 351 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 352 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 353 25000); 354 if (ret < 0) 355 IWL_ERR(priv, "Time out access OTP\n"); 356 else { 357 iwl_set_bits_prph(priv, APMG_PS_CTRL_REG, 358 APMG_PS_CTRL_VAL_RESET_REQ); 359 udelay(5); 360 iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, 361 APMG_PS_CTRL_VAL_RESET_REQ); 362 363 /* 364 * CSR auto clock gate disable bit - 365 * this is only applicable for HW with OTP shadow RAM 366 */ 367 if (priv->cfg->shadow_ram_support) 368 iwl_set_bit(priv, CSR_DBG_LINK_PWR_MGMT_REG, 369 CSR_RESET_LINK_PWR_MGMT_DISABLED); 370 } 371 return ret; 372} 373 374static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, __le16 *eeprom_data) 375{ 376 int ret = 0; 377 u32 r; 378 u32 otpgp; 379 380 _iwl_write32(priv, CSR_EEPROM_REG, 381 CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); 382 ret = iwl_poll_bit(priv, CSR_EEPROM_REG, 383 CSR_EEPROM_REG_READ_VALID_MSK, 384 CSR_EEPROM_REG_READ_VALID_MSK, 385 IWL_EEPROM_ACCESS_TIMEOUT); 386 if (ret < 0) { 387 IWL_ERR(priv, "Time out reading OTP[%d]\n", addr); 388 return ret; 389 } 390 r = _iwl_read_direct32(priv, CSR_EEPROM_REG); 391 /* check for ECC errors: */ 392 otpgp = iwl_read32(priv, CSR_OTP_GP_REG); 393 if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { 394 /* stop in this case */ 395 /* set the uncorrectable OTP ECC bit for acknowledgement */ 396 iwl_set_bit(priv, CSR_OTP_GP_REG, 397 CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); 398 IWL_ERR(priv, "Uncorrectable OTP ECC error, abort OTP read\n"); 399 return -EINVAL; 400 } 401 if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { 402 /* continue in this case */ 403 /* set the correctable OTP ECC bit for acknowledgement */ 404 iwl_set_bit(priv, CSR_OTP_GP_REG, 405 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); 406 IWL_ERR(priv, "Correctable OTP ECC error, continue read\n"); 407 } 408 *eeprom_data = cpu_to_le16(r >> 16); 409 return 0; 410} 411 412/* 413 * iwl_is_otp_empty: check for empty OTP 414 */ 415static bool iwl_is_otp_empty(struct iwl_priv *priv) 416{ 417 u16 next_link_addr = 0; 418 __le16 link_value; 419 bool is_empty = false; 420 421 /* locate the beginning of OTP link list */ 422 if (!iwl_read_otp_word(priv, next_link_addr, &link_value)) { 423 if (!link_value) { 424 IWL_ERR(priv, "OTP is empty\n"); 425 is_empty = true; 426 } 427 } else { 428 IWL_ERR(priv, "Unable to read first block of OTP list.\n"); 429 is_empty = true; 430 } 431 432 return is_empty; 433} 434 435 436/* 437 * iwl_find_otp_image: find EEPROM image in OTP 438 * finding the OTP block that contains the EEPROM image. 439 * the last valid block on the link list (the block _before_ the last block) 440 * is the block we should read and used to configure the device. 441 * If all the available OTP blocks are full, the last block will be the block 442 * we should read and used to configure the device. 443 * only perform this operation if shadow RAM is disabled 444 */ 445static int iwl_find_otp_image(struct iwl_priv *priv, 446 u16 *validblockaddr) 447{ 448 u16 next_link_addr = 0, valid_addr; 449 __le16 link_value = 0; 450 int usedblocks = 0; 451 452 /* set addressing mode to absolute to traverse the link list */ 453 iwl_set_otp_access(priv, IWL_OTP_ACCESS_ABSOLUTE); 454 455 /* checking for empty OTP or error */ 456 if (iwl_is_otp_empty(priv)) 457 return -EINVAL; 458 459 /* 460 * start traverse link list 461 * until reach the max number of OTP blocks 462 * different devices have different number of OTP blocks 463 */ 464 do { 465 /* save current valid block address 466 * check for more block on the link list 467 */ 468 valid_addr = next_link_addr; 469 next_link_addr = le16_to_cpu(link_value) * sizeof(u16); 470 IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n", 471 usedblocks, next_link_addr); 472 if (iwl_read_otp_word(priv, next_link_addr, &link_value)) 473 return -EINVAL; 474 if (!link_value) { 475 /* 476 * reach the end of link list, return success and 477 * set address point to the starting address 478 * of the image 479 */ 480 *validblockaddr = valid_addr; 481 /* skip first 2 bytes (link list pointer) */ 482 *validblockaddr += 2; 483 return 0; 484 } 485 /* more in the link list, continue */ 486 usedblocks++; 487 } while (usedblocks <= priv->cfg->max_ll_items); 488 489 /* OTP has no valid blocks */ 490 IWL_DEBUG_INFO(priv, "OTP has no valid blocks\n"); 491 return -EINVAL; 492} 493 494/** 495 * iwl_eeprom_init - read EEPROM contents 496 * 497 * Load the EEPROM contents from adapter into priv->eeprom 498 * 499 * NOTE: This routine uses the non-debug IO access functions. 500 */ 501int iwl_eeprom_init(struct iwl_priv *priv) 502{ 503 __le16 *e; 504 u32 gp = iwl_read32(priv, CSR_EEPROM_GP); 505 int sz; 506 int ret; 507 u16 addr; 508 u16 validblockaddr = 0; 509 u16 cache_addr = 0; 510 511 priv->nvm_device_type = iwlcore_get_nvm_type(priv); 512 if (priv->nvm_device_type == -ENOENT) 513 return -ENOENT; 514 /* allocate eeprom */ 515 IWL_DEBUG_INFO(priv, "NVM size = %d\n", priv->cfg->eeprom_size); 516 sz = priv->cfg->eeprom_size; 517 priv->eeprom = kzalloc(sz, GFP_KERNEL); 518 if (!priv->eeprom) { 519 ret = -ENOMEM; 520 goto alloc_err; 521 } 522 e = (__le16 *)priv->eeprom; 523 524 priv->cfg->ops->lib->apm_ops.init(priv); 525 526 ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv); 527 if (ret < 0) { 528 IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); 529 ret = -ENOENT; 530 goto err; 531 } 532 533 /* Make sure driver (instead of uCode) is allowed to read EEPROM */ 534 ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv); 535 if (ret < 0) { 536 IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n"); 537 ret = -ENOENT; 538 goto err; 539 } 540 541 if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) { 542 543 ret = iwl_init_otp_access(priv); 544 if (ret) { 545 IWL_ERR(priv, "Failed to initialize OTP access.\n"); 546 ret = -ENOENT; 547 goto done; 548 } 549 _iwl_write32(priv, CSR_EEPROM_GP, 550 iwl_read32(priv, CSR_EEPROM_GP) & 551 ~CSR_EEPROM_GP_IF_OWNER_MSK); 552 553 iwl_set_bit(priv, CSR_OTP_GP_REG, 554 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | 555 CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); 556 /* traversing the linked list if no shadow ram supported */ 557 if (!priv->cfg->shadow_ram_support) { 558 if (iwl_find_otp_image(priv, &validblockaddr)) { 559 ret = -ENOENT; 560 goto done; 561 } 562 } 563 for (addr = validblockaddr; addr < validblockaddr + sz; 564 addr += sizeof(u16)) { 565 __le16 eeprom_data; 566 567 ret = iwl_read_otp_word(priv, addr, &eeprom_data); 568 if (ret) 569 goto done; 570 e[cache_addr / 2] = eeprom_data; 571 cache_addr += sizeof(u16); 572 } 573 } else { 574 /* eeprom is an array of 16bit values */ 575 for (addr = 0; addr < sz; addr += sizeof(u16)) { 576 u32 r; 577 578 _iwl_write32(priv, CSR_EEPROM_REG, 579 CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); 580 581 ret = iwl_poll_bit(priv, CSR_EEPROM_REG, 582 CSR_EEPROM_REG_READ_VALID_MSK, 583 CSR_EEPROM_REG_READ_VALID_MSK, 584 IWL_EEPROM_ACCESS_TIMEOUT); 585 if (ret < 0) { 586 IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr); 587 goto done; 588 } 589 r = _iwl_read_direct32(priv, CSR_EEPROM_REG); 590 e[addr / 2] = cpu_to_le16(r >> 16); 591 } 592 } 593 594 IWL_DEBUG_INFO(priv, "NVM Type: %s, version: 0x%x\n", 595 (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) 596 ? "OTP" : "EEPROM", 597 iwl_eeprom_query16(priv, EEPROM_VERSION)); 598 599 ret = 0; 600done: 601 priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv); 602 603err: 604 if (ret) 605 iwl_eeprom_free(priv); 606 /* Reset chip to save power until we load uCode during "up". */ 607 priv->cfg->ops->lib->apm_ops.stop(priv); 608alloc_err: 609 return ret; 610} 611EXPORT_SYMBOL(iwl_eeprom_init); 612 613void iwl_eeprom_free(struct iwl_priv *priv) 614{ 615 kfree(priv->eeprom); 616 priv->eeprom = NULL; 617} 618EXPORT_SYMBOL(iwl_eeprom_free); 619 620int iwl_eeprom_check_version(struct iwl_priv *priv) 621{ 622 u16 eeprom_ver; 623 u16 calib_ver; 624 625 eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); 626 calib_ver = priv->cfg->ops->lib->eeprom_ops.calib_version(priv); 627 628 if (eeprom_ver < priv->cfg->eeprom_ver || 629 calib_ver < priv->cfg->eeprom_calib_ver) 630 goto err; 631 632 IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n", 633 eeprom_ver, calib_ver); 634 635 return 0; 636err: 637 IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n", 638 eeprom_ver, priv->cfg->eeprom_ver, 639 calib_ver, priv->cfg->eeprom_calib_ver); 640 return -EINVAL; 641 642} 643EXPORT_SYMBOL(iwl_eeprom_check_version); 644 645const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) 646{ 647 return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset); 648} 649EXPORT_SYMBOL(iwl_eeprom_query_addr); 650 651u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset) 652{ 653 if (!priv->eeprom) 654 return 0; 655 return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8); 656} 657EXPORT_SYMBOL(iwl_eeprom_query16); 658 659void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac) 660{ 661 const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv, 662 EEPROM_MAC_ADDRESS); 663 memcpy(mac, addr, ETH_ALEN); 664} 665EXPORT_SYMBOL(iwl_eeprom_get_mac); 666 667static void iwl_init_band_reference(const struct iwl_priv *priv, 668 int eep_band, int *eeprom_ch_count, 669 const struct iwl_eeprom_channel **eeprom_ch_info, 670 const u8 **eeprom_ch_index) 671{ 672 u32 offset = priv->cfg->ops->lib-> 673 eeprom_ops.regulatory_bands[eep_band - 1]; 674 switch (eep_band) { 675 case 1: /* 2.4GHz band */ 676 *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1); 677 *eeprom_ch_info = (struct iwl_eeprom_channel *) 678 iwl_eeprom_query_addr(priv, offset); 679 *eeprom_ch_index = iwl_eeprom_band_1; 680 break; 681 case 2: /* 4.9GHz band */ 682 *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2); 683 *eeprom_ch_info = (struct iwl_eeprom_channel *) 684 iwl_eeprom_query_addr(priv, offset); 685 *eeprom_ch_index = iwl_eeprom_band_2; 686 break; 687 case 3: /* 5.2GHz band */ 688 *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3); 689 *eeprom_ch_info = (struct iwl_eeprom_channel *) 690 iwl_eeprom_query_addr(priv, offset); 691 *eeprom_ch_index = iwl_eeprom_band_3; 692 break; 693 case 4: /* 5.5GHz band */ 694 *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4); 695 *eeprom_ch_info = (struct iwl_eeprom_channel *) 696 iwl_eeprom_query_addr(priv, offset); 697 *eeprom_ch_index = iwl_eeprom_band_4; 698 break; 699 case 5: /* 5.7GHz band */ 700 *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5); 701 *eeprom_ch_info = (struct iwl_eeprom_channel *) 702 iwl_eeprom_query_addr(priv, offset); 703 *eeprom_ch_index = iwl_eeprom_band_5; 704 break; 705 case 6: /* 2.4GHz ht40 channels */ 706 *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_6); 707 *eeprom_ch_info = (struct iwl_eeprom_channel *) 708 iwl_eeprom_query_addr(priv, offset); 709 *eeprom_ch_index = iwl_eeprom_band_6; 710 break; 711 case 7: /* 5 GHz ht40 channels */ 712 *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_7); 713 *eeprom_ch_info = (struct iwl_eeprom_channel *) 714 iwl_eeprom_query_addr(priv, offset); 715 *eeprom_ch_index = iwl_eeprom_band_7; 716 break; 717 default: 718 BUG(); 719 return; 720 } 721} 722 723#define CHECK_AND_PRINT(x) ((eeprom_ch->flags & EEPROM_CHANNEL_##x) \ 724 ? # x " " : "") 725 726/** 727 * iwl_mod_ht40_chan_info - Copy ht40 channel info into driver's priv. 728 * 729 * Does not set up a command, or touch hardware. 730 */ 731static int iwl_mod_ht40_chan_info(struct iwl_priv *priv, 732 enum ieee80211_band band, u16 channel, 733 const struct iwl_eeprom_channel *eeprom_ch, 734 u8 clear_ht40_extension_channel) 735{ 736 struct iwl_channel_info *ch_info; 737 738 ch_info = (struct iwl_channel_info *) 739 iwl_get_channel_info(priv, band, channel); 740 741 if (!is_channel_valid(ch_info)) 742 return -1; 743 744 IWL_DEBUG_INFO(priv, "HT40 Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):" 745 " Ad-Hoc %ssupported\n", 746 ch_info->channel, 747 is_channel_a_band(ch_info) ? 748 "5.2" : "2.4", 749 CHECK_AND_PRINT(IBSS), 750 CHECK_AND_PRINT(ACTIVE), 751 CHECK_AND_PRINT(RADAR), 752 CHECK_AND_PRINT(WIDE), 753 CHECK_AND_PRINT(DFS), 754 eeprom_ch->flags, 755 eeprom_ch->max_power_avg, 756 ((eeprom_ch->flags & EEPROM_CHANNEL_IBSS) 757 && !(eeprom_ch->flags & EEPROM_CHANNEL_RADAR)) ? 758 "" : "not "); 759 760 ch_info->ht40_eeprom = *eeprom_ch; 761 ch_info->ht40_max_power_avg = eeprom_ch->max_power_avg; 762 ch_info->ht40_flags = eeprom_ch->flags; 763 if (eeprom_ch->flags & EEPROM_CHANNEL_VALID) 764 ch_info->ht40_extension_channel &= ~clear_ht40_extension_channel; 765 766 return 0; 767} 768 769/** 770 * iwl_get_max_txpower_avg - get the highest tx power from all chains. 771 * find the highest tx power from all chains for the channel 772 */ 773static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv, 774 struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, 775 int element, s8 *max_txpower_in_half_dbm) 776{ 777 s8 max_txpower_avg = 0; /* (dBm) */ 778 779 IWL_DEBUG_INFO(priv, "%d - " 780 "chain_a: %d dB chain_b: %d dB " 781 "chain_c: %d dB mimo2: %d dB mimo3: %d dB\n", 782 element, 783 enhanced_txpower[element].chain_a_max >> 1, 784 enhanced_txpower[element].chain_b_max >> 1, 785 enhanced_txpower[element].chain_c_max >> 1, 786 enhanced_txpower[element].mimo2_max >> 1, 787 enhanced_txpower[element].mimo3_max >> 1); 788 /* Take the highest tx power from any valid chains */ 789 if ((priv->cfg->valid_tx_ant & ANT_A) && 790 (enhanced_txpower[element].chain_a_max > max_txpower_avg)) 791 max_txpower_avg = enhanced_txpower[element].chain_a_max; 792 if ((priv->cfg->valid_tx_ant & ANT_B) && 793 (enhanced_txpower[element].chain_b_max > max_txpower_avg)) 794 max_txpower_avg = enhanced_txpower[element].chain_b_max; 795 if ((priv->cfg->valid_tx_ant & ANT_C) && 796 (enhanced_txpower[element].chain_c_max > max_txpower_avg)) 797 max_txpower_avg = enhanced_txpower[element].chain_c_max; 798 if (((priv->cfg->valid_tx_ant == ANT_AB) | 799 (priv->cfg->valid_tx_ant == ANT_BC) | 800 (priv->cfg->valid_tx_ant == ANT_AC)) && 801 (enhanced_txpower[element].mimo2_max > max_txpower_avg)) 802 max_txpower_avg = enhanced_txpower[element].mimo2_max; 803 if ((priv->cfg->valid_tx_ant == ANT_ABC) && 804 (enhanced_txpower[element].mimo3_max > max_txpower_avg)) 805 max_txpower_avg = enhanced_txpower[element].mimo3_max; 806 807 /* 808 * max. tx power in EEPROM is in 1/2 dBm format 809 * convert from 1/2 dBm to dBm (round-up convert) 810 * but we also do not want to loss 1/2 dBm resolution which 811 * will impact performance 812 */ 813 *max_txpower_in_half_dbm = max_txpower_avg; 814 return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1); 815} 816 817/** 818 * iwl_update_common_txpower: update channel tx power 819 * update tx power per band based on EEPROM enhanced tx power info. 820 */ 821static s8 iwl_update_common_txpower(struct iwl_priv *priv, 822 struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, 823 int section, int element, s8 *max_txpower_in_half_dbm) 824{ 825 struct iwl_channel_info *ch_info; 826 int ch; 827 bool is_ht40 = false; 828 s8 max_txpower_avg; /* (dBm) */ 829 830 /* it is common section, contain all type (Legacy, HT and HT40) 831 * based on the element in the section to determine 832 * is it HT 40 or not 833 */ 834 if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX) 835 is_ht40 = true; 836 max_txpower_avg = 837 iwl_get_max_txpower_avg(priv, enhanced_txpower, 838 element, max_txpower_in_half_dbm); 839 840 ch_info = priv->channel_info; 841 842 for (ch = 0; ch < priv->channel_count; ch++) { 843 /* find matching band and update tx power if needed */ 844 if ((ch_info->band == enhinfo[section].band) && 845 (ch_info->max_power_avg < max_txpower_avg) && 846 (!is_ht40)) { 847 /* Update regulatory-based run-time data */ 848 ch_info->max_power_avg = ch_info->curr_txpow = 849 max_txpower_avg; 850 ch_info->scan_power = max_txpower_avg; 851 } 852 if ((ch_info->band == enhinfo[section].band) && is_ht40 && 853 (ch_info->ht40_max_power_avg < max_txpower_avg)) { 854 /* Update regulatory-based run-time data */ 855 ch_info->ht40_max_power_avg = max_txpower_avg; 856 } 857 ch_info++; 858 } 859 return max_txpower_avg; 860} 861 862/** 863 * iwl_update_channel_txpower: update channel tx power 864 * update channel tx power based on EEPROM enhanced tx power info. 865 */ 866static s8 iwl_update_channel_txpower(struct iwl_priv *priv, 867 struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, 868 int section, int element, s8 *max_txpower_in_half_dbm) 869{ 870 struct iwl_channel_info *ch_info; 871 int ch; 872 u8 channel; 873 s8 max_txpower_avg; /* (dBm) */ 874 875 channel = enhinfo[section].iwl_eeprom_section_channel[element]; 876 max_txpower_avg = 877 iwl_get_max_txpower_avg(priv, enhanced_txpower, 878 element, max_txpower_in_half_dbm); 879 880 ch_info = priv->channel_info; 881 for (ch = 0; ch < priv->channel_count; ch++) { 882 /* find matching channel and update tx power if needed */ 883 if (ch_info->channel == channel) { 884 if ((ch_info->max_power_avg < max_txpower_avg) && 885 (!enhinfo[section].is_ht40)) { 886 /* Update regulatory-based run-time data */ 887 ch_info->max_power_avg = max_txpower_avg; 888 ch_info->curr_txpow = max_txpower_avg; 889 ch_info->scan_power = max_txpower_avg; 890 } 891 if ((enhinfo[section].is_ht40) && 892 (ch_info->ht40_max_power_avg < max_txpower_avg)) { 893 /* Update regulatory-based run-time data */ 894 ch_info->ht40_max_power_avg = max_txpower_avg; 895 } 896 break; 897 } 898 ch_info++; 899 } 900 return max_txpower_avg; 901} 902 903/** 904 * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info 905 */ 906void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) 907{ 908 int eeprom_section_count = 0; 909 int section, element; 910 struct iwl_eeprom_enhanced_txpwr *enhanced_txpower; 911 u32 offset; 912 s8 max_txpower_avg; /* (dBm) */ 913 s8 max_txpower_in_half_dbm; /* (half-dBm) */ 914 915 /* Loop through all the sections 916 * adjust bands and channel's max tx power 917 * Set the tx_power_user_lmt to the highest power 918 * supported by any channels and chains 919 */ 920 for (section = 0; section < ARRAY_SIZE(enhinfo); section++) { 921 eeprom_section_count = enhinfo[section].count; 922 offset = enhinfo[section].offset; 923 enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *) 924 iwl_eeprom_query_addr(priv, offset); 925 926 /* 927 * check for valid entry - 928 * different version of EEPROM might contain different set 929 * of enhanced tx power table 930 * always check for valid entry before process 931 * the information 932 */ 933 if (!enhanced_txpower->common || enhanced_txpower->reserved) 934 continue; 935 936 for (element = 0; element < eeprom_section_count; element++) { 937 if (enhinfo[section].is_common) 938 max_txpower_avg = 939 iwl_update_common_txpower(priv, 940 enhanced_txpower, section, 941 element, 942 &max_txpower_in_half_dbm); 943 else 944 max_txpower_avg = 945 iwl_update_channel_txpower(priv, 946 enhanced_txpower, section, 947 element, 948 &max_txpower_in_half_dbm); 949 950 /* Update the tx_power_user_lmt to the highest power 951 * supported by any channel */ 952 if (max_txpower_avg > priv->tx_power_user_lmt) 953 priv->tx_power_user_lmt = max_txpower_avg; 954 955 /* 956 * Update the tx_power_lmt_in_half_dbm to 957 * the highest power supported by any channel 958 */ 959 if (max_txpower_in_half_dbm > 960 priv->tx_power_lmt_in_half_dbm) 961 priv->tx_power_lmt_in_half_dbm = 962 max_txpower_in_half_dbm; 963 } 964 } 965} 966EXPORT_SYMBOL(iwlcore_eeprom_enhanced_txpower); 967 968#define CHECK_AND_PRINT_I(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \ 969 ? # x " " : "") 970 971/** 972 * iwl_init_channel_map - Set up driver's info for all possible channels 973 */ 974int iwl_init_channel_map(struct iwl_priv *priv) 975{ 976 int eeprom_ch_count = 0; 977 const u8 *eeprom_ch_index = NULL; 978 const struct iwl_eeprom_channel *eeprom_ch_info = NULL; 979 int band, ch; 980 struct iwl_channel_info *ch_info; 981 982 if (priv->channel_count) { 983 IWL_DEBUG_INFO(priv, "Channel map already initialized.\n"); 984 return 0; 985 } 986 987 IWL_DEBUG_INFO(priv, "Initializing regulatory info from EEPROM\n"); 988 989 priv->channel_count = 990 ARRAY_SIZE(iwl_eeprom_band_1) + 991 ARRAY_SIZE(iwl_eeprom_band_2) + 992 ARRAY_SIZE(iwl_eeprom_band_3) + 993 ARRAY_SIZE(iwl_eeprom_band_4) + 994 ARRAY_SIZE(iwl_eeprom_band_5); 995 996 IWL_DEBUG_INFO(priv, "Parsing data for %d channels.\n", priv->channel_count); 997 998 priv->channel_info = kzalloc(sizeof(struct iwl_channel_info) * 999 priv->channel_count, GFP_KERNEL); 1000 if (!priv->channel_info) { 1001 IWL_ERR(priv, "Could not allocate channel_info\n"); 1002 priv->channel_count = 0; 1003 return -ENOMEM; 1004 } 1005 1006 ch_info = priv->channel_info; 1007 1008 /* Loop through the 5 EEPROM bands adding them in order to the 1009 * channel map we maintain (that contains additional information than 1010 * what just in the EEPROM) */ 1011 for (band = 1; band <= 5; band++) { 1012 1013 iwl_init_band_reference(priv, band, &eeprom_ch_count, 1014 &eeprom_ch_info, &eeprom_ch_index); 1015 1016 /* Loop through each band adding each of the channels */ 1017 for (ch = 0; ch < eeprom_ch_count; ch++) { 1018 ch_info->channel = eeprom_ch_index[ch]; 1019 ch_info->band = (band == 1) ? IEEE80211_BAND_2GHZ : 1020 IEEE80211_BAND_5GHZ; 1021 1022 /* permanently store EEPROM's channel regulatory flags 1023 * and max power in channel info database. */ 1024 ch_info->eeprom = eeprom_ch_info[ch]; 1025 1026 /* Copy the run-time flags so they are there even on 1027 * invalid channels */ 1028 ch_info->flags = eeprom_ch_info[ch].flags; 1029 /* First write that ht40 is not enabled, and then enable 1030 * one by one */ 1031 ch_info->ht40_extension_channel = 1032 IEEE80211_CHAN_NO_HT40; 1033 1034 if (!(is_channel_valid(ch_info))) { 1035 IWL_DEBUG_INFO(priv, "Ch. %d Flags %x [%sGHz] - " 1036 "No traffic\n", 1037 ch_info->channel, 1038 ch_info->flags, 1039 is_channel_a_band(ch_info) ? 1040 "5.2" : "2.4"); 1041 ch_info++; 1042 continue; 1043 } 1044 1045 /* Initialize regulatory-based run-time data */ 1046 ch_info->max_power_avg = ch_info->curr_txpow = 1047 eeprom_ch_info[ch].max_power_avg; 1048 ch_info->scan_power = eeprom_ch_info[ch].max_power_avg; 1049 ch_info->min_power = 0; 1050 1051 IWL_DEBUG_INFO(priv, "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm):" 1052 " Ad-Hoc %ssupported\n", 1053 ch_info->channel, 1054 is_channel_a_band(ch_info) ? 1055 "5.2" : "2.4", 1056 CHECK_AND_PRINT_I(VALID), 1057 CHECK_AND_PRINT_I(IBSS), 1058 CHECK_AND_PRINT_I(ACTIVE), 1059 CHECK_AND_PRINT_I(RADAR), 1060 CHECK_AND_PRINT_I(WIDE), 1061 CHECK_AND_PRINT_I(DFS), 1062 eeprom_ch_info[ch].flags, 1063 eeprom_ch_info[ch].max_power_avg, 1064 ((eeprom_ch_info[ch]. 1065 flags & EEPROM_CHANNEL_IBSS) 1066 && !(eeprom_ch_info[ch]. 1067 flags & EEPROM_CHANNEL_RADAR)) 1068 ? "" : "not "); 1069 1070 /* Set the tx_power_user_lmt to the highest power 1071 * supported by any channel */ 1072 if (eeprom_ch_info[ch].max_power_avg > 1073 priv->tx_power_user_lmt) 1074 priv->tx_power_user_lmt = 1075 eeprom_ch_info[ch].max_power_avg; 1076 1077 ch_info++; 1078 } 1079 } 1080 1081 /* Check if we do have HT40 channels */ 1082 if (priv->cfg->ops->lib->eeprom_ops.regulatory_bands[5] == 1083 EEPROM_REGULATORY_BAND_NO_HT40 && 1084 priv->cfg->ops->lib->eeprom_ops.regulatory_bands[6] == 1085 EEPROM_REGULATORY_BAND_NO_HT40) 1086 return 0; 1087 1088 /* Two additional EEPROM bands for 2.4 and 5 GHz HT40 channels */ 1089 for (band = 6; band <= 7; band++) { 1090 enum ieee80211_band ieeeband; 1091 1092 iwl_init_band_reference(priv, band, &eeprom_ch_count, 1093 &eeprom_ch_info, &eeprom_ch_index); 1094 1095 /* EEPROM band 6 is 2.4, band 7 is 5 GHz */ 1096 ieeeband = 1097 (band == 6) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; 1098 1099 /* Loop through each band adding each of the channels */ 1100 for (ch = 0; ch < eeprom_ch_count; ch++) { 1101 /* Set up driver's info for lower half */ 1102 iwl_mod_ht40_chan_info(priv, ieeeband, 1103 eeprom_ch_index[ch], 1104 &eeprom_ch_info[ch], 1105 IEEE80211_CHAN_NO_HT40PLUS); 1106 1107 /* Set up driver's info for upper half */ 1108 iwl_mod_ht40_chan_info(priv, ieeeband, 1109 eeprom_ch_index[ch] + 4, 1110 &eeprom_ch_info[ch], 1111 IEEE80211_CHAN_NO_HT40MINUS); 1112 } 1113 } 1114 1115 /* for newer device (6000 series and up) 1116 * EEPROM contain enhanced tx power information 1117 * driver need to process addition information 1118 * to determine the max channel tx power limits 1119 */ 1120 if (priv->cfg->ops->lib->eeprom_ops.update_enhanced_txpower) 1121 priv->cfg->ops->lib->eeprom_ops.update_enhanced_txpower(priv); 1122 1123 return 0; 1124} 1125EXPORT_SYMBOL(iwl_init_channel_map); 1126 1127/* 1128 * iwl_free_channel_map - undo allocations in iwl_init_channel_map 1129 */ 1130void iwl_free_channel_map(struct iwl_priv *priv) 1131{ 1132 kfree(priv->channel_info); 1133 priv->channel_count = 0; 1134} 1135EXPORT_SYMBOL(iwl_free_channel_map); 1136 1137/** 1138 * iwl_get_channel_info - Find driver's private channel info 1139 * 1140 * Based on band and channel number. 1141 */ 1142const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv, 1143 enum ieee80211_band band, u16 channel) 1144{ 1145 int i; 1146 1147 switch (band) { 1148 case IEEE80211_BAND_5GHZ: 1149 for (i = 14; i < priv->channel_count; i++) { 1150 if (priv->channel_info[i].channel == channel) 1151 return &priv->channel_info[i]; 1152 } 1153 break; 1154 case IEEE80211_BAND_2GHZ: 1155 if (channel >= 1 && channel <= 14) 1156 return &priv->channel_info[channel - 1]; 1157 break; 1158 default: 1159 BUG(); 1160 } 1161 1162 return NULL; 1163} 1164EXPORT_SYMBOL(iwl_get_channel_info); 1165