diff options
| author | John W. Linville <linville@tuxdriver.com> | 2012-03-09 14:57:30 -0500 |
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2012-03-09 14:57:30 -0500 |
| commit | 74dd1521d0b4f940cdd3ce7b9d988836bef589b8 (patch) | |
| tree | 42f3d4ee1d4e6d60a91aaadab771f766a3024bc0 /drivers | |
| parent | 2f2d76cc3e938389feee671b46252dde6880b3b7 (diff) | |
| parent | 1745e4405b2c0da6db2ec4b6bc0ad930612d8295 (diff) | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Diffstat (limited to 'drivers')
116 files changed, 4449 insertions, 4172 deletions
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c index 800163c8c2e7..a058842f14fd 100644 --- a/drivers/bcma/driver_chipcommon_pmu.c +++ b/drivers/bcma/driver_chipcommon_pmu.c | |||
| @@ -80,6 +80,7 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) | |||
| 80 | min_msk = 0x200D; | 80 | min_msk = 0x200D; |
| 81 | max_msk = 0xFFFF; | 81 | max_msk = 0xFFFF; |
| 82 | break; | 82 | break; |
| 83 | case 0x4331: | ||
| 83 | case 43224: | 84 | case 43224: |
| 84 | case 43225: | 85 | case 43225: |
| 85 | break; | 86 | break; |
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index b8379b90d045..7e138ec21357 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c | |||
| @@ -61,7 +61,7 @@ static struct bus_type bcma_bus_type = { | |||
| 61 | .dev_attrs = bcma_device_attrs, | 61 | .dev_attrs = bcma_device_attrs, |
| 62 | }; | 62 | }; |
| 63 | 63 | ||
| 64 | static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid) | 64 | struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid) |
| 65 | { | 65 | { |
| 66 | struct bcma_device *core; | 66 | struct bcma_device *core; |
| 67 | 67 | ||
| @@ -71,6 +71,7 @@ static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid) | |||
| 71 | } | 71 | } |
| 72 | return NULL; | 72 | return NULL; |
| 73 | } | 73 | } |
| 74 | EXPORT_SYMBOL_GPL(bcma_find_core); | ||
| 74 | 75 | ||
| 75 | static void bcma_release_core_dev(struct device *dev) | 76 | static void bcma_release_core_dev(struct device *dev) |
| 76 | { | 77 | { |
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index ca7752510d5b..cdcf75c0954f 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | * Broadcom specific AMBA | 2 | * Broadcom specific AMBA |
| 3 | * SPROM reading | 3 | * SPROM reading |
| 4 | * | 4 | * |
| 5 | * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de> | ||
| 6 | * | ||
| 5 | * Licensed under the GNU/GPL. See COPYING for details. | 7 | * Licensed under the GNU/GPL. See COPYING for details. |
| 6 | */ | 8 | */ |
| 7 | 9 | ||
| @@ -14,6 +16,58 @@ | |||
| 14 | #include <linux/dma-mapping.h> | 16 | #include <linux/dma-mapping.h> |
| 15 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
| 16 | 18 | ||
| 19 | static int(*get_fallback_sprom)(struct bcma_bus *dev, struct ssb_sprom *out); | ||
| 20 | |||
| 21 | /** | ||
| 22 | * bcma_arch_register_fallback_sprom - Registers a method providing a | ||
| 23 | * fallback SPROM if no SPROM is found. | ||
| 24 | * | ||
| 25 | * @sprom_callback: The callback function. | ||
| 26 | * | ||
| 27 | * With this function the architecture implementation may register a | ||
| 28 | * callback handler which fills the SPROM data structure. The fallback is | ||
| 29 | * used for PCI based BCMA devices, where no valid SPROM can be found | ||
| 30 | * in the shadow registers and to provide the SPROM for SoCs where BCMA is | ||
| 31 | * to controll the system bus. | ||
| 32 | * | ||
| 33 | * This function is useful for weird architectures that have a half-assed | ||
| 34 | * BCMA device hardwired to their PCI bus. | ||
| 35 | * | ||
| 36 | * This function is available for architecture code, only. So it is not | ||
| 37 | * exported. | ||
| 38 | */ | ||
| 39 | int bcma_arch_register_fallback_sprom(int (*sprom_callback)(struct bcma_bus *bus, | ||
| 40 | struct ssb_sprom *out)) | ||
| 41 | { | ||
| 42 | if (get_fallback_sprom) | ||
| 43 | return -EEXIST; | ||
| 44 | get_fallback_sprom = sprom_callback; | ||
| 45 | |||
| 46 | return 0; | ||
| 47 | } | ||
| 48 | |||
| 49 | static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus, | ||
| 50 | struct ssb_sprom *out) | ||
| 51 | { | ||
| 52 | int err; | ||
| 53 | |||
| 54 | if (!get_fallback_sprom) { | ||
| 55 | err = -ENOENT; | ||
| 56 | goto fail; | ||
| 57 | } | ||
| 58 | |||
| 59 | err = get_fallback_sprom(bus, out); | ||
| 60 | if (err) | ||
| 61 | goto fail; | ||
| 62 | |||
| 63 | pr_debug("Using SPROM revision %d provided by" | ||
| 64 | " platform.\n", bus->sprom.revision); | ||
| 65 | return 0; | ||
| 66 | fail: | ||
| 67 | pr_warn("Using fallback SPROM failed (err %d)\n", err); | ||
| 68 | return err; | ||
| 69 | } | ||
| 70 | |||
| 17 | /************************************************** | 71 | /************************************************** |
| 18 | * R/W ops. | 72 | * R/W ops. |
| 19 | **************************************************/ | 73 | **************************************************/ |
| @@ -246,23 +300,128 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) | |||
| 246 | SSB_SROM8_FEM_ANTSWLUT_SHIFT); | 300 | SSB_SROM8_FEM_ANTSWLUT_SHIFT); |
| 247 | } | 301 | } |
| 248 | 302 | ||
| 303 | /* | ||
| 304 | * Indicates the presence of external SPROM. | ||
| 305 | */ | ||
| 306 | static bool bcma_sprom_ext_available(struct bcma_bus *bus) | ||
| 307 | { | ||
| 308 | u32 chip_status; | ||
| 309 | u32 srom_control; | ||
| 310 | u32 present_mask; | ||
| 311 | |||
| 312 | if (bus->drv_cc.core->id.rev >= 31) { | ||
| 313 | if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM)) | ||
| 314 | return false; | ||
| 315 | |||
| 316 | srom_control = bcma_read32(bus->drv_cc.core, | ||
| 317 | BCMA_CC_SROM_CONTROL); | ||
| 318 | return srom_control & BCMA_CC_SROM_CONTROL_PRESENT; | ||
| 319 | } | ||
| 320 | |||
| 321 | /* older chipcommon revisions use chip status register */ | ||
| 322 | chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT); | ||
| 323 | switch (bus->chipinfo.id) { | ||
| 324 | case 0x4313: | ||
| 325 | present_mask = BCMA_CC_CHIPST_4313_SPROM_PRESENT; | ||
| 326 | break; | ||
| 327 | |||
| 328 | case 0x4331: | ||
| 329 | present_mask = BCMA_CC_CHIPST_4331_SPROM_PRESENT; | ||
| 330 | break; | ||
| 331 | |||
| 332 | default: | ||
| 333 | return true; | ||
| 334 | } | ||
| 335 | |||
| 336 | return chip_status & present_mask; | ||
| 337 | } | ||
| 338 | |||
| 339 | /* | ||
| 340 | * Indicates that on-chip OTP memory is present and enabled. | ||
| 341 | */ | ||
| 342 | static bool bcma_sprom_onchip_available(struct bcma_bus *bus) | ||
| 343 | { | ||
| 344 | u32 chip_status; | ||
| 345 | u32 otpsize = 0; | ||
| 346 | bool present; | ||
| 347 | |||
| 348 | chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT); | ||
| 349 | switch (bus->chipinfo.id) { | ||
| 350 | case 0x4313: | ||
| 351 | present = chip_status & BCMA_CC_CHIPST_4313_OTP_PRESENT; | ||
| 352 | break; | ||
| 353 | |||
| 354 | case 0x4331: | ||
| 355 | present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT; | ||
| 356 | break; | ||
| 357 | |||
| 358 | case 43224: | ||
| 359 | case 43225: | ||
| 360 | /* for these chips OTP is always available */ | ||
| 361 | present = true; | ||
| 362 | break; | ||
| 363 | |||
| 364 | default: | ||
| 365 | present = false; | ||
| 366 | break; | ||
| 367 | } | ||
| 368 | |||
| 369 | if (present) { | ||
| 370 | otpsize = bus->drv_cc.capabilities & BCMA_CC_CAP_OTPS; | ||
| 371 | otpsize >>= BCMA_CC_CAP_OTPS_SHIFT; | ||
| 372 | } | ||
| 373 | |||
| 374 | return otpsize != 0; | ||
| 375 | } | ||
| 376 | |||
| 377 | /* | ||
| 378 | * Verify OTP is filled and determine the byte | ||
| 379 | * offset where SPROM data is located. | ||
| 380 | * | ||
| 381 | * On error, returns 0; byte offset otherwise. | ||
| 382 | */ | ||
| 383 | static int bcma_sprom_onchip_offset(struct bcma_bus *bus) | ||
| 384 | { | ||
| 385 | struct bcma_device *cc = bus->drv_cc.core; | ||
| 386 | u32 offset; | ||
| 387 | |||
| 388 | /* verify OTP status */ | ||
| 389 | if ((bcma_read32(cc, BCMA_CC_OTPS) & BCMA_CC_OTPS_GU_PROG_HW) == 0) | ||
| 390 | return 0; | ||
| 391 | |||
| 392 | /* obtain bit offset from otplayout register */ | ||
| 393 | offset = (bcma_read32(cc, BCMA_CC_OTPL) & BCMA_CC_OTPL_GURGN_OFFSET); | ||
| 394 | return BCMA_CC_SPROM + (offset >> 3); | ||
| 395 | } | ||
| 396 | |||
| 249 | int bcma_sprom_get(struct bcma_bus *bus) | 397 | int bcma_sprom_get(struct bcma_bus *bus) |
| 250 | { | 398 | { |
| 251 | u16 offset; | 399 | u16 offset = BCMA_CC_SPROM; |
| 252 | u16 *sprom; | 400 | u16 *sprom; |
| 253 | u32 sromctrl; | ||
| 254 | int err = 0; | 401 | int err = 0; |
| 255 | 402 | ||
| 256 | if (!bus->drv_cc.core) | 403 | if (!bus->drv_cc.core) |
| 257 | return -EOPNOTSUPP; | 404 | return -EOPNOTSUPP; |
| 258 | 405 | ||
| 259 | if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM)) | 406 | if (!bcma_sprom_ext_available(bus)) { |
| 260 | return -ENOENT; | 407 | /* |
| 261 | 408 | * External SPROM takes precedence so check | |
| 262 | if (bus->drv_cc.core->id.rev >= 32) { | 409 | * on-chip OTP only when no external SPROM |
| 263 | sromctrl = bcma_read32(bus->drv_cc.core, BCMA_CC_SROM_CONTROL); | 410 | * is present. |
| 264 | if (!(sromctrl & BCMA_CC_SROM_CONTROL_PRESENT)) | 411 | */ |
| 265 | return -ENOENT; | 412 | if (bcma_sprom_onchip_available(bus)) { |
| 413 | /* determine offset */ | ||
| 414 | offset = bcma_sprom_onchip_offset(bus); | ||
| 415 | } | ||
| 416 | if (!offset) { | ||
| 417 | /* | ||
| 418 | * Maybe there is no SPROM on the device? | ||
| 419 | * Now we ask the arch code if there is some sprom | ||
| 420 | * available for this device in some other storage. | ||
| 421 | */ | ||
| 422 | err = bcma_fill_sprom_with_fallback(bus, &bus->sprom); | ||
| 423 | return err; | ||
| 424 | } | ||
| 266 | } | 425 | } |
| 267 | 426 | ||
| 268 | sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), | 427 | sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), |
| @@ -273,11 +432,6 @@ int bcma_sprom_get(struct bcma_bus *bus) | |||
| 273 | if (bus->chipinfo.id == 0x4331) | 432 | if (bus->chipinfo.id == 0x4331) |
| 274 | bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false); | 433 | bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false); |
| 275 | 434 | ||
| 276 | /* Most cards have SPROM moved by additional offset 0x30 (48 dwords). | ||
| 277 | * According to brcm80211 this applies to cards with PCIe rev >= 6 | ||
| 278 | * TODO: understand this condition and use it */ | ||
| 279 | offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM : | ||
| 280 | BCMA_CC_SPROM_PCIE6; | ||
| 281 | pr_debug("SPROM offset 0x%x\n", offset); | 435 | pr_debug("SPROM offset 0x%x\n", offset); |
| 282 | bcma_sprom_read(bus, offset, sprom); | 436 | bcma_sprom_read(bus, offset, sprom); |
| 283 | 437 | ||
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 1c008c61b95c..ddc061dd150c 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
| @@ -1869,7 +1869,7 @@ static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock) | |||
| 1869 | 1869 | ||
| 1870 | static void try_auto_wep(struct airo_info *ai) | 1870 | static void try_auto_wep(struct airo_info *ai) |
| 1871 | { | 1871 | { |
| 1872 | if (auto_wep && !(ai->flags & FLAG_RADIO_DOWN)) { | 1872 | if (auto_wep && !test_bit(FLAG_RADIO_DOWN, &ai->flags)) { |
| 1873 | ai->expires = RUN_AT(3*HZ); | 1873 | ai->expires = RUN_AT(3*HZ); |
| 1874 | wake_up_interruptible(&ai->thr_wait); | 1874 | wake_up_interruptible(&ai->thr_wait); |
| 1875 | } | 1875 | } |
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 6640326f7005..8d434b8f5855 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
| @@ -1320,6 +1320,7 @@ struct ath5k_hw { | |||
| 1320 | struct ieee80211_vif *bslot[ATH_BCBUF]; | 1320 | struct ieee80211_vif *bslot[ATH_BCBUF]; |
| 1321 | u16 num_ap_vifs; | 1321 | u16 num_ap_vifs; |
| 1322 | u16 num_adhoc_vifs; | 1322 | u16 num_adhoc_vifs; |
| 1323 | u16 num_mesh_vifs; | ||
| 1323 | unsigned int bhalq, /* SW q for outgoing beacons */ | 1324 | unsigned int bhalq, /* SW q for outgoing beacons */ |
| 1324 | bmisscount, /* missed beacon transmits */ | 1325 | bmisscount, /* missed beacon transmits */ |
| 1325 | bintval, /* beacon interval in TU */ | 1326 | bintval, /* beacon interval in TU */ |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index a339693fbe26..0e643b016b32 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
| @@ -1867,7 +1867,8 @@ ath5k_beacon_send(struct ath5k_hw *ah) | |||
| 1867 | ah->bmisscount = 0; | 1867 | ah->bmisscount = 0; |
| 1868 | } | 1868 | } |
| 1869 | 1869 | ||
| 1870 | if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs > 1) || | 1870 | if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs + |
| 1871 | ah->num_mesh_vifs > 1) || | ||
| 1871 | ah->opmode == NL80211_IFTYPE_MESH_POINT) { | 1872 | ah->opmode == NL80211_IFTYPE_MESH_POINT) { |
| 1872 | u64 tsf = ath5k_hw_get_tsf64(ah); | 1873 | u64 tsf = ath5k_hw_get_tsf64(ah); |
| 1873 | u32 tsftu = TSF_TO_TU(tsf); | 1874 | u32 tsftu = TSF_TO_TU(tsf); |
| @@ -1952,7 +1953,8 @@ ath5k_beacon_update_timers(struct ath5k_hw *ah, u64 bc_tsf) | |||
| 1952 | u64 hw_tsf; | 1953 | u64 hw_tsf; |
| 1953 | 1954 | ||
| 1954 | intval = ah->bintval & AR5K_BEACON_PERIOD; | 1955 | intval = ah->bintval & AR5K_BEACON_PERIOD; |
| 1955 | if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs > 1) { | 1956 | if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs |
| 1957 | + ah->num_mesh_vifs > 1) { | ||
| 1956 | intval /= ATH_BCBUF; /* staggered multi-bss beacons */ | 1958 | intval /= ATH_BCBUF; /* staggered multi-bss beacons */ |
| 1957 | if (intval < 15) | 1959 | if (intval < 15) |
| 1958 | ATH5K_WARN(ah, "intval %u is too low, min 15\n", | 1960 | ATH5K_WARN(ah, "intval %u is too low, min 15\n", |
| @@ -2330,15 +2332,6 @@ ath5k_calibrate_work(struct work_struct *work) | |||
| 2330 | "got new rfgain, resetting\n"); | 2332 | "got new rfgain, resetting\n"); |
| 2331 | ieee80211_queue_work(ah->hw, &ah->reset_work); | 2333 | ieee80211_queue_work(ah->hw, &ah->reset_work); |
| 2332 | } | 2334 | } |
| 2333 | |||
| 2334 | /* TODO: On full calibration we should stop TX here, | ||
| 2335 | * so that it doesn't interfere (mostly due to gain_f | ||
| 2336 | * calibration that messes with tx packets -see phy.c). | ||
| 2337 | * | ||
| 2338 | * NOTE: Stopping the queues from above is not enough | ||
| 2339 | * to stop TX but saves us from disconecting (at least | ||
| 2340 | * we don't lose packets). */ | ||
| 2341 | ieee80211_stop_queues(ah->hw); | ||
| 2342 | } else | 2335 | } else |
| 2343 | ah->ah_cal_mask |= AR5K_CALIBRATION_SHORT; | 2336 | ah->ah_cal_mask |= AR5K_CALIBRATION_SHORT; |
| 2344 | 2337 | ||
| @@ -2353,10 +2346,9 @@ ath5k_calibrate_work(struct work_struct *work) | |||
| 2353 | ah->curchan->center_freq)); | 2346 | ah->curchan->center_freq)); |
| 2354 | 2347 | ||
| 2355 | /* Clear calibration flags */ | 2348 | /* Clear calibration flags */ |
| 2356 | if (ah->ah_cal_mask & AR5K_CALIBRATION_FULL) { | 2349 | if (ah->ah_cal_mask & AR5K_CALIBRATION_FULL) |
| 2357 | ieee80211_wake_queues(ah->hw); | ||
| 2358 | ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL; | 2350 | ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL; |
| 2359 | } else if (ah->ah_cal_mask & AR5K_CALIBRATION_SHORT) | 2351 | else if (ah->ah_cal_mask & AR5K_CALIBRATION_SHORT) |
| 2360 | ah->ah_cal_mask &= ~AR5K_CALIBRATION_SHORT; | 2352 | ah->ah_cal_mask &= ~AR5K_CALIBRATION_SHORT; |
| 2361 | } | 2353 | } |
| 2362 | 2354 | ||
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index af4c7ecb4b30..5c5329955414 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c | |||
| @@ -134,6 +134,8 @@ ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
| 134 | ah->num_ap_vifs++; | 134 | ah->num_ap_vifs++; |
| 135 | else if (avf->opmode == NL80211_IFTYPE_ADHOC) | 135 | else if (avf->opmode == NL80211_IFTYPE_ADHOC) |
| 136 | ah->num_adhoc_vifs++; | 136 | ah->num_adhoc_vifs++; |
| 137 | else if (avf->opmode == NL80211_IFTYPE_MESH_POINT) | ||
| 138 | ah->num_mesh_vifs++; | ||
| 137 | } | 139 | } |
| 138 | 140 | ||
| 139 | /* Any MAC address is fine, all others are included through the | 141 | /* Any MAC address is fine, all others are included through the |
| @@ -175,6 +177,8 @@ ath5k_remove_interface(struct ieee80211_hw *hw, | |||
| 175 | ah->num_ap_vifs--; | 177 | ah->num_ap_vifs--; |
| 176 | else if (avf->opmode == NL80211_IFTYPE_ADHOC) | 178 | else if (avf->opmode == NL80211_IFTYPE_ADHOC) |
| 177 | ah->num_adhoc_vifs--; | 179 | ah->num_adhoc_vifs--; |
| 180 | else if (avf->opmode == NL80211_IFTYPE_MESH_POINT) | ||
| 181 | ah->num_mesh_vifs--; | ||
| 178 | 182 | ||
| 179 | ath5k_update_bssid_mask_and_opmode(ah, NULL); | 183 | ath5k_update_bssid_mask_and_opmode(ah, NULL); |
| 180 | mutex_unlock(&ah->lock); | 184 | mutex_unlock(&ah->lock); |
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index e1f8613426a9..3a2845489a1b 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c | |||
| @@ -1871,31 +1871,15 @@ ath5k_hw_phy_calibrate(struct ath5k_hw *ah, | |||
| 1871 | ret = 0; | 1871 | ret = 0; |
| 1872 | } | 1872 | } |
| 1873 | 1873 | ||
| 1874 | /* On full calibration do an AGC calibration and | 1874 | /* On full calibration request a PAPD probe for |
| 1875 | * request a PAPD probe for gainf calibration if | 1875 | * gainf calibration if needed */ |
| 1876 | * needed */ | 1876 | if ((ah->ah_cal_mask & AR5K_CALIBRATION_FULL) && |
| 1877 | if (ah->ah_cal_mask & AR5K_CALIBRATION_FULL) { | 1877 | (ah->ah_radio == AR5K_RF5111 || |
| 1878 | 1878 | ah->ah_radio == AR5K_RF5112) && | |
| 1879 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, | 1879 | channel->hw_value != AR5K_MODE_11B) |
| 1880 | AR5K_PHY_AGCCTL_CAL); | 1880 | ath5k_hw_request_rfgain_probe(ah); |
| 1881 | 1881 | ||
| 1882 | ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, | 1882 | /* Update noise floor */ |
| 1883 | AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF, | ||
| 1884 | 0, false); | ||
| 1885 | if (ret) { | ||
| 1886 | ATH5K_ERR(ah, | ||
| 1887 | "gain calibration timeout (%uMHz)\n", | ||
| 1888 | channel->center_freq); | ||
| 1889 | } | ||
| 1890 | |||
| 1891 | if ((ah->ah_radio == AR5K_RF5111 || | ||
| 1892 | ah->ah_radio == AR5K_RF5112) | ||
| 1893 | && (channel->hw_value != AR5K_MODE_11B)) | ||
| 1894 | ath5k_hw_request_rfgain_probe(ah); | ||
| 1895 | } | ||
| 1896 | |||
| 1897 | /* Update noise floor | ||
| 1898 | * XXX: Only do this after AGC calibration */ | ||
| 1899 | if (!(ah->ah_cal_mask & AR5K_CALIBRATION_NF)) | 1883 | if (!(ah->ah_cal_mask & AR5K_CALIBRATION_NF)) |
| 1900 | ath5k_hw_update_noise_floor(ah); | 1884 | ath5k_hw_update_noise_floor(ah); |
| 1901 | 1885 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 18fa9aa8af92..97abf4699b41 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c | |||
| @@ -556,7 +556,8 @@ static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
| 556 | dlen, freq, vif->probe_req_report); | 556 | dlen, freq, vif->probe_req_report); |
| 557 | 557 | ||
| 558 | if (vif->probe_req_report || vif->nw_type == AP_NETWORK) | 558 | if (vif->probe_req_report || vif->nw_type == AP_NETWORK) |
| 559 | cfg80211_rx_mgmt(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC); | 559 | cfg80211_rx_mgmt(vif->ndev, freq, 0, |
| 560 | ev->data, dlen, GFP_ATOMIC); | ||
| 560 | 561 | ||
| 561 | return 0; | 562 | return 0; |
| 562 | } | 563 | } |
| @@ -595,7 +596,8 @@ static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
| 595 | return -EINVAL; | 596 | return -EINVAL; |
| 596 | } | 597 | } |
| 597 | ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq); | 598 | ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq); |
| 598 | cfg80211_rx_mgmt(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC); | 599 | cfg80211_rx_mgmt(vif->ndev, freq, 0, |
| 600 | ev->data, dlen, GFP_ATOMIC); | ||
| 599 | 601 | ||
| 600 | return 0; | 602 | return 0; |
| 601 | } | 603 | } |
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index 595a272aa96e..e507e78398f3 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig | |||
| @@ -81,6 +81,14 @@ config ATH9K_DFS_CERTIFIED | |||
| 81 | developed. At this point enabling this option won't do anything | 81 | developed. At this point enabling this option won't do anything |
| 82 | except increase code size. | 82 | except increase code size. |
| 83 | 83 | ||
| 84 | config ATH9K_MAC_DEBUG | ||
| 85 | bool "Atheros MAC statistics" | ||
| 86 | depends on ATH9K_DEBUGFS | ||
| 87 | default y | ||
| 88 | ---help--- | ||
| 89 | This option enables collection of statistics for Rx/Tx status | ||
| 90 | data and some other MAC related statistics | ||
| 91 | |||
| 84 | config ATH9K_RATE_CONTROL | 92 | config ATH9K_RATE_CONTROL |
| 85 | bool "Atheros ath9k rate control" | 93 | bool "Atheros ath9k rate control" |
| 86 | depends on ATH9K | 94 | depends on ATH9K |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 8d1bca03bc0e..a66a13b76848 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c | |||
| @@ -326,7 +326,6 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) | |||
| 326 | static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, | 326 | static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, |
| 327 | struct ath_tx_status *ts) | 327 | struct ath_tx_status *ts) |
| 328 | { | 328 | { |
| 329 | struct ar9003_txc *txc = (struct ar9003_txc *) ds; | ||
| 330 | struct ar9003_txs *ads; | 329 | struct ar9003_txs *ads; |
| 331 | u32 status; | 330 | u32 status; |
| 332 | 331 | ||
| @@ -336,11 +335,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, | |||
| 336 | if ((status & AR_TxDone) == 0) | 335 | if ((status & AR_TxDone) == 0) |
| 337 | return -EINPROGRESS; | 336 | return -EINPROGRESS; |
| 338 | 337 | ||
| 339 | ts->qid = MS(ads->ds_info, AR_TxQcuNum); | 338 | ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size; |
| 340 | if (!txc || (MS(txc->info, AR_TxQcuNum) == ts->qid)) | ||
| 341 | ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size; | ||
| 342 | else | ||
| 343 | return -ENOENT; | ||
| 344 | 339 | ||
| 345 | if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) || | 340 | if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) || |
| 346 | (MS(ads->ds_info, AR_TxRxDesc) != 1)) { | 341 | (MS(ads->ds_info, AR_TxRxDesc) != 1)) { |
| @@ -354,6 +349,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, | |||
| 354 | ts->ts_seqnum = MS(status, AR_SeqNum); | 349 | ts->ts_seqnum = MS(status, AR_SeqNum); |
| 355 | ts->tid = MS(status, AR_TxTid); | 350 | ts->tid = MS(status, AR_TxTid); |
| 356 | 351 | ||
| 352 | ts->qid = MS(ads->ds_info, AR_TxQcuNum); | ||
| 357 | ts->desc_id = MS(ads->status1, AR_TxDescId); | 353 | ts->desc_id = MS(ads->status1, AR_TxDescId); |
| 358 | ts->ts_tstamp = ads->status4; | 354 | ts->ts_tstamp = ads->status4; |
| 359 | ts->ts_status = 0; | 355 | ts->ts_status = 0; |
| @@ -440,20 +436,14 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs, | |||
| 440 | struct ar9003_rxs *rxsp = (struct ar9003_rxs *) buf_addr; | 436 | struct ar9003_rxs *rxsp = (struct ar9003_rxs *) buf_addr; |
| 441 | unsigned int phyerr; | 437 | unsigned int phyerr; |
| 442 | 438 | ||
| 443 | /* TODO: byte swap on big endian for ar9300_10 */ | 439 | if ((rxsp->status11 & AR_RxDone) == 0) |
| 444 | 440 | return -EINPROGRESS; | |
| 445 | if (!rxs) { | ||
| 446 | if ((rxsp->status11 & AR_RxDone) == 0) | ||
| 447 | return -EINPROGRESS; | ||
| 448 | |||
| 449 | if (MS(rxsp->ds_info, AR_DescId) != 0x168c) | ||
| 450 | return -EINVAL; | ||
| 451 | 441 | ||
| 452 | if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0) | 442 | if (MS(rxsp->ds_info, AR_DescId) != 0x168c) |
| 453 | return -EINPROGRESS; | 443 | return -EINVAL; |
| 454 | 444 | ||
| 455 | return 0; | 445 | if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0) |
| 456 | } | 446 | return -EINPROGRESS; |
| 457 | 447 | ||
| 458 | rxs->rs_status = 0; | 448 | rxs->rs_status = 0; |
| 459 | rxs->rs_flags = 0; | 449 | rxs->rs_flags = 0; |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index c2ccba676eca..3d8e51cd5d8f 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
| @@ -299,7 +299,6 @@ struct ath_tx { | |||
| 299 | 299 | ||
| 300 | struct ath_rx_edma { | 300 | struct ath_rx_edma { |
| 301 | struct sk_buff_head rx_fifo; | 301 | struct sk_buff_head rx_fifo; |
| 302 | struct sk_buff_head rx_buffers; | ||
| 303 | u32 rx_fifo_hwsize; | 302 | u32 rx_fifo_hwsize; |
| 304 | }; | 303 | }; |
| 305 | 304 | ||
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index b8967e482e6e..43882f9e25c4 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
| @@ -91,7 +91,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, | |||
| 91 | info.txpower = MAX_RATE_POWER; | 91 | info.txpower = MAX_RATE_POWER; |
| 92 | info.keyix = ATH9K_TXKEYIX_INVALID; | 92 | info.keyix = ATH9K_TXKEYIX_INVALID; |
| 93 | info.keytype = ATH9K_KEY_TYPE_CLEAR; | 93 | info.keytype = ATH9K_KEY_TYPE_CLEAR; |
| 94 | info.flags = ATH9K_TXDESC_NOACK; | 94 | info.flags = ATH9K_TXDESC_NOACK | ATH9K_TXDESC_INTREQ; |
| 95 | 95 | ||
| 96 | info.buf_addr[0] = bf->bf_buf_addr; | 96 | info.buf_addr[0] = bf->bf_buf_addr; |
| 97 | info.buf_len[0] = roundup(skb->len, 4); | 97 | info.buf_len[0] = roundup(skb->len, 4); |
| @@ -355,7 +355,6 @@ void ath_beacon_tasklet(unsigned long data) | |||
| 355 | struct ath_common *common = ath9k_hw_common(ah); | 355 | struct ath_common *common = ath9k_hw_common(ah); |
| 356 | struct ath_buf *bf = NULL; | 356 | struct ath_buf *bf = NULL; |
| 357 | struct ieee80211_vif *vif; | 357 | struct ieee80211_vif *vif; |
| 358 | struct ath_tx_status ts; | ||
| 359 | bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); | 358 | bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); |
| 360 | int slot; | 359 | int slot; |
| 361 | u32 bfaddr, bc = 0; | 360 | u32 bfaddr, bc = 0; |
| @@ -462,11 +461,6 @@ void ath_beacon_tasklet(unsigned long data) | |||
| 462 | ath9k_hw_txstart(ah, sc->beacon.beaconq); | 461 | ath9k_hw_txstart(ah, sc->beacon.beaconq); |
| 463 | 462 | ||
| 464 | sc->beacon.ast_be_xmit += bc; /* XXX per-vif? */ | 463 | sc->beacon.ast_be_xmit += bc; /* XXX per-vif? */ |
| 465 | if (edma) { | ||
| 466 | spin_lock_bh(&sc->sc_pcu_lock); | ||
| 467 | ath9k_hw_txprocdesc(ah, bf->bf_desc, (void *)&ts); | ||
| 468 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
| 469 | } | ||
| 470 | } | 464 | } |
| 471 | } | 465 | } |
| 472 | 466 | ||
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 228c18189a3a..c2edf688da49 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
| @@ -818,6 +818,7 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, | |||
| 818 | if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN) | 818 | if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN) |
| 819 | TX_STAT_INC(qnum, delim_underrun); | 819 | TX_STAT_INC(qnum, delim_underrun); |
| 820 | 820 | ||
| 821 | #ifdef CONFIG_ATH9K_MAC_DEBUG | ||
| 821 | spin_lock(&sc->debug.samp_lock); | 822 | spin_lock(&sc->debug.samp_lock); |
| 822 | TX_SAMP_DBG(jiffies) = jiffies; | 823 | TX_SAMP_DBG(jiffies) = jiffies; |
| 823 | TX_SAMP_DBG(rssi_ctl0) = ts->ts_rssi_ctl0; | 824 | TX_SAMP_DBG(rssi_ctl0) = ts->ts_rssi_ctl0; |
| @@ -844,6 +845,7 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, | |||
| 844 | 845 | ||
| 845 | sc->debug.tsidx = (sc->debug.tsidx + 1) % ATH_DBG_MAX_SAMPLES; | 846 | sc->debug.tsidx = (sc->debug.tsidx + 1) % ATH_DBG_MAX_SAMPLES; |
| 846 | spin_unlock(&sc->debug.samp_lock); | 847 | spin_unlock(&sc->debug.samp_lock); |
| 848 | #endif | ||
| 847 | 849 | ||
| 848 | #undef TX_SAMP_DBG | 850 | #undef TX_SAMP_DBG |
| 849 | } | 851 | } |
| @@ -942,27 +944,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, | |||
| 942 | PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL); | 944 | PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL); |
| 943 | 945 | ||
| 944 | len += snprintf(buf + len, size - len, | 946 | len += snprintf(buf + len, size - len, |
| 945 | "%22s : %10d\n", "RSSI-CTL0", | ||
| 946 | sc->debug.stats.rxstats.rs_rssi_ctl0); | ||
| 947 | len += snprintf(buf + len, size - len, | ||
| 948 | "%22s : %10d\n", "RSSI-CTL1", | ||
| 949 | sc->debug.stats.rxstats.rs_rssi_ctl1); | ||
| 950 | len += snprintf(buf + len, size - len, | ||
| 951 | "%22s : %10d\n", "RSSI-CTL2", | ||
| 952 | sc->debug.stats.rxstats.rs_rssi_ctl2); | ||
| 953 | len += snprintf(buf + len, size - len, | ||
| 954 | "%22s : %10d\n", "RSSI-EXT0", | ||
| 955 | sc->debug.stats.rxstats.rs_rssi_ext0); | ||
| 956 | len += snprintf(buf + len, size - len, | ||
| 957 | "%22s : %10d\n", "RSSI-EXT1", | ||
| 958 | sc->debug.stats.rxstats.rs_rssi_ext1); | ||
| 959 | len += snprintf(buf + len, size - len, | ||
| 960 | "%22s : %10d\n", "RSSI-EXT2", | ||
| 961 | sc->debug.stats.rxstats.rs_rssi_ext2); | ||
| 962 | len += snprintf(buf + len, size - len, | ||
| 963 | "%22s : %10d\n", "Rx Antenna", | ||
| 964 | sc->debug.stats.rxstats.rs_antenna); | ||
| 965 | len += snprintf(buf + len, size - len, | ||
| 966 | "%22s : %10u\n", "RX-Pkts-All", | 947 | "%22s : %10u\n", "RX-Pkts-All", |
| 967 | sc->debug.stats.rxstats.rx_pkts_all); | 948 | sc->debug.stats.rxstats.rx_pkts_all); |
| 968 | len += snprintf(buf + len, size - len, | 949 | len += snprintf(buf + len, size - len, |
| @@ -1009,16 +990,7 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) | |||
| 1009 | RX_PHY_ERR_INC(rs->rs_phyerr); | 990 | RX_PHY_ERR_INC(rs->rs_phyerr); |
| 1010 | } | 991 | } |
| 1011 | 992 | ||
| 1012 | sc->debug.stats.rxstats.rs_rssi_ctl0 = rs->rs_rssi_ctl0; | 993 | #ifdef CONFIG_ATH9K_MAC_DEBUG |
| 1013 | sc->debug.stats.rxstats.rs_rssi_ctl1 = rs->rs_rssi_ctl1; | ||
| 1014 | sc->debug.stats.rxstats.rs_rssi_ctl2 = rs->rs_rssi_ctl2; | ||
| 1015 | |||
| 1016 | sc->debug.stats.rxstats.rs_rssi_ext0 = rs->rs_rssi_ext0; | ||
| 1017 | sc->debug.stats.rxstats.rs_rssi_ext1 = rs->rs_rssi_ext1; | ||
| 1018 | sc->debug.stats.rxstats.rs_rssi_ext2 = rs->rs_rssi_ext2; | ||
| 1019 | |||
| 1020 | sc->debug.stats.rxstats.rs_antenna = rs->rs_antenna; | ||
| 1021 | |||
| 1022 | spin_lock(&sc->debug.samp_lock); | 994 | spin_lock(&sc->debug.samp_lock); |
| 1023 | RX_SAMP_DBG(jiffies) = jiffies; | 995 | RX_SAMP_DBG(jiffies) = jiffies; |
| 1024 | RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0; | 996 | RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0; |
| @@ -1035,6 +1007,8 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) | |||
| 1035 | sc->debug.rsidx = (sc->debug.rsidx + 1) % ATH_DBG_MAX_SAMPLES; | 1007 | sc->debug.rsidx = (sc->debug.rsidx + 1) % ATH_DBG_MAX_SAMPLES; |
| 1036 | spin_unlock(&sc->debug.samp_lock); | 1008 | spin_unlock(&sc->debug.samp_lock); |
| 1037 | 1009 | ||
| 1010 | #endif | ||
| 1011 | |||
| 1038 | #undef RX_STAT_INC | 1012 | #undef RX_STAT_INC |
| 1039 | #undef RX_PHY_ERR_INC | 1013 | #undef RX_PHY_ERR_INC |
| 1040 | #undef RX_SAMP_DBG | 1014 | #undef RX_SAMP_DBG |
| @@ -1278,6 +1252,8 @@ static const struct file_operations fops_modal_eeprom = { | |||
| 1278 | .llseek = default_llseek, | 1252 | .llseek = default_llseek, |
| 1279 | }; | 1253 | }; |
| 1280 | 1254 | ||
| 1255 | #ifdef CONFIG_ATH9K_MAC_DEBUG | ||
| 1256 | |||
| 1281 | void ath9k_debug_samp_bb_mac(struct ath_softc *sc) | 1257 | void ath9k_debug_samp_bb_mac(struct ath_softc *sc) |
| 1282 | { | 1258 | { |
| 1283 | #define ATH_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].c) | 1259 | #define ATH_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].c) |
| @@ -1551,6 +1527,7 @@ static const struct file_operations fops_samps = { | |||
| 1551 | .llseek = default_llseek, | 1527 | .llseek = default_llseek, |
| 1552 | }; | 1528 | }; |
| 1553 | 1529 | ||
| 1530 | #endif | ||
| 1554 | 1531 | ||
| 1555 | int ath9k_init_debug(struct ath_hw *ah) | 1532 | int ath9k_init_debug(struct ath_hw *ah) |
| 1556 | { | 1533 | { |
| @@ -1604,8 +1581,10 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
| 1604 | &fops_base_eeprom); | 1581 | &fops_base_eeprom); |
| 1605 | debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, | 1582 | debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, |
| 1606 | &fops_modal_eeprom); | 1583 | &fops_modal_eeprom); |
| 1584 | #ifdef CONFIG_ATH9K_MAC_DEBUG | ||
| 1607 | debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc, | 1585 | debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc, |
| 1608 | &fops_samps); | 1586 | &fops_samps); |
| 1587 | #endif | ||
| 1609 | 1588 | ||
| 1610 | debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, | 1589 | debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, |
| 1611 | sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); | 1590 | sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 776a24ada600..64fcfad467bf 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
| @@ -165,13 +165,6 @@ struct ath_rx_stats { | |||
| 165 | u32 post_delim_crc_err; | 165 | u32 post_delim_crc_err; |
| 166 | u32 decrypt_busy_err; | 166 | u32 decrypt_busy_err; |
| 167 | u32 phy_err_stats[ATH9K_PHYERR_MAX]; | 167 | u32 phy_err_stats[ATH9K_PHYERR_MAX]; |
| 168 | int8_t rs_rssi_ctl0; | ||
| 169 | int8_t rs_rssi_ctl1; | ||
| 170 | int8_t rs_rssi_ctl2; | ||
| 171 | int8_t rs_rssi_ext0; | ||
| 172 | int8_t rs_rssi_ext1; | ||
| 173 | int8_t rs_rssi_ext2; | ||
| 174 | u8 rs_antenna; | ||
| 175 | }; | 168 | }; |
| 176 | 169 | ||
| 177 | enum ath_reset_type { | 170 | enum ath_reset_type { |
| @@ -235,16 +228,17 @@ struct ath9k_debug { | |||
| 235 | struct dentry *debugfs_phy; | 228 | struct dentry *debugfs_phy; |
| 236 | u32 regidx; | 229 | u32 regidx; |
| 237 | struct ath_stats stats; | 230 | struct ath_stats stats; |
| 231 | #ifdef CONFIG_ATH9K_MAC_DEBUG | ||
| 238 | spinlock_t samp_lock; | 232 | spinlock_t samp_lock; |
| 239 | struct ath_dbg_bb_mac_samp bb_mac_samp[ATH_DBG_MAX_SAMPLES]; | 233 | struct ath_dbg_bb_mac_samp bb_mac_samp[ATH_DBG_MAX_SAMPLES]; |
| 240 | u8 sampidx; | 234 | u8 sampidx; |
| 241 | u8 tsidx; | 235 | u8 tsidx; |
| 242 | u8 rsidx; | 236 | u8 rsidx; |
| 237 | #endif | ||
| 243 | }; | 238 | }; |
| 244 | 239 | ||
| 245 | int ath9k_init_debug(struct ath_hw *ah); | 240 | int ath9k_init_debug(struct ath_hw *ah); |
| 246 | 241 | ||
| 247 | void ath9k_debug_samp_bb_mac(struct ath_softc *sc); | ||
| 248 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); | 242 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); |
| 249 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, | 243 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, |
| 250 | struct ath_tx_status *ts, struct ath_txq *txq, | 244 | struct ath_tx_status *ts, struct ath_txq *txq, |
| @@ -258,10 +252,6 @@ static inline int ath9k_init_debug(struct ath_hw *ah) | |||
| 258 | return 0; | 252 | return 0; |
| 259 | } | 253 | } |
| 260 | 254 | ||
| 261 | static inline void ath9k_debug_samp_bb_mac(struct ath_softc *sc) | ||
| 262 | { | ||
| 263 | } | ||
| 264 | |||
| 265 | static inline void ath_debug_stat_interrupt(struct ath_softc *sc, | 255 | static inline void ath_debug_stat_interrupt(struct ath_softc *sc, |
| 266 | enum ath9k_int status) | 256 | enum ath9k_int status) |
| 267 | { | 257 | { |
| @@ -282,4 +272,17 @@ static inline void ath_debug_stat_rx(struct ath_softc *sc, | |||
| 282 | 272 | ||
| 283 | #endif /* CONFIG_ATH9K_DEBUGFS */ | 273 | #endif /* CONFIG_ATH9K_DEBUGFS */ |
| 284 | 274 | ||
| 275 | #ifdef CONFIG_ATH9K_MAC_DEBUG | ||
| 276 | |||
| 277 | void ath9k_debug_samp_bb_mac(struct ath_softc *sc); | ||
| 278 | |||
| 279 | #else | ||
| 280 | |||
| 281 | static inline void ath9k_debug_samp_bb_mac(struct ath_softc *sc) | ||
| 282 | { | ||
| 283 | } | ||
| 284 | |||
| 285 | #endif | ||
| 286 | |||
| 287 | |||
| 285 | #endif /* DEBUG_H */ | 288 | #endif /* DEBUG_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 5c57568c64d9..2eb0ef315e31 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
| @@ -1386,10 +1386,16 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) | |||
| 1386 | static bool ath9k_hw_chip_reset(struct ath_hw *ah, | 1386 | static bool ath9k_hw_chip_reset(struct ath_hw *ah, |
| 1387 | struct ath9k_channel *chan) | 1387 | struct ath9k_channel *chan) |
| 1388 | { | 1388 | { |
| 1389 | if (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) { | 1389 | int reset_type = ATH9K_RESET_WARM; |
| 1390 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) | 1390 | |
| 1391 | return false; | 1391 | if (AR_SREV_9280(ah)) { |
| 1392 | } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) | 1392 | if (ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) |
| 1393 | reset_type = ATH9K_RESET_POWER_ON; | ||
| 1394 | else | ||
| 1395 | reset_type = ATH9K_RESET_COLD; | ||
| 1396 | } | ||
| 1397 | |||
| 1398 | if (!ath9k_hw_set_reset_reg(ah, reset_type)) | ||
| 1393 | return false; | 1399 | return false; |
| 1394 | 1400 | ||
| 1395 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) | 1401 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index d8b05961f7e3..944e9b518f19 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
| @@ -555,9 +555,11 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
| 555 | mutex_init(&sc->mutex); | 555 | mutex_init(&sc->mutex); |
| 556 | #ifdef CONFIG_ATH9K_DEBUGFS | 556 | #ifdef CONFIG_ATH9K_DEBUGFS |
| 557 | spin_lock_init(&sc->nodes_lock); | 557 | spin_lock_init(&sc->nodes_lock); |
| 558 | spin_lock_init(&sc->debug.samp_lock); | ||
| 559 | INIT_LIST_HEAD(&sc->nodes); | 558 | INIT_LIST_HEAD(&sc->nodes); |
| 560 | #endif | 559 | #endif |
| 560 | #ifdef CONFIG_ATH9K_MAC_DEBUG | ||
| 561 | spin_lock_init(&sc->debug.samp_lock); | ||
| 562 | #endif | ||
| 561 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); | 563 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); |
| 562 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, | 564 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, |
| 563 | (unsigned long)sc); | 565 | (unsigned long)sc); |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index e196aba77acf..5f4ae6c9a93c 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
| @@ -745,7 +745,11 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah) | |||
| 745 | qi.tqi_aifs = 1; | 745 | qi.tqi_aifs = 1; |
| 746 | qi.tqi_cwmin = 0; | 746 | qi.tqi_cwmin = 0; |
| 747 | qi.tqi_cwmax = 0; | 747 | qi.tqi_cwmax = 0; |
| 748 | /* NB: don't enable any interrupts */ | 748 | |
| 749 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | ||
| 750 | qi.tqi_qflags = TXQ_FLAG_TXOKINT_ENABLE | | ||
| 751 | TXQ_FLAG_TXERRINT_ENABLE; | ||
| 752 | |||
| 749 | return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi); | 753 | return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi); |
| 750 | } | 754 | } |
| 751 | EXPORT_SYMBOL(ath9k_hw_beaconq_setup); | 755 | EXPORT_SYMBOL(ath9k_hw_beaconq_setup); |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 02e95c8e7465..cc2535c38bed 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
| @@ -2300,6 +2300,7 @@ static int ath9k_tx_last_beacon(struct ieee80211_hw *hw) | |||
| 2300 | struct ath_vif *avp; | 2300 | struct ath_vif *avp; |
| 2301 | struct ath_buf *bf; | 2301 | struct ath_buf *bf; |
| 2302 | struct ath_tx_status ts; | 2302 | struct ath_tx_status ts; |
| 2303 | bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); | ||
| 2303 | int status; | 2304 | int status; |
| 2304 | 2305 | ||
| 2305 | vif = sc->beacon.bslot[0]; | 2306 | vif = sc->beacon.bslot[0]; |
| @@ -2310,7 +2311,7 @@ static int ath9k_tx_last_beacon(struct ieee80211_hw *hw) | |||
| 2310 | if (!avp->is_bslot_active) | 2311 | if (!avp->is_bslot_active) |
| 2311 | return 0; | 2312 | return 0; |
| 2312 | 2313 | ||
| 2313 | if (!sc->beacon.tx_processed) { | 2314 | if (!sc->beacon.tx_processed && !edma) { |
| 2314 | tasklet_disable(&sc->bcon_tasklet); | 2315 | tasklet_disable(&sc->bcon_tasklet); |
| 2315 | 2316 | ||
| 2316 | bf = avp->av_bcbuf; | 2317 | bf = avp->av_bcbuf; |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index b8c6c38cbb98..6407af22f7b9 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
| @@ -1226,7 +1226,7 @@ static void ath_rc_init(struct ath_softc *sc, | |||
| 1226 | ath_rc_init_valid_rate_idx(ath_rc_priv); | 1226 | ath_rc_init_valid_rate_idx(ath_rc_priv); |
| 1227 | 1227 | ||
| 1228 | for (i = 0; i < WLAN_RC_PHY_MAX; i++) { | 1228 | for (i = 0; i < WLAN_RC_PHY_MAX; i++) { |
| 1229 | for (j = 0; j < MAX_TX_RATE_PHY; j++) | 1229 | for (j = 0; j < RATE_TABLE_SIZE; j++) |
| 1230 | ath_rc_priv->valid_phy_rateidx[i][j] = 0; | 1230 | ath_rc_priv->valid_phy_rateidx[i][j] = 0; |
| 1231 | ath_rc_priv->valid_phy_ratecnt[i] = 0; | 1231 | ath_rc_priv->valid_phy_ratecnt[i] = 0; |
| 1232 | } | 1232 | } |
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index b7a4bcd3eec7..75f8e9b06b28 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h | |||
| @@ -25,8 +25,6 @@ struct ath_softc; | |||
| 25 | 25 | ||
| 26 | #define ATH_RATE_MAX 30 | 26 | #define ATH_RATE_MAX 30 |
| 27 | #define RATE_TABLE_SIZE 72 | 27 | #define RATE_TABLE_SIZE 72 |
| 28 | #define MAX_TX_RATE_PHY 48 | ||
| 29 | |||
| 30 | 28 | ||
| 31 | #define RC_INVALID 0x0000 | 29 | #define RC_INVALID 0x0000 |
| 32 | #define RC_LEGACY 0x0001 | 30 | #define RC_LEGACY 0x0001 |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 7e1a91af1497..1b1b279c304a 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
| @@ -169,22 +169,17 @@ static void ath_rx_addbuffer_edma(struct ath_softc *sc, | |||
| 169 | enum ath9k_rx_qtype qtype, int size) | 169 | enum ath9k_rx_qtype qtype, int size) |
| 170 | { | 170 | { |
| 171 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 171 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
| 172 | u32 nbuf = 0; | 172 | struct ath_buf *bf, *tbf; |
| 173 | 173 | ||
| 174 | if (list_empty(&sc->rx.rxbuf)) { | 174 | if (list_empty(&sc->rx.rxbuf)) { |
| 175 | ath_dbg(common, QUEUE, "No free rx buf available\n"); | 175 | ath_dbg(common, QUEUE, "No free rx buf available\n"); |
| 176 | return; | 176 | return; |
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | while (!list_empty(&sc->rx.rxbuf)) { | 179 | list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) |
| 180 | nbuf++; | ||
| 181 | |||
| 182 | if (!ath_rx_edma_buf_link(sc, qtype)) | 180 | if (!ath_rx_edma_buf_link(sc, qtype)) |
| 183 | break; | 181 | break; |
| 184 | 182 | ||
| 185 | if (nbuf >= size) | ||
| 186 | break; | ||
| 187 | } | ||
| 188 | } | 183 | } |
| 189 | 184 | ||
| 190 | static void ath_rx_remove_buffer(struct ath_softc *sc, | 185 | static void ath_rx_remove_buffer(struct ath_softc *sc, |
| @@ -232,7 +227,6 @@ static void ath_rx_edma_cleanup(struct ath_softc *sc) | |||
| 232 | static void ath_rx_edma_init_queue(struct ath_rx_edma *rx_edma, int size) | 227 | static void ath_rx_edma_init_queue(struct ath_rx_edma *rx_edma, int size) |
| 233 | { | 228 | { |
| 234 | skb_queue_head_init(&rx_edma->rx_fifo); | 229 | skb_queue_head_init(&rx_edma->rx_fifo); |
| 235 | skb_queue_head_init(&rx_edma->rx_buffers); | ||
| 236 | rx_edma->rx_fifo_hwsize = size; | 230 | rx_edma->rx_fifo_hwsize = size; |
| 237 | } | 231 | } |
| 238 | 232 | ||
| @@ -658,7 +652,9 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb, bool mybeacon) | |||
| 658 | } | 652 | } |
| 659 | 653 | ||
| 660 | static bool ath_edma_get_buffers(struct ath_softc *sc, | 654 | static bool ath_edma_get_buffers(struct ath_softc *sc, |
| 661 | enum ath9k_rx_qtype qtype) | 655 | enum ath9k_rx_qtype qtype, |
| 656 | struct ath_rx_status *rs, | ||
| 657 | struct ath_buf **dest) | ||
| 662 | { | 658 | { |
| 663 | struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype]; | 659 | struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype]; |
| 664 | struct ath_hw *ah = sc->sc_ah; | 660 | struct ath_hw *ah = sc->sc_ah; |
| @@ -677,7 +673,7 @@ static bool ath_edma_get_buffers(struct ath_softc *sc, | |||
| 677 | dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr, | 673 | dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr, |
| 678 | common->rx_bufsize, DMA_FROM_DEVICE); | 674 | common->rx_bufsize, DMA_FROM_DEVICE); |
| 679 | 675 | ||
| 680 | ret = ath9k_hw_process_rxdesc_edma(ah, NULL, skb->data); | 676 | ret = ath9k_hw_process_rxdesc_edma(ah, rs, skb->data); |
| 681 | if (ret == -EINPROGRESS) { | 677 | if (ret == -EINPROGRESS) { |
| 682 | /*let device gain the buffer again*/ | 678 | /*let device gain the buffer again*/ |
| 683 | dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, | 679 | dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, |
| @@ -690,20 +686,21 @@ static bool ath_edma_get_buffers(struct ath_softc *sc, | |||
| 690 | /* corrupt descriptor, skip this one and the following one */ | 686 | /* corrupt descriptor, skip this one and the following one */ |
| 691 | list_add_tail(&bf->list, &sc->rx.rxbuf); | 687 | list_add_tail(&bf->list, &sc->rx.rxbuf); |
| 692 | ath_rx_edma_buf_link(sc, qtype); | 688 | ath_rx_edma_buf_link(sc, qtype); |
| 693 | skb = skb_peek(&rx_edma->rx_fifo); | ||
| 694 | if (!skb) | ||
| 695 | return true; | ||
| 696 | 689 | ||
| 697 | bf = SKB_CB_ATHBUF(skb); | 690 | skb = skb_peek(&rx_edma->rx_fifo); |
| 698 | BUG_ON(!bf); | 691 | if (skb) { |
| 692 | bf = SKB_CB_ATHBUF(skb); | ||
| 693 | BUG_ON(!bf); | ||
| 699 | 694 | ||
| 700 | __skb_unlink(skb, &rx_edma->rx_fifo); | 695 | __skb_unlink(skb, &rx_edma->rx_fifo); |
| 701 | list_add_tail(&bf->list, &sc->rx.rxbuf); | 696 | list_add_tail(&bf->list, &sc->rx.rxbuf); |
| 702 | ath_rx_edma_buf_link(sc, qtype); | 697 | ath_rx_edma_buf_link(sc, qtype); |
| 703 | return true; | 698 | } else { |
| 699 | bf = NULL; | ||
| 700 | } | ||
| 704 | } | 701 | } |
| 705 | skb_queue_tail(&rx_edma->rx_buffers, skb); | ||
| 706 | 702 | ||
| 703 | *dest = bf; | ||
| 707 | return true; | 704 | return true; |
| 708 | } | 705 | } |
| 709 | 706 | ||
| @@ -711,18 +708,15 @@ static struct ath_buf *ath_edma_get_next_rx_buf(struct ath_softc *sc, | |||
| 711 | struct ath_rx_status *rs, | 708 | struct ath_rx_status *rs, |
| 712 | enum ath9k_rx_qtype qtype) | 709 | enum ath9k_rx_qtype qtype) |
| 713 | { | 710 | { |
| 714 | struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype]; | 711 | struct ath_buf *bf = NULL; |
| 715 | struct sk_buff *skb; | ||
| 716 | struct ath_buf *bf; | ||
| 717 | 712 | ||
| 718 | while (ath_edma_get_buffers(sc, qtype)); | 713 | while (ath_edma_get_buffers(sc, qtype, rs, &bf)) { |
| 719 | skb = __skb_dequeue(&rx_edma->rx_buffers); | 714 | if (!bf) |
| 720 | if (!skb) | 715 | continue; |
| 721 | return NULL; | ||
| 722 | 716 | ||
| 723 | bf = SKB_CB_ATHBUF(skb); | 717 | return bf; |
| 724 | ath9k_hw_process_rxdesc_edma(sc->sc_ah, rs, skb->data); | 718 | } |
| 725 | return bf; | 719 | return NULL; |
| 726 | } | 720 | } |
| 727 | 721 | ||
| 728 | static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, | 722 | static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, |
| @@ -954,6 +948,7 @@ static void ath9k_process_rssi(struct ath_common *common, | |||
| 954 | struct ath_softc *sc = hw->priv; | 948 | struct ath_softc *sc = hw->priv; |
| 955 | struct ath_hw *ah = common->ah; | 949 | struct ath_hw *ah = common->ah; |
| 956 | int last_rssi; | 950 | int last_rssi; |
| 951 | int rssi = rx_stats->rs_rssi; | ||
| 957 | 952 | ||
| 958 | if (!rx_stats->is_mybeacon || | 953 | if (!rx_stats->is_mybeacon || |
| 959 | ((ah->opmode != NL80211_IFTYPE_STATION) && | 954 | ((ah->opmode != NL80211_IFTYPE_STATION) && |
| @@ -965,13 +960,12 @@ static void ath9k_process_rssi(struct ath_common *common, | |||
| 965 | 960 | ||
| 966 | last_rssi = sc->last_rssi; | 961 | last_rssi = sc->last_rssi; |
| 967 | if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) | 962 | if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) |
| 968 | rx_stats->rs_rssi = ATH_EP_RND(last_rssi, | 963 | rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER); |
| 969 | ATH_RSSI_EP_MULTIPLIER); | 964 | if (rssi < 0) |
| 970 | if (rx_stats->rs_rssi < 0) | 965 | rssi = 0; |
| 971 | rx_stats->rs_rssi = 0; | ||
| 972 | 966 | ||
| 973 | /* Update Beacon RSSI, this is used by ANI. */ | 967 | /* Update Beacon RSSI, this is used by ANI. */ |
| 974 | ah->stats.avgbrssi = rx_stats->rs_rssi; | 968 | ah->stats.avgbrssi = rssi; |
| 975 | } | 969 | } |
| 976 | 970 | ||
| 977 | /* | 971 | /* |
| @@ -1011,6 +1005,8 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common, | |||
| 1011 | rx_status->signal = ah->noise + rx_stats->rs_rssi; | 1005 | rx_status->signal = ah->noise + rx_stats->rs_rssi; |
| 1012 | rx_status->antenna = rx_stats->rs_antenna; | 1006 | rx_status->antenna = rx_stats->rs_antenna; |
| 1013 | rx_status->flag |= RX_FLAG_MACTIME_MPDU; | 1007 | rx_status->flag |= RX_FLAG_MACTIME_MPDU; |
| 1008 | if (rx_stats->rs_moreaggr) | ||
| 1009 | rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; | ||
| 1014 | 1010 | ||
| 1015 | return 0; | 1011 | return 0; |
| 1016 | } | 1012 | } |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 5dd27d2712fc..9f785015a7dc 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
| @@ -2296,9 +2296,12 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
| 2296 | break; | 2296 | break; |
| 2297 | } | 2297 | } |
| 2298 | 2298 | ||
| 2299 | /* Skip beacon completions */ | 2299 | /* Process beacon completions separately */ |
| 2300 | if (ts.qid == sc->beacon.beaconq) | 2300 | if (ts.qid == sc->beacon.beaconq) { |
| 2301 | sc->beacon.tx_processed = true; | ||
| 2302 | sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK); | ||
| 2301 | continue; | 2303 | continue; |
| 2304 | } | ||
| 2302 | 2305 | ||
| 2303 | txq = &sc->tx.txq[ts.qid]; | 2306 | txq = &sc->tx.txq[ts.qid]; |
| 2304 | 2307 | ||
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 5189cf38123a..1d633f3b3274 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
| @@ -2706,6 +2706,8 @@ static int b43_gpio_init(struct b43_wldev *dev) | |||
| 2706 | mask |= 0x0060; | 2706 | mask |= 0x0060; |
| 2707 | set |= 0x0060; | 2707 | set |= 0x0060; |
| 2708 | } | 2708 | } |
| 2709 | if (dev->dev->chip_id == 0x5354) | ||
| 2710 | set &= 0xff02; | ||
| 2709 | if (0 /* FIXME: conditional unknown */ ) { | 2711 | if (0 /* FIXME: conditional unknown */ ) { |
| 2710 | b43_write16(dev, B43_MMIO_GPIO_MASK, | 2712 | b43_write16(dev, B43_MMIO_GPIO_MASK, |
| 2711 | b43_read16(dev, B43_MMIO_GPIO_MASK) | 2713 | b43_read16(dev, B43_MMIO_GPIO_MASK) |
diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c index 96faaef3661b..950334197f40 100644 --- a/drivers/net/wireless/b43legacy/phy.c +++ b/drivers/net/wireless/b43legacy/phy.c | |||
| @@ -1860,7 +1860,7 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev) | |||
| 1860 | * which accounts for the factor of 4 */ | 1860 | * which accounts for the factor of 4 */ |
| 1861 | #define REG_MAX_PWR 20 | 1861 | #define REG_MAX_PWR 20 |
| 1862 | max_pwr = min(REG_MAX_PWR * 4 | 1862 | max_pwr = min(REG_MAX_PWR * 4 |
| 1863 | - dev->dev->bus->sprom.antenna_gain.ghz24.a0 | 1863 | - dev->dev->bus->sprom.antenna_gain.a0 |
| 1864 | - 0x6, max_pwr); | 1864 | - 0x6, max_pwr); |
| 1865 | 1865 | ||
| 1866 | /* find the desired power in Q5.2 - power_level is in dBm | 1866 | /* find the desired power in Q5.2 - power_level is in dBm |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 83ca3cc2cccb..4688904908ec 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | |||
| @@ -604,7 +604,7 @@ void brcmf_sdio_exit(void) | |||
| 604 | sdio_unregister_driver(&brcmf_sdmmc_driver); | 604 | sdio_unregister_driver(&brcmf_sdmmc_driver); |
| 605 | } | 605 | } |
| 606 | 606 | ||
| 607 | int brcmf_sdio_init(void) | 607 | void brcmf_sdio_init(void) |
| 608 | { | 608 | { |
| 609 | int ret; | 609 | int ret; |
| 610 | 610 | ||
| @@ -614,6 +614,4 @@ int brcmf_sdio_init(void) | |||
| 614 | 614 | ||
| 615 | if (ret) | 615 | if (ret) |
| 616 | brcmf_dbg(ERROR, "sdio_register_driver failed: %d\n", ret); | 616 | brcmf_dbg(ERROR, "sdio_register_driver failed: %d\n", ret); |
| 617 | |||
| 618 | return ret; | ||
| 619 | } | 617 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index b7671b30692f..366916494be4 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | |||
| @@ -108,11 +108,11 @@ extern int brcmf_add_if(struct device *dev, int ifidx, | |||
| 108 | 108 | ||
| 109 | #ifdef CONFIG_BRCMFMAC_SDIO | 109 | #ifdef CONFIG_BRCMFMAC_SDIO |
| 110 | extern void brcmf_sdio_exit(void); | 110 | extern void brcmf_sdio_exit(void); |
| 111 | extern int brcmf_sdio_init(void); | 111 | extern void brcmf_sdio_init(void); |
| 112 | #endif | 112 | #endif |
| 113 | #ifdef CONFIG_BRCMFMAC_USB | 113 | #ifdef CONFIG_BRCMFMAC_USB |
| 114 | extern void brcmf_usb_exit(void); | 114 | extern void brcmf_usb_exit(void); |
| 115 | extern int brcmf_usb_init(void); | 115 | extern void brcmf_usb_init(void); |
| 116 | #endif | 116 | #endif |
| 117 | 117 | ||
| 118 | #endif /* _BRCMF_BUS_H_ */ | 118 | #endif /* _BRCMF_BUS_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index c4da05817443..2a1e5ae0c402 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | |||
| @@ -1181,27 +1181,29 @@ exit: | |||
| 1181 | } | 1181 | } |
| 1182 | #endif /* DEBUG */ | 1182 | #endif /* DEBUG */ |
| 1183 | 1183 | ||
| 1184 | static int __init brcmfmac_init(void) | 1184 | static void brcmf_driver_init(struct work_struct *work) |
| 1185 | { | 1185 | { |
| 1186 | int ret = 0; | ||
| 1187 | |||
| 1188 | #ifdef CONFIG_BRCMFMAC_SDIO | 1186 | #ifdef CONFIG_BRCMFMAC_SDIO |
| 1189 | ret = brcmf_sdio_init(); | 1187 | brcmf_sdio_init(); |
| 1190 | if (ret) | ||
| 1191 | goto fail; | ||
| 1192 | #endif | 1188 | #endif |
| 1193 | #ifdef CONFIG_BRCMFMAC_USB | 1189 | #ifdef CONFIG_BRCMFMAC_USB |
| 1194 | ret = brcmf_usb_init(); | 1190 | brcmf_usb_init(); |
| 1195 | if (ret) | ||
| 1196 | goto fail; | ||
| 1197 | #endif | 1191 | #endif |
| 1192 | } | ||
| 1193 | static DECLARE_WORK(brcmf_driver_work, brcmf_driver_init); | ||
| 1198 | 1194 | ||
| 1199 | fail: | 1195 | static int __init brcmfmac_module_init(void) |
| 1200 | return ret; | 1196 | { |
| 1197 | if (!schedule_work(&brcmf_driver_work)) | ||
| 1198 | return -EBUSY; | ||
| 1199 | |||
| 1200 | return 0; | ||
| 1201 | } | 1201 | } |
| 1202 | 1202 | ||
| 1203 | static void __exit brcmfmac_exit(void) | 1203 | static void __exit brcmfmac_module_exit(void) |
| 1204 | { | 1204 | { |
| 1205 | cancel_work_sync(&brcmf_driver_work); | ||
| 1206 | |||
| 1205 | #ifdef CONFIG_BRCMFMAC_SDIO | 1207 | #ifdef CONFIG_BRCMFMAC_SDIO |
| 1206 | brcmf_sdio_exit(); | 1208 | brcmf_sdio_exit(); |
| 1207 | #endif | 1209 | #endif |
| @@ -1210,5 +1212,5 @@ static void __exit brcmfmac_exit(void) | |||
| 1210 | #endif | 1212 | #endif |
| 1211 | } | 1213 | } |
| 1212 | 1214 | ||
| 1213 | module_init(brcmfmac_init); | 1215 | module_init(brcmfmac_module_init); |
| 1214 | module_exit(brcmfmac_exit); | 1216 | module_exit(brcmfmac_module_exit); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index d4a9e8e7deb3..82364223e817 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c | |||
| @@ -514,9 +514,9 @@ static void brcmf_usb_tx_complete(struct urb *urb) | |||
| 514 | 514 | ||
| 515 | brcmf_usb_del_fromq(devinfo, req); | 515 | brcmf_usb_del_fromq(devinfo, req); |
| 516 | if (urb->status == 0) | 516 | if (urb->status == 0) |
| 517 | devinfo->bus_pub.stats.tx_packets++; | 517 | devinfo->bus_pub.bus->dstats.tx_packets++; |
| 518 | else | 518 | else |
| 519 | devinfo->bus_pub.stats.tx_errors++; | 519 | devinfo->bus_pub.bus->dstats.tx_errors++; |
| 520 | 520 | ||
| 521 | dev_kfree_skb(req->skb); | 521 | dev_kfree_skb(req->skb); |
| 522 | req->skb = NULL; | 522 | req->skb = NULL; |
| @@ -536,9 +536,9 @@ static void brcmf_usb_rx_complete(struct urb *urb) | |||
| 536 | req->skb = NULL; | 536 | req->skb = NULL; |
| 537 | 537 | ||
| 538 | if (urb->status == 0) { | 538 | if (urb->status == 0) { |
| 539 | devinfo->bus_pub.stats.rx_packets++; | 539 | devinfo->bus_pub.bus->dstats.rx_packets++; |
| 540 | } else { | 540 | } else { |
| 541 | devinfo->bus_pub.stats.rx_errors++; | 541 | devinfo->bus_pub.bus->dstats.rx_errors++; |
| 542 | dev_kfree_skb(skb); | 542 | dev_kfree_skb(skb); |
| 543 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); | 543 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); |
| 544 | return; | 544 | return; |
| @@ -712,9 +712,6 @@ static int brcmf_usb_up(struct device *dev) | |||
| 712 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); | 712 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); |
| 713 | u16 ifnum; | 713 | u16 ifnum; |
| 714 | 714 | ||
| 715 | if (devinfo == NULL) | ||
| 716 | return -EINVAL; | ||
| 717 | |||
| 718 | if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) | 715 | if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) |
| 719 | return 0; | 716 | return 0; |
| 720 | 717 | ||
| @@ -900,8 +897,8 @@ brcmf_usb_dlneeded(struct brcmf_usbdev_info *devinfo) | |||
| 900 | sizeof(struct bootrom_id_le)); | 897 | sizeof(struct bootrom_id_le)); |
| 901 | return false; | 898 | return false; |
| 902 | } else { | 899 | } else { |
| 903 | devinfo->bus_pub.attrib.devid = chipid; | 900 | devinfo->bus_pub.devid = chipid; |
| 904 | devinfo->bus_pub.attrib.chiprev = chiprev; | 901 | devinfo->bus_pub.chiprev = chiprev; |
| 905 | } | 902 | } |
| 906 | return true; | 903 | return true; |
| 907 | } | 904 | } |
| @@ -1067,7 +1064,7 @@ static int brcmf_usb_dlstart(struct brcmf_usbdev_info *devinfo, u8 *fw, int len) | |||
| 1067 | if (devinfo == NULL) | 1064 | if (devinfo == NULL) |
| 1068 | return -EINVAL; | 1065 | return -EINVAL; |
| 1069 | 1066 | ||
| 1070 | if (devinfo->bus_pub.attrib.devid == 0xDEAD) | 1067 | if (devinfo->bus_pub.devid == 0xDEAD) |
| 1071 | return -EINVAL; | 1068 | return -EINVAL; |
| 1072 | 1069 | ||
| 1073 | err = brcmf_usb_dl_writeimage(devinfo, fw, len); | 1070 | err = brcmf_usb_dl_writeimage(devinfo, fw, len); |
| @@ -1088,7 +1085,7 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo) | |||
| 1088 | if (!devinfo) | 1085 | if (!devinfo) |
| 1089 | return -EINVAL; | 1086 | return -EINVAL; |
| 1090 | 1087 | ||
| 1091 | if (devinfo->bus_pub.attrib.devid == 0xDEAD) | 1088 | if (devinfo->bus_pub.devid == 0xDEAD) |
| 1092 | return -EINVAL; | 1089 | return -EINVAL; |
| 1093 | 1090 | ||
| 1094 | /* Check we are runnable */ | 1091 | /* Check we are runnable */ |
| @@ -1127,18 +1124,19 @@ static bool brcmf_usb_chip_support(int chipid, int chiprev) | |||
| 1127 | static int | 1124 | static int |
| 1128 | brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo) | 1125 | brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo) |
| 1129 | { | 1126 | { |
| 1130 | struct brcmf_usb_attrib *attr; | 1127 | int devid, chiprev; |
| 1131 | int err; | 1128 | int err; |
| 1132 | 1129 | ||
| 1133 | brcmf_dbg(TRACE, "enter\n"); | 1130 | brcmf_dbg(TRACE, "enter\n"); |
| 1134 | if (devinfo == NULL) | 1131 | if (devinfo == NULL) |
| 1135 | return -ENODEV; | 1132 | return -ENODEV; |
| 1136 | 1133 | ||
| 1137 | attr = &devinfo->bus_pub.attrib; | 1134 | devid = devinfo->bus_pub.devid; |
| 1135 | chiprev = devinfo->bus_pub.chiprev; | ||
| 1138 | 1136 | ||
| 1139 | if (!brcmf_usb_chip_support(attr->devid, attr->chiprev)) { | 1137 | if (!brcmf_usb_chip_support(devid, chiprev)) { |
| 1140 | brcmf_dbg(ERROR, "unsupported chip %d rev %d\n", | 1138 | brcmf_dbg(ERROR, "unsupported chip %d rev %d\n", |
| 1141 | attr->devid, attr->chiprev); | 1139 | devid, chiprev); |
| 1142 | return -EINVAL; | 1140 | return -EINVAL; |
| 1143 | } | 1141 | } |
| 1144 | 1142 | ||
| @@ -1617,7 +1615,7 @@ void brcmf_usb_exit(void) | |||
| 1617 | g_image.len = 0; | 1615 | g_image.len = 0; |
| 1618 | } | 1616 | } |
| 1619 | 1617 | ||
| 1620 | int brcmf_usb_init(void) | 1618 | void brcmf_usb_init(void) |
| 1621 | { | 1619 | { |
| 1622 | return usb_register(&brcmf_usbdrvr); | 1620 | usb_register(&brcmf_usbdrvr); |
| 1623 | } | 1621 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.h b/drivers/net/wireless/brcm80211/brcmfmac/usb.h index b31da7b83ff7..acfa5e89872f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.h | |||
| @@ -33,36 +33,12 @@ enum brcmf_usb_pnp_state { | |||
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | struct brcmf_stats { | 35 | struct brcmf_stats { |
| 36 | u32 tx_errors; | ||
| 37 | u32 tx_packets; | ||
| 38 | u32 tx_multicast; | ||
| 39 | u32 tx_ctlpkts; | 36 | u32 tx_ctlpkts; |
| 40 | u32 tx_ctlerrs; | 37 | u32 tx_ctlerrs; |
| 41 | u32 tx_dropped; | ||
| 42 | u32 tx_flushed; | ||
| 43 | u32 rx_errors; | ||
| 44 | u32 rx_packets; | ||
| 45 | u32 rx_multicast; | ||
| 46 | u32 rx_ctlpkts; | 38 | u32 rx_ctlpkts; |
| 47 | u32 rx_ctlerrs; | 39 | u32 rx_ctlerrs; |
| 48 | u32 rx_dropped; | ||
| 49 | u32 rx_flushed; | ||
| 50 | |||
| 51 | }; | ||
| 52 | |||
| 53 | struct brcmf_usb_attrib { | ||
| 54 | int bustype; | ||
| 55 | int vid; | ||
| 56 | int pid; | ||
| 57 | int devid; | ||
| 58 | int chiprev; /* chip revsion number */ | ||
| 59 | int mtu; | ||
| 60 | int nchan; /* Data Channels */ | ||
| 61 | int has_2nd_bulk_in_ep; | ||
| 62 | }; | 40 | }; |
| 63 | 41 | ||
| 64 | struct brcmf_usbdev_info; | ||
| 65 | |||
| 66 | struct brcmf_usbdev { | 42 | struct brcmf_usbdev { |
| 67 | struct brcmf_bus *bus; | 43 | struct brcmf_bus *bus; |
| 68 | struct brcmf_usbdev_info *devinfo; | 44 | struct brcmf_usbdev_info *devinfo; |
| @@ -70,7 +46,8 @@ struct brcmf_usbdev { | |||
| 70 | struct brcmf_stats stats; | 46 | struct brcmf_stats stats; |
| 71 | int ntxq, nrxq, rxsize; | 47 | int ntxq, nrxq, rxsize; |
| 72 | u32 bus_mtu; | 48 | u32 bus_mtu; |
| 73 | struct brcmf_usb_attrib attrib; | 49 | int devid; |
| 50 | int chiprev; /* chip revsion number */ | ||
| 74 | }; | 51 | }; |
| 75 | 52 | ||
| 76 | /* IO Request Block (IRB) */ | 53 | /* IO Request Block (IRB) */ |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c index dbee69620a90..95b5902bc4b3 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | |||
| @@ -959,14 +959,13 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
| 959 | if (supr_status) { | 959 | if (supr_status) { |
| 960 | update_rate = false; | 960 | update_rate = false; |
| 961 | if (supr_status == TX_STATUS_SUPR_BADCH) { | 961 | if (supr_status == TX_STATUS_SUPR_BADCH) { |
| 962 | wiphy_err(wiphy, "%s: Pkt tx suppressed, " | 962 | wiphy_err(wiphy, |
| 963 | "illegal channel possibly %d\n", | 963 | "%s: Pkt tx suppressed, illegal channel possibly %d\n", |
| 964 | __func__, CHSPEC_CHANNEL( | 964 | __func__, CHSPEC_CHANNEL( |
| 965 | wlc->default_bss->chanspec)); | 965 | wlc->default_bss->chanspec)); |
| 966 | } else { | 966 | } else { |
| 967 | if (supr_status != TX_STATUS_SUPR_FRAG) | 967 | if (supr_status != TX_STATUS_SUPR_FRAG) |
| 968 | wiphy_err(wiphy, "%s:" | 968 | wiphy_err(wiphy, "%s: supr_status 0x%x\n", |
| 969 | "supr_status 0x%x\n", | ||
| 970 | __func__, supr_status); | 969 | __func__, supr_status); |
| 971 | } | 970 | } |
| 972 | /* no need to retry for badch; will fail again */ | 971 | /* no need to retry for badch; will fail again */ |
| @@ -988,9 +987,8 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
| 988 | } | 987 | } |
| 989 | } else if (txs->phyerr) { | 988 | } else if (txs->phyerr) { |
| 990 | update_rate = false; | 989 | update_rate = false; |
| 991 | wiphy_err(wiphy, "wl%d: ampdu tx phy " | 990 | wiphy_err(wiphy, "%s: ampdu tx phy error (0x%x)\n", |
| 992 | "error (0x%x)\n", wlc->pub->unit, | 991 | __func__, txs->phyerr); |
| 993 | txs->phyerr); | ||
| 994 | 992 | ||
| 995 | if (brcm_msg_level & LOG_ERROR_VAL) { | 993 | if (brcm_msg_level & LOG_ERROR_VAL) { |
| 996 | brcmu_prpkt("txpkt (AMPDU)", p); | 994 | brcmu_prpkt("txpkt (AMPDU)", p); |
| @@ -1018,10 +1016,10 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
| 1018 | ack_recd = false; | 1016 | ack_recd = false; |
| 1019 | if (ba_recd) { | 1017 | if (ba_recd) { |
| 1020 | bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX); | 1018 | bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX); |
| 1021 | BCMMSG(wlc->wiphy, "tid %d seq %d," | 1019 | BCMMSG(wiphy, |
| 1022 | " start_seq %d, bindex %d set %d, index %d\n", | 1020 | "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n", |
| 1023 | tid, seq, start_seq, bindex, | 1021 | tid, seq, start_seq, bindex, |
| 1024 | isset(bitmap, bindex), index); | 1022 | isset(bitmap, bindex), index); |
| 1025 | /* if acked then clear bit and free packet */ | 1023 | /* if acked then clear bit and free packet */ |
| 1026 | if ((bindex < AMPDU_TX_BA_MAX_WSIZE) | 1024 | if ((bindex < AMPDU_TX_BA_MAX_WSIZE) |
| 1027 | && isset(bitmap, bindex)) { | 1025 | && isset(bitmap, bindex)) { |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index fec0f10773e5..569ab8abd2a1 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | |||
| @@ -1169,25 +1169,31 @@ static struct bcma_driver brcms_bcma_driver = { | |||
| 1169 | /** | 1169 | /** |
| 1170 | * This is the main entry point for the brcmsmac driver. | 1170 | * This is the main entry point for the brcmsmac driver. |
| 1171 | * | 1171 | * |
| 1172 | * This function determines if a device pointed to by pdev is a WL device, | 1172 | * This function is scheduled upon module initialization and |
| 1173 | * and if so, performs a brcms_attach() on it. | 1173 | * does the driver registration, which result in brcms_bcma_probe() |
| 1174 | * | 1174 | * call resulting in the driver bringup. |
| 1175 | */ | 1175 | */ |
| 1176 | static int __init brcms_module_init(void) | 1176 | static void brcms_driver_init(struct work_struct *work) |
| 1177 | { | 1177 | { |
| 1178 | int error = -ENODEV; | 1178 | int error; |
| 1179 | 1179 | ||
| 1180 | error = bcma_driver_register(&brcms_bcma_driver); | ||
| 1181 | if (error) | ||
| 1182 | pr_err("%s: register returned %d\n", __func__, error); | ||
| 1183 | } | ||
| 1184 | |||
| 1185 | static DECLARE_WORK(brcms_driver_work, brcms_driver_init); | ||
| 1186 | |||
| 1187 | static int __init brcms_module_init(void) | ||
| 1188 | { | ||
| 1180 | #ifdef DEBUG | 1189 | #ifdef DEBUG |
| 1181 | if (msglevel != 0xdeadbeef) | 1190 | if (msglevel != 0xdeadbeef) |
| 1182 | brcm_msg_level = msglevel; | 1191 | brcm_msg_level = msglevel; |
| 1183 | #endif /* DEBUG */ | 1192 | #endif |
| 1184 | 1193 | if (!schedule_work(&brcms_driver_work)) | |
| 1185 | error = bcma_driver_register(&brcms_bcma_driver); | 1194 | return -EBUSY; |
| 1186 | pr_err("%s: register returned %d\n", __func__, error); | ||
| 1187 | if (!error) | ||
| 1188 | return 0; | ||
| 1189 | 1195 | ||
| 1190 | return error; | 1196 | return 0; |
| 1191 | } | 1197 | } |
| 1192 | 1198 | ||
| 1193 | /** | 1199 | /** |
| @@ -1199,6 +1205,7 @@ static int __init brcms_module_init(void) | |||
| 1199 | */ | 1205 | */ |
| 1200 | static void __exit brcms_module_exit(void) | 1206 | static void __exit brcms_module_exit(void) |
| 1201 | { | 1207 | { |
| 1208 | cancel_work_sync(&brcms_driver_work); | ||
| 1202 | bcma_driver_unregister(&brcms_bcma_driver); | 1209 | bcma_driver_unregister(&brcms_bcma_driver); |
| 1203 | } | 1210 | } |
| 1204 | 1211 | ||
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 5fd56addca49..f0551f807f69 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c | |||
| @@ -298,8 +298,6 @@ static const char *command_types[] = { | |||
| 298 | }; | 298 | }; |
| 299 | #endif | 299 | #endif |
| 300 | 300 | ||
| 301 | #define WEXT_USECHANNELS 1 | ||
| 302 | |||
| 303 | static const long ipw2100_frequencies[] = { | 301 | static const long ipw2100_frequencies[] = { |
| 304 | 2412, 2417, 2422, 2427, | 302 | 2412, 2417, 2422, 2427, |
| 305 | 2432, 2437, 2442, 2447, | 303 | 2432, 2437, 2442, 2447, |
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.h b/drivers/net/wireless/ipw2x00/ipw2200.h index ecb561d7a7a0..66e84ec0eb55 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.h +++ b/drivers/net/wireless/ipw2x00/ipw2200.h | |||
| @@ -27,8 +27,6 @@ | |||
| 27 | #ifndef __ipw2200_h__ | 27 | #ifndef __ipw2200_h__ |
| 28 | #define __ipw2200_h__ | 28 | #define __ipw2200_h__ |
| 29 | 29 | ||
| 30 | #define WEXT_USECHANNELS 1 | ||
| 31 | |||
| 32 | #include <linux/module.h> | 30 | #include <linux/module.h> |
| 33 | #include <linux/moduleparam.h> | 31 | #include <linux/moduleparam.h> |
| 34 | #include <linux/init.h> | 32 | #include <linux/init.h> |
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index ae08498dfcad..2fe62730dddd 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config IWLWIFI | 1 | config IWLWIFI |
| 2 | tristate "Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlwifi) " | 2 | tristate "Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlwifi) " |
| 3 | depends on PCI && MAC80211 | 3 | depends on PCI && MAC80211 && HAS_IOMEM |
| 4 | select FW_LOADER | 4 | select FW_LOADER |
| 5 | select NEW_LEDS | 5 | select NEW_LEDS |
| 6 | select LEDS_CLASS | 6 | select LEDS_CLASS |
| @@ -127,3 +127,12 @@ config IWLWIFI_P2P | |||
| 127 | support when it is loaded. | 127 | support when it is loaded. |
| 128 | 128 | ||
| 129 | Say Y only if you want to experiment with P2P. | 129 | Say Y only if you want to experiment with P2P. |
| 130 | |||
| 131 | config IWLWIFI_EXPERIMENTAL_MFP | ||
| 132 | bool "support MFP (802.11w) even if uCode doesn't advertise" | ||
| 133 | depends on IWLWIFI | ||
| 134 | help | ||
| 135 | This option enables experimental MFP (802.11W) support | ||
| 136 | even if the microcode doesn't advertise it. | ||
| 137 | |||
| 138 | Say Y only if you want to experiment with MFP. | ||
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index afa0bb8f3245..85d163ed3db1 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
| @@ -14,7 +14,7 @@ iwlwifi-objs += iwl-1000.o | |||
| 14 | iwlwifi-objs += iwl-2000.o | 14 | iwlwifi-objs += iwl-2000.o |
| 15 | iwlwifi-objs += iwl-pci.o | 15 | iwlwifi-objs += iwl-pci.o |
| 16 | iwlwifi-objs += iwl-drv.o | 16 | iwlwifi-objs += iwl-drv.o |
| 17 | iwlwifi-objs += iwl-trans.o | 17 | iwlwifi-objs += iwl-notif-wait.o |
| 18 | iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o | 18 | iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o |
| 19 | 19 | ||
| 20 | iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o | 20 | iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o |
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 605ee3df1d82..5b0d888f746b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | #include "iwl-agn-hw.h" | 43 | #include "iwl-agn-hw.h" |
| 44 | #include "iwl-shared.h" | 44 | #include "iwl-shared.h" |
| 45 | #include "iwl-cfg.h" | 45 | #include "iwl-cfg.h" |
| 46 | #include "iwl-prph.h" | ||
| 46 | 47 | ||
| 47 | /* Highest firmware API version supported */ | 48 | /* Highest firmware API version supported */ |
| 48 | #define IWL1000_UCODE_API_MAX 6 | 49 | #define IWL1000_UCODE_API_MAX 6 |
| @@ -95,9 +96,8 @@ static void iwl1000_nic_config(struct iwl_priv *priv) | |||
| 95 | ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK); | 96 | ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK); |
| 96 | } | 97 | } |
| 97 | 98 | ||
| 98 | static struct iwl_sensitivity_ranges iwl1000_sensitivity = { | 99 | static const struct iwl_sensitivity_ranges iwl1000_sensitivity = { |
| 99 | .min_nrg_cck = 95, | 100 | .min_nrg_cck = 95, |
| 100 | .max_nrg_cck = 0, /* not used, set to 0 */ | ||
| 101 | .auto_corr_min_ofdm = 90, | 101 | .auto_corr_min_ofdm = 90, |
| 102 | .auto_corr_min_ofdm_mrc = 170, | 102 | .auto_corr_min_ofdm_mrc = 170, |
| 103 | .auto_corr_min_ofdm_x1 = 120, | 103 | .auto_corr_min_ofdm_x1 = 120, |
| @@ -122,23 +122,15 @@ static struct iwl_sensitivity_ranges iwl1000_sensitivity = { | |||
| 122 | 122 | ||
| 123 | static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) | 123 | static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) |
| 124 | { | 124 | { |
| 125 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && | ||
| 126 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) | ||
| 127 | cfg(priv)->base_params->num_of_queues = | ||
| 128 | iwlagn_mod_params.num_of_queues; | ||
| 129 | |||
| 130 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; | ||
| 131 | |||
| 132 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); | 125 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); |
| 133 | 126 | ||
| 134 | hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); | 127 | hw_params(priv).tx_chains_num = |
| 128 | num_of_ant(hw_params(priv).valid_tx_ant); | ||
| 135 | if (cfg(priv)->rx_with_siso_diversity) | 129 | if (cfg(priv)->rx_with_siso_diversity) |
| 136 | hw_params(priv).rx_chains_num = 1; | 130 | hw_params(priv).rx_chains_num = 1; |
| 137 | else | 131 | else |
| 138 | hw_params(priv).rx_chains_num = | 132 | hw_params(priv).rx_chains_num = |
| 139 | num_of_ant(cfg(priv)->valid_rx_ant); | 133 | num_of_ant(hw_params(priv).valid_rx_ant); |
| 140 | hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; | ||
| 141 | hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; | ||
| 142 | 134 | ||
| 143 | iwl1000_set_ct_threshold(priv); | 135 | iwl1000_set_ct_threshold(priv); |
| 144 | 136 | ||
| @@ -163,7 +155,7 @@ static struct iwl_lib_ops iwl1000_lib = { | |||
| 163 | .temperature = iwlagn_temperature, | 155 | .temperature = iwlagn_temperature, |
| 164 | }; | 156 | }; |
| 165 | 157 | ||
| 166 | static struct iwl_base_params iwl1000_base_params = { | 158 | static const struct iwl_base_params iwl1000_base_params = { |
| 167 | .num_of_queues = IWLAGN_NUM_QUEUES, | 159 | .num_of_queues = IWLAGN_NUM_QUEUES, |
| 168 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | 160 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, |
| 169 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 161 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
| @@ -178,7 +170,8 @@ static struct iwl_base_params iwl1000_base_params = { | |||
| 178 | .max_event_log_size = 128, | 170 | .max_event_log_size = 128, |
| 179 | .wd_disable = true, | 171 | .wd_disable = true, |
| 180 | }; | 172 | }; |
| 181 | static struct iwl_ht_params iwl1000_ht_params = { | 173 | |
| 174 | static const struct iwl_ht_params iwl1000_ht_params = { | ||
| 182 | .ht_greenfield_support = true, | 175 | .ht_greenfield_support = true, |
| 183 | .use_rts_for_aggregation = true, /* use rts/cts protection */ | 176 | .use_rts_for_aggregation = true, /* use rts/cts protection */ |
| 184 | .smps_mode = IEEE80211_SMPS_DYNAMIC, | 177 | .smps_mode = IEEE80211_SMPS_DYNAMIC, |
| @@ -197,13 +190,13 @@ static struct iwl_ht_params iwl1000_ht_params = { | |||
| 197 | .base_params = &iwl1000_base_params, \ | 190 | .base_params = &iwl1000_base_params, \ |
| 198 | .led_mode = IWL_LED_BLINK | 191 | .led_mode = IWL_LED_BLINK |
| 199 | 192 | ||
| 200 | struct iwl_cfg iwl1000_bgn_cfg = { | 193 | const struct iwl_cfg iwl1000_bgn_cfg = { |
| 201 | .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN", | 194 | .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN", |
| 202 | IWL_DEVICE_1000, | 195 | IWL_DEVICE_1000, |
| 203 | .ht_params = &iwl1000_ht_params, | 196 | .ht_params = &iwl1000_ht_params, |
| 204 | }; | 197 | }; |
| 205 | 198 | ||
| 206 | struct iwl_cfg iwl1000_bg_cfg = { | 199 | const struct iwl_cfg iwl1000_bg_cfg = { |
| 207 | .name = "Intel(R) Centrino(R) Wireless-N 1000 BG", | 200 | .name = "Intel(R) Centrino(R) Wireless-N 1000 BG", |
| 208 | IWL_DEVICE_1000, | 201 | IWL_DEVICE_1000, |
| 209 | }; | 202 | }; |
| @@ -222,13 +215,13 @@ struct iwl_cfg iwl1000_bg_cfg = { | |||
| 222 | .led_mode = IWL_LED_RF_STATE, \ | 215 | .led_mode = IWL_LED_RF_STATE, \ |
| 223 | .rx_with_siso_diversity = true | 216 | .rx_with_siso_diversity = true |
| 224 | 217 | ||
| 225 | struct iwl_cfg iwl100_bgn_cfg = { | 218 | const struct iwl_cfg iwl100_bgn_cfg = { |
| 226 | .name = "Intel(R) Centrino(R) Wireless-N 100 BGN", | 219 | .name = "Intel(R) Centrino(R) Wireless-N 100 BGN", |
| 227 | IWL_DEVICE_100, | 220 | IWL_DEVICE_100, |
| 228 | .ht_params = &iwl1000_ht_params, | 221 | .ht_params = &iwl1000_ht_params, |
| 229 | }; | 222 | }; |
| 230 | 223 | ||
| 231 | struct iwl_cfg iwl100_bg_cfg = { | 224 | const struct iwl_cfg iwl100_bg_cfg = { |
| 232 | .name = "Intel(R) Centrino(R) Wireless-N 100 BG", | 225 | .name = "Intel(R) Centrino(R) Wireless-N 100 BG", |
| 233 | IWL_DEVICE_100, | 226 | IWL_DEVICE_100, |
| 234 | }; | 227 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index e6e8c79a80d8..5635b9e2c69e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c | |||
| @@ -91,9 +91,8 @@ static void iwl2000_nic_config(struct iwl_priv *priv) | |||
| 91 | CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); | 91 | CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | static struct iwl_sensitivity_ranges iwl2000_sensitivity = { | 94 | static const struct iwl_sensitivity_ranges iwl2000_sensitivity = { |
| 95 | .min_nrg_cck = 97, | 95 | .min_nrg_cck = 97, |
| 96 | .max_nrg_cck = 0, /* not used, set to 0 */ | ||
| 97 | .auto_corr_min_ofdm = 80, | 96 | .auto_corr_min_ofdm = 80, |
| 98 | .auto_corr_min_ofdm_mrc = 128, | 97 | .auto_corr_min_ofdm_mrc = 128, |
| 99 | .auto_corr_min_ofdm_x1 = 105, | 98 | .auto_corr_min_ofdm_x1 = 105, |
| @@ -118,23 +117,15 @@ static struct iwl_sensitivity_ranges iwl2000_sensitivity = { | |||
| 118 | 117 | ||
| 119 | static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) | 118 | static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) |
| 120 | { | 119 | { |
| 121 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && | ||
| 122 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) | ||
| 123 | cfg(priv)->base_params->num_of_queues = | ||
| 124 | iwlagn_mod_params.num_of_queues; | ||
| 125 | |||
| 126 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; | ||
| 127 | |||
| 128 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); | 120 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); |
| 129 | 121 | ||
| 130 | hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); | 122 | hw_params(priv).tx_chains_num = |
| 123 | num_of_ant(hw_params(priv).valid_tx_ant); | ||
| 131 | if (cfg(priv)->rx_with_siso_diversity) | 124 | if (cfg(priv)->rx_with_siso_diversity) |
| 132 | hw_params(priv).rx_chains_num = 1; | 125 | hw_params(priv).rx_chains_num = 1; |
| 133 | else | 126 | else |
| 134 | hw_params(priv).rx_chains_num = | 127 | hw_params(priv).rx_chains_num = |
| 135 | num_of_ant(cfg(priv)->valid_rx_ant); | 128 | num_of_ant(hw_params(priv).valid_rx_ant); |
| 136 | hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; | ||
| 137 | hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; | ||
| 138 | 129 | ||
| 139 | iwl2000_set_ct_threshold(priv); | 130 | iwl2000_set_ct_threshold(priv); |
| 140 | 131 | ||
| @@ -155,16 +146,13 @@ static struct iwl_lib_ops iwl2000_lib = { | |||
| 155 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | 146 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, |
| 156 | EEPROM_REGULATORY_BAND_NO_HT40, | 147 | EEPROM_REGULATORY_BAND_NO_HT40, |
| 157 | }, | 148 | }, |
| 158 | .update_enhanced_txpower = iwl_eeprom_enhanced_txpower, | 149 | .enhanced_txpower = true, |
| 159 | }, | 150 | }, |
| 160 | .temperature = iwlagn_temperature, | 151 | .temperature = iwlagn_temperature, |
| 161 | }; | 152 | }; |
| 162 | 153 | ||
| 163 | static struct iwl_lib_ops iwl2030_lib = { | 154 | static struct iwl_lib_ops iwl2030_lib = { |
| 164 | .set_hw_params = iwl2000_hw_set_hw_params, | 155 | .set_hw_params = iwl2000_hw_set_hw_params, |
| 165 | .bt_rx_handler_setup = iwlagn_bt_rx_handler_setup, | ||
| 166 | .bt_setup_deferred_work = iwlagn_bt_setup_deferred_work, | ||
| 167 | .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, | ||
| 168 | .nic_config = iwl2000_nic_config, | 156 | .nic_config = iwl2000_nic_config, |
| 169 | .eeprom_ops = { | 157 | .eeprom_ops = { |
| 170 | .regulatory_bands = { | 158 | .regulatory_bands = { |
| @@ -176,12 +164,12 @@ static struct iwl_lib_ops iwl2030_lib = { | |||
| 176 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | 164 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, |
| 177 | EEPROM_REGULATORY_BAND_NO_HT40, | 165 | EEPROM_REGULATORY_BAND_NO_HT40, |
| 178 | }, | 166 | }, |
| 179 | .update_enhanced_txpower = iwl_eeprom_enhanced_txpower, | 167 | .enhanced_txpower = true, |
| 180 | }, | 168 | }, |
| 181 | .temperature = iwlagn_temperature, | 169 | .temperature = iwlagn_temperature, |
| 182 | }; | 170 | }; |
| 183 | 171 | ||
| 184 | static struct iwl_base_params iwl2000_base_params = { | 172 | static const struct iwl_base_params iwl2000_base_params = { |
| 185 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 173 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
| 186 | .num_of_queues = IWLAGN_NUM_QUEUES, | 174 | .num_of_queues = IWLAGN_NUM_QUEUES, |
| 187 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | 175 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, |
| @@ -200,7 +188,7 @@ static struct iwl_base_params iwl2000_base_params = { | |||
| 200 | }; | 188 | }; |
| 201 | 189 | ||
| 202 | 190 | ||
| 203 | static struct iwl_base_params iwl2030_base_params = { | 191 | static const struct iwl_base_params iwl2030_base_params = { |
| 204 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 192 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
| 205 | .num_of_queues = IWLAGN_NUM_QUEUES, | 193 | .num_of_queues = IWLAGN_NUM_QUEUES, |
| 206 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | 194 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, |
| @@ -218,12 +206,12 @@ static struct iwl_base_params iwl2030_base_params = { | |||
| 218 | .hd_v2 = true, | 206 | .hd_v2 = true, |
| 219 | }; | 207 | }; |
| 220 | 208 | ||
| 221 | static struct iwl_ht_params iwl2000_ht_params = { | 209 | static const struct iwl_ht_params iwl2000_ht_params = { |
| 222 | .ht_greenfield_support = true, | 210 | .ht_greenfield_support = true, |
| 223 | .use_rts_for_aggregation = true, /* use rts/cts protection */ | 211 | .use_rts_for_aggregation = true, /* use rts/cts protection */ |
| 224 | }; | 212 | }; |
| 225 | 213 | ||
| 226 | static struct iwl_bt_params iwl2030_bt_params = { | 214 | static const struct iwl_bt_params iwl2030_bt_params = { |
| 227 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ | 215 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ |
| 228 | .advanced_bt_coexist = true, | 216 | .advanced_bt_coexist = true, |
| 229 | .agg_time_limit = BT_AGG_THRESHOLD_DEF, | 217 | .agg_time_limit = BT_AGG_THRESHOLD_DEF, |
| @@ -249,13 +237,13 @@ static struct iwl_bt_params iwl2030_bt_params = { | |||
| 249 | .led_mode = IWL_LED_RF_STATE, \ | 237 | .led_mode = IWL_LED_RF_STATE, \ |
| 250 | .iq_invert = true \ | 238 | .iq_invert = true \ |
| 251 | 239 | ||
| 252 | struct iwl_cfg iwl2000_2bgn_cfg = { | 240 | const struct iwl_cfg iwl2000_2bgn_cfg = { |
| 253 | .name = "Intel(R) Centrino(R) Wireless-N 2200 BGN", | 241 | .name = "Intel(R) Centrino(R) Wireless-N 2200 BGN", |
| 254 | IWL_DEVICE_2000, | 242 | IWL_DEVICE_2000, |
| 255 | .ht_params = &iwl2000_ht_params, | 243 | .ht_params = &iwl2000_ht_params, |
| 256 | }; | 244 | }; |
| 257 | 245 | ||
| 258 | struct iwl_cfg iwl2000_2bgn_d_cfg = { | 246 | const struct iwl_cfg iwl2000_2bgn_d_cfg = { |
| 259 | .name = "Intel(R) Centrino(R) Wireless-N 2200D BGN", | 247 | .name = "Intel(R) Centrino(R) Wireless-N 2200D BGN", |
| 260 | IWL_DEVICE_2000, | 248 | IWL_DEVICE_2000, |
| 261 | .ht_params = &iwl2000_ht_params, | 249 | .ht_params = &iwl2000_ht_params, |
| @@ -279,7 +267,7 @@ struct iwl_cfg iwl2000_2bgn_d_cfg = { | |||
| 279 | .adv_pm = true, \ | 267 | .adv_pm = true, \ |
| 280 | .iq_invert = true \ | 268 | .iq_invert = true \ |
| 281 | 269 | ||
| 282 | struct iwl_cfg iwl2030_2bgn_cfg = { | 270 | const struct iwl_cfg iwl2030_2bgn_cfg = { |
| 283 | .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN", | 271 | .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN", |
| 284 | IWL_DEVICE_2030, | 272 | IWL_DEVICE_2030, |
| 285 | .ht_params = &iwl2000_ht_params, | 273 | .ht_params = &iwl2000_ht_params, |
| @@ -303,13 +291,13 @@ struct iwl_cfg iwl2030_2bgn_cfg = { | |||
| 303 | .rx_with_siso_diversity = true, \ | 291 | .rx_with_siso_diversity = true, \ |
| 304 | .iq_invert = true \ | 292 | .iq_invert = true \ |
| 305 | 293 | ||
| 306 | struct iwl_cfg iwl105_bgn_cfg = { | 294 | const struct iwl_cfg iwl105_bgn_cfg = { |
| 307 | .name = "Intel(R) Centrino(R) Wireless-N 105 BGN", | 295 | .name = "Intel(R) Centrino(R) Wireless-N 105 BGN", |
| 308 | IWL_DEVICE_105, | 296 | IWL_DEVICE_105, |
| 309 | .ht_params = &iwl2000_ht_params, | 297 | .ht_params = &iwl2000_ht_params, |
| 310 | }; | 298 | }; |
| 311 | 299 | ||
| 312 | struct iwl_cfg iwl105_bgn_d_cfg = { | 300 | const struct iwl_cfg iwl105_bgn_d_cfg = { |
| 313 | .name = "Intel(R) Centrino(R) Wireless-N 105D BGN", | 301 | .name = "Intel(R) Centrino(R) Wireless-N 105D BGN", |
| 314 | IWL_DEVICE_105, | 302 | IWL_DEVICE_105, |
| 315 | .ht_params = &iwl2000_ht_params, | 303 | .ht_params = &iwl2000_ht_params, |
| @@ -334,7 +322,7 @@ struct iwl_cfg iwl105_bgn_d_cfg = { | |||
| 334 | .rx_with_siso_diversity = true, \ | 322 | .rx_with_siso_diversity = true, \ |
| 335 | .iq_invert = true \ | 323 | .iq_invert = true \ |
| 336 | 324 | ||
| 337 | struct iwl_cfg iwl135_bgn_cfg = { | 325 | const struct iwl_cfg iwl135_bgn_cfg = { |
| 338 | .name = "Intel(R) Centrino(R) Wireless-N 135 BGN", | 326 | .name = "Intel(R) Centrino(R) Wireless-N 135 BGN", |
| 339 | IWL_DEVICE_135, | 327 | IWL_DEVICE_135, |
| 340 | .ht_params = &iwl2000_ht_params, | 328 | .ht_params = &iwl2000_ht_params, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 1527dec7a267..a805e97b89af 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
| @@ -45,6 +45,7 @@ | |||
| 45 | #include "iwl-trans.h" | 45 | #include "iwl-trans.h" |
| 46 | #include "iwl-shared.h" | 46 | #include "iwl-shared.h" |
| 47 | #include "iwl-cfg.h" | 47 | #include "iwl-cfg.h" |
| 48 | #include "iwl-prph.h" | ||
| 48 | 49 | ||
| 49 | /* Highest firmware API version supported */ | 50 | /* Highest firmware API version supported */ |
| 50 | #define IWL5000_UCODE_API_MAX 5 | 51 | #define IWL5000_UCODE_API_MAX 5 |
| @@ -63,12 +64,8 @@ | |||
| 63 | /* NIC configuration for 5000 series */ | 64 | /* NIC configuration for 5000 series */ |
| 64 | static void iwl5000_nic_config(struct iwl_priv *priv) | 65 | static void iwl5000_nic_config(struct iwl_priv *priv) |
| 65 | { | 66 | { |
| 66 | unsigned long flags; | ||
| 67 | |||
| 68 | iwl_rf_config(priv); | 67 | iwl_rf_config(priv); |
| 69 | 68 | ||
| 70 | spin_lock_irqsave(&priv->shrd->lock, flags); | ||
| 71 | |||
| 72 | /* W/A : NIC is stuck in a reset state after Early PCIe power off | 69 | /* W/A : NIC is stuck in a reset state after Early PCIe power off |
| 73 | * (PCIe power is lost before PERST# is asserted), | 70 | * (PCIe power is lost before PERST# is asserted), |
| 74 | * causing ME FW to lose ownership and not being able to obtain it back. | 71 | * causing ME FW to lose ownership and not being able to obtain it back. |
| @@ -76,14 +73,10 @@ static void iwl5000_nic_config(struct iwl_priv *priv) | |||
| 76 | iwl_set_bits_mask_prph(trans(priv), APMG_PS_CTRL_REG, | 73 | iwl_set_bits_mask_prph(trans(priv), APMG_PS_CTRL_REG, |
| 77 | APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS, | 74 | APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS, |
| 78 | ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS); | 75 | ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS); |
| 79 | |||
| 80 | |||
| 81 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | ||
| 82 | } | 76 | } |
| 83 | 77 | ||
| 84 | static struct iwl_sensitivity_ranges iwl5000_sensitivity = { | 78 | static const struct iwl_sensitivity_ranges iwl5000_sensitivity = { |
| 85 | .min_nrg_cck = 100, | 79 | .min_nrg_cck = 100, |
| 86 | .max_nrg_cck = 0, /* not used, set to 0 */ | ||
| 87 | .auto_corr_min_ofdm = 90, | 80 | .auto_corr_min_ofdm = 90, |
| 88 | .auto_corr_min_ofdm_mrc = 170, | 81 | .auto_corr_min_ofdm_mrc = 170, |
| 89 | .auto_corr_min_ofdm_x1 = 105, | 82 | .auto_corr_min_ofdm_x1 = 105, |
| @@ -108,7 +101,6 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = { | |||
| 108 | 101 | ||
| 109 | static struct iwl_sensitivity_ranges iwl5150_sensitivity = { | 102 | static struct iwl_sensitivity_ranges iwl5150_sensitivity = { |
| 110 | .min_nrg_cck = 95, | 103 | .min_nrg_cck = 95, |
| 111 | .max_nrg_cck = 0, /* not used, set to 0 */ | ||
| 112 | .auto_corr_min_ofdm = 90, | 104 | .auto_corr_min_ofdm = 90, |
| 113 | .auto_corr_min_ofdm_mrc = 170, | 105 | .auto_corr_min_ofdm_mrc = 170, |
| 114 | .auto_corr_min_ofdm_x1 = 105, | 106 | .auto_corr_min_ofdm_x1 = 105, |
| @@ -164,20 +156,13 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv) | |||
| 164 | 156 | ||
| 165 | static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) | 157 | static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) |
| 166 | { | 158 | { |
| 167 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && | ||
| 168 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) | ||
| 169 | cfg(priv)->base_params->num_of_queues = | ||
| 170 | iwlagn_mod_params.num_of_queues; | ||
| 171 | |||
| 172 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; | ||
| 173 | |||
| 174 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | 159 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | |
| 175 | BIT(IEEE80211_BAND_5GHZ); | 160 | BIT(IEEE80211_BAND_5GHZ); |
| 176 | 161 | ||
| 177 | hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); | 162 | hw_params(priv).tx_chains_num = |
| 178 | hw_params(priv).rx_chains_num = num_of_ant(cfg(priv)->valid_rx_ant); | 163 | num_of_ant(hw_params(priv).valid_tx_ant); |
| 179 | hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; | 164 | hw_params(priv).rx_chains_num = |
| 180 | hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; | 165 | num_of_ant(hw_params(priv).valid_rx_ant); |
| 181 | 166 | ||
| 182 | iwl5000_set_ct_threshold(priv); | 167 | iwl5000_set_ct_threshold(priv); |
| 183 | 168 | ||
| @@ -187,20 +172,13 @@ static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) | |||
| 187 | 172 | ||
| 188 | static void iwl5150_hw_set_hw_params(struct iwl_priv *priv) | 173 | static void iwl5150_hw_set_hw_params(struct iwl_priv *priv) |
| 189 | { | 174 | { |
| 190 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && | ||
| 191 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) | ||
| 192 | cfg(priv)->base_params->num_of_queues = | ||
| 193 | iwlagn_mod_params.num_of_queues; | ||
| 194 | |||
| 195 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; | ||
| 196 | |||
| 197 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | 175 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | |
| 198 | BIT(IEEE80211_BAND_5GHZ); | 176 | BIT(IEEE80211_BAND_5GHZ); |
| 199 | 177 | ||
| 200 | hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); | 178 | hw_params(priv).tx_chains_num = |
| 201 | hw_params(priv).rx_chains_num = num_of_ant(cfg(priv)->valid_rx_ant); | 179 | num_of_ant(hw_params(priv).valid_tx_ant); |
| 202 | hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; | 180 | hw_params(priv).rx_chains_num = |
| 203 | hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; | 181 | num_of_ant(hw_params(priv).valid_rx_ant); |
| 204 | 182 | ||
| 205 | iwl5150_set_ct_threshold(priv); | 183 | iwl5150_set_ct_threshold(priv); |
| 206 | 184 | ||
| @@ -288,7 +266,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, | |||
| 288 | return -EFAULT; | 266 | return -EFAULT; |
| 289 | } | 267 | } |
| 290 | 268 | ||
| 291 | return iwl_trans_send_cmd(trans(priv), &hcmd); | 269 | return iwl_dvm_send_cmd(priv, &hcmd); |
| 292 | } | 270 | } |
| 293 | 271 | ||
| 294 | static struct iwl_lib_ops iwl5000_lib = { | 272 | static struct iwl_lib_ops iwl5000_lib = { |
| @@ -327,7 +305,7 @@ static struct iwl_lib_ops iwl5150_lib = { | |||
| 327 | .temperature = iwl5150_temperature, | 305 | .temperature = iwl5150_temperature, |
| 328 | }; | 306 | }; |
| 329 | 307 | ||
| 330 | static struct iwl_base_params iwl5000_base_params = { | 308 | static const struct iwl_base_params iwl5000_base_params = { |
| 331 | .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, | 309 | .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, |
| 332 | .num_of_queues = IWLAGN_NUM_QUEUES, | 310 | .num_of_queues = IWLAGN_NUM_QUEUES, |
| 333 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | 311 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, |
| @@ -340,7 +318,8 @@ static struct iwl_base_params iwl5000_base_params = { | |||
| 340 | .no_idle_support = true, | 318 | .no_idle_support = true, |
| 341 | .wd_disable = true, | 319 | .wd_disable = true, |
| 342 | }; | 320 | }; |
| 343 | static struct iwl_ht_params iwl5000_ht_params = { | 321 | |
| 322 | static const struct iwl_ht_params iwl5000_ht_params = { | ||
| 344 | .ht_greenfield_support = true, | 323 | .ht_greenfield_support = true, |
| 345 | }; | 324 | }; |
| 346 | 325 | ||
| @@ -356,7 +335,7 @@ static struct iwl_ht_params iwl5000_ht_params = { | |||
| 356 | .base_params = &iwl5000_base_params, \ | 335 | .base_params = &iwl5000_base_params, \ |
| 357 | .led_mode = IWL_LED_BLINK | 336 | .led_mode = IWL_LED_BLINK |
| 358 | 337 | ||
| 359 | struct iwl_cfg iwl5300_agn_cfg = { | 338 | const struct iwl_cfg iwl5300_agn_cfg = { |
| 360 | .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", | 339 | .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", |
| 361 | IWL_DEVICE_5000, | 340 | IWL_DEVICE_5000, |
| 362 | /* at least EEPROM 0x11A has wrong info */ | 341 | /* at least EEPROM 0x11A has wrong info */ |
| @@ -365,7 +344,7 @@ struct iwl_cfg iwl5300_agn_cfg = { | |||
| 365 | .ht_params = &iwl5000_ht_params, | 344 | .ht_params = &iwl5000_ht_params, |
| 366 | }; | 345 | }; |
| 367 | 346 | ||
| 368 | struct iwl_cfg iwl5100_bgn_cfg = { | 347 | const struct iwl_cfg iwl5100_bgn_cfg = { |
| 369 | .name = "Intel(R) WiFi Link 5100 BGN", | 348 | .name = "Intel(R) WiFi Link 5100 BGN", |
| 370 | IWL_DEVICE_5000, | 349 | IWL_DEVICE_5000, |
| 371 | .valid_tx_ant = ANT_B, /* .cfg overwrite */ | 350 | .valid_tx_ant = ANT_B, /* .cfg overwrite */ |
| @@ -373,14 +352,14 @@ struct iwl_cfg iwl5100_bgn_cfg = { | |||
| 373 | .ht_params = &iwl5000_ht_params, | 352 | .ht_params = &iwl5000_ht_params, |
| 374 | }; | 353 | }; |
| 375 | 354 | ||
| 376 | struct iwl_cfg iwl5100_abg_cfg = { | 355 | const struct iwl_cfg iwl5100_abg_cfg = { |
| 377 | .name = "Intel(R) WiFi Link 5100 ABG", | 356 | .name = "Intel(R) WiFi Link 5100 ABG", |
| 378 | IWL_DEVICE_5000, | 357 | IWL_DEVICE_5000, |
| 379 | .valid_tx_ant = ANT_B, /* .cfg overwrite */ | 358 | .valid_tx_ant = ANT_B, /* .cfg overwrite */ |
| 380 | .valid_rx_ant = ANT_AB, /* .cfg overwrite */ | 359 | .valid_rx_ant = ANT_AB, /* .cfg overwrite */ |
| 381 | }; | 360 | }; |
| 382 | 361 | ||
| 383 | struct iwl_cfg iwl5100_agn_cfg = { | 362 | const struct iwl_cfg iwl5100_agn_cfg = { |
| 384 | .name = "Intel(R) WiFi Link 5100 AGN", | 363 | .name = "Intel(R) WiFi Link 5100 AGN", |
| 385 | IWL_DEVICE_5000, | 364 | IWL_DEVICE_5000, |
| 386 | .valid_tx_ant = ANT_B, /* .cfg overwrite */ | 365 | .valid_tx_ant = ANT_B, /* .cfg overwrite */ |
| @@ -388,7 +367,7 @@ struct iwl_cfg iwl5100_agn_cfg = { | |||
| 388 | .ht_params = &iwl5000_ht_params, | 367 | .ht_params = &iwl5000_ht_params, |
| 389 | }; | 368 | }; |
| 390 | 369 | ||
| 391 | struct iwl_cfg iwl5350_agn_cfg = { | 370 | const struct iwl_cfg iwl5350_agn_cfg = { |
| 392 | .name = "Intel(R) WiMAX/WiFi Link 5350 AGN", | 371 | .name = "Intel(R) WiMAX/WiFi Link 5350 AGN", |
| 393 | .fw_name_pre = IWL5000_FW_PRE, | 372 | .fw_name_pre = IWL5000_FW_PRE, |
| 394 | .ucode_api_max = IWL5000_UCODE_API_MAX, | 373 | .ucode_api_max = IWL5000_UCODE_API_MAX, |
| @@ -418,14 +397,14 @@ struct iwl_cfg iwl5350_agn_cfg = { | |||
| 418 | .led_mode = IWL_LED_BLINK, \ | 397 | .led_mode = IWL_LED_BLINK, \ |
| 419 | .internal_wimax_coex = true | 398 | .internal_wimax_coex = true |
| 420 | 399 | ||
| 421 | struct iwl_cfg iwl5150_agn_cfg = { | 400 | const struct iwl_cfg iwl5150_agn_cfg = { |
| 422 | .name = "Intel(R) WiMAX/WiFi Link 5150 AGN", | 401 | .name = "Intel(R) WiMAX/WiFi Link 5150 AGN", |
| 423 | IWL_DEVICE_5150, | 402 | IWL_DEVICE_5150, |
| 424 | .ht_params = &iwl5000_ht_params, | 403 | .ht_params = &iwl5000_ht_params, |
| 425 | 404 | ||
| 426 | }; | 405 | }; |
| 427 | 406 | ||
| 428 | struct iwl_cfg iwl5150_abg_cfg = { | 407 | const struct iwl_cfg iwl5150_abg_cfg = { |
| 429 | .name = "Intel(R) WiMAX/WiFi Link 5150 ABG", | 408 | .name = "Intel(R) WiMAX/WiFi Link 5150 ABG", |
| 430 | IWL_DEVICE_5150, | 409 | IWL_DEVICE_5150, |
| 431 | }; | 410 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 223e60a1b79d..64060cd738b5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
| @@ -96,25 +96,25 @@ static void iwl6150_additional_nic_config(struct iwl_priv *priv) | |||
| 96 | CSR_GP_DRIVER_REG_BIT_6050_1x2); | 96 | CSR_GP_DRIVER_REG_BIT_6050_1x2); |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | static void iwl6000i_additional_nic_config(struct iwl_priv *priv) | ||
| 100 | { | ||
| 101 | /* 2x2 IPA phy type */ | ||
| 102 | iwl_write32(trans(priv), CSR_GP_DRIVER_REG, | ||
| 103 | CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); | ||
| 104 | } | ||
| 105 | |||
| 99 | /* NIC configuration for 6000 series */ | 106 | /* NIC configuration for 6000 series */ |
| 100 | static void iwl6000_nic_config(struct iwl_priv *priv) | 107 | static void iwl6000_nic_config(struct iwl_priv *priv) |
| 101 | { | 108 | { |
| 102 | iwl_rf_config(priv); | 109 | iwl_rf_config(priv); |
| 103 | 110 | ||
| 104 | /* no locking required for register write */ | ||
| 105 | if (cfg(priv)->pa_type == IWL_PA_INTERNAL) { | ||
| 106 | /* 2x2 IPA phy type */ | ||
| 107 | iwl_write32(trans(priv), CSR_GP_DRIVER_REG, | ||
| 108 | CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); | ||
| 109 | } | ||
| 110 | /* do additional nic configuration if needed */ | 111 | /* do additional nic configuration if needed */ |
| 111 | if (cfg(priv)->additional_nic_config) | 112 | if (cfg(priv)->additional_nic_config) |
| 112 | cfg(priv)->additional_nic_config(priv); | 113 | cfg(priv)->additional_nic_config(priv); |
| 113 | } | 114 | } |
| 114 | 115 | ||
| 115 | static struct iwl_sensitivity_ranges iwl6000_sensitivity = { | 116 | static const struct iwl_sensitivity_ranges iwl6000_sensitivity = { |
| 116 | .min_nrg_cck = 110, | 117 | .min_nrg_cck = 110, |
| 117 | .max_nrg_cck = 0, /* not used, set to 0 */ | ||
| 118 | .auto_corr_min_ofdm = 80, | 118 | .auto_corr_min_ofdm = 80, |
| 119 | .auto_corr_min_ofdm_mrc = 128, | 119 | .auto_corr_min_ofdm_mrc = 128, |
| 120 | .auto_corr_min_ofdm_x1 = 105, | 120 | .auto_corr_min_ofdm_x1 = 105, |
| @@ -139,24 +139,16 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = { | |||
| 139 | 139 | ||
| 140 | static void iwl6000_hw_set_hw_params(struct iwl_priv *priv) | 140 | static void iwl6000_hw_set_hw_params(struct iwl_priv *priv) |
| 141 | { | 141 | { |
| 142 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && | ||
| 143 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) | ||
| 144 | cfg(priv)->base_params->num_of_queues = | ||
| 145 | iwlagn_mod_params.num_of_queues; | ||
| 146 | |||
| 147 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; | ||
| 148 | |||
| 149 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | 142 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | |
| 150 | BIT(IEEE80211_BAND_5GHZ); | 143 | BIT(IEEE80211_BAND_5GHZ); |
| 151 | 144 | ||
| 152 | hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); | 145 | hw_params(priv).tx_chains_num = |
| 146 | num_of_ant(hw_params(priv).valid_tx_ant); | ||
| 153 | if (cfg(priv)->rx_with_siso_diversity) | 147 | if (cfg(priv)->rx_with_siso_diversity) |
| 154 | hw_params(priv).rx_chains_num = 1; | 148 | hw_params(priv).rx_chains_num = 1; |
| 155 | else | 149 | else |
| 156 | hw_params(priv).rx_chains_num = | 150 | hw_params(priv).rx_chains_num = |
| 157 | num_of_ant(cfg(priv)->valid_rx_ant); | 151 | num_of_ant(hw_params(priv).valid_rx_ant); |
| 158 | hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; | ||
| 159 | hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; | ||
| 160 | 152 | ||
| 161 | iwl6000_set_ct_threshold(priv); | 153 | iwl6000_set_ct_threshold(priv); |
| 162 | 154 | ||
| @@ -233,7 +225,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, | |||
| 233 | return -EFAULT; | 225 | return -EFAULT; |
| 234 | } | 226 | } |
| 235 | 227 | ||
| 236 | return iwl_trans_send_cmd(trans(priv), &hcmd); | 228 | return iwl_dvm_send_cmd(priv, &hcmd); |
| 237 | } | 229 | } |
| 238 | 230 | ||
| 239 | static struct iwl_lib_ops iwl6000_lib = { | 231 | static struct iwl_lib_ops iwl6000_lib = { |
| @@ -250,16 +242,13 @@ static struct iwl_lib_ops iwl6000_lib = { | |||
| 250 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | 242 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, |
| 251 | EEPROM_REG_BAND_52_HT40_CHANNELS | 243 | EEPROM_REG_BAND_52_HT40_CHANNELS |
| 252 | }, | 244 | }, |
| 253 | .update_enhanced_txpower = iwl_eeprom_enhanced_txpower, | 245 | .enhanced_txpower = true, |
| 254 | }, | 246 | }, |
| 255 | .temperature = iwlagn_temperature, | 247 | .temperature = iwlagn_temperature, |
| 256 | }; | 248 | }; |
| 257 | 249 | ||
| 258 | static struct iwl_lib_ops iwl6030_lib = { | 250 | static struct iwl_lib_ops iwl6030_lib = { |
| 259 | .set_hw_params = iwl6000_hw_set_hw_params, | 251 | .set_hw_params = iwl6000_hw_set_hw_params, |
| 260 | .bt_rx_handler_setup = iwlagn_bt_rx_handler_setup, | ||
| 261 | .bt_setup_deferred_work = iwlagn_bt_setup_deferred_work, | ||
| 262 | .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, | ||
| 263 | .set_channel_switch = iwl6000_hw_channel_switch, | 252 | .set_channel_switch = iwl6000_hw_channel_switch, |
| 264 | .nic_config = iwl6000_nic_config, | 253 | .nic_config = iwl6000_nic_config, |
| 265 | .eeprom_ops = { | 254 | .eeprom_ops = { |
| @@ -272,12 +261,12 @@ static struct iwl_lib_ops iwl6030_lib = { | |||
| 272 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | 261 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, |
| 273 | EEPROM_REG_BAND_52_HT40_CHANNELS | 262 | EEPROM_REG_BAND_52_HT40_CHANNELS |
| 274 | }, | 263 | }, |
| 275 | .update_enhanced_txpower = iwl_eeprom_enhanced_txpower, | 264 | .enhanced_txpower = true, |
| 276 | }, | 265 | }, |
| 277 | .temperature = iwlagn_temperature, | 266 | .temperature = iwlagn_temperature, |
| 278 | }; | 267 | }; |
| 279 | 268 | ||
| 280 | static struct iwl_base_params iwl6000_base_params = { | 269 | static const struct iwl_base_params iwl6000_base_params = { |
| 281 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 270 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
| 282 | .num_of_queues = IWLAGN_NUM_QUEUES, | 271 | .num_of_queues = IWLAGN_NUM_QUEUES, |
| 283 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | 272 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, |
| @@ -294,7 +283,7 @@ static struct iwl_base_params iwl6000_base_params = { | |||
| 294 | .shadow_reg_enable = true, | 283 | .shadow_reg_enable = true, |
| 295 | }; | 284 | }; |
| 296 | 285 | ||
| 297 | static struct iwl_base_params iwl6050_base_params = { | 286 | static const struct iwl_base_params iwl6050_base_params = { |
| 298 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 287 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
| 299 | .num_of_queues = IWLAGN_NUM_QUEUES, | 288 | .num_of_queues = IWLAGN_NUM_QUEUES, |
| 300 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | 289 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, |
| @@ -310,7 +299,8 @@ static struct iwl_base_params iwl6050_base_params = { | |||
| 310 | .max_event_log_size = 1024, | 299 | .max_event_log_size = 1024, |
| 311 | .shadow_reg_enable = true, | 300 | .shadow_reg_enable = true, |
| 312 | }; | 301 | }; |
| 313 | static struct iwl_base_params iwl6000_g2_base_params = { | 302 | |
| 303 | static const struct iwl_base_params iwl6000_g2_base_params = { | ||
| 314 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 304 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
| 315 | .num_of_queues = IWLAGN_NUM_QUEUES, | 305 | .num_of_queues = IWLAGN_NUM_QUEUES, |
| 316 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | 306 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, |
| @@ -327,12 +317,12 @@ static struct iwl_base_params iwl6000_g2_base_params = { | |||
| 327 | .shadow_reg_enable = true, | 317 | .shadow_reg_enable = true, |
| 328 | }; | 318 | }; |
| 329 | 319 | ||
| 330 | static struct iwl_ht_params iwl6000_ht_params = { | 320 | static const struct iwl_ht_params iwl6000_ht_params = { |
| 331 | .ht_greenfield_support = true, | 321 | .ht_greenfield_support = true, |
| 332 | .use_rts_for_aggregation = true, /* use rts/cts protection */ | 322 | .use_rts_for_aggregation = true, /* use rts/cts protection */ |
| 333 | }; | 323 | }; |
| 334 | 324 | ||
| 335 | static struct iwl_bt_params iwl6000_bt_params = { | 325 | static const struct iwl_bt_params iwl6000_bt_params = { |
| 336 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ | 326 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ |
| 337 | .advanced_bt_coexist = true, | 327 | .advanced_bt_coexist = true, |
| 338 | .agg_time_limit = BT_AGG_THRESHOLD_DEF, | 328 | .agg_time_limit = BT_AGG_THRESHOLD_DEF, |
| @@ -355,40 +345,41 @@ static struct iwl_bt_params iwl6000_bt_params = { | |||
| 355 | .need_temp_offset_calib = true, \ | 345 | .need_temp_offset_calib = true, \ |
| 356 | .led_mode = IWL_LED_RF_STATE | 346 | .led_mode = IWL_LED_RF_STATE |
| 357 | 347 | ||
| 358 | struct iwl_cfg iwl6005_2agn_cfg = { | 348 | const struct iwl_cfg iwl6005_2agn_cfg = { |
| 359 | .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN", | 349 | .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN", |
| 360 | IWL_DEVICE_6005, | 350 | IWL_DEVICE_6005, |
| 361 | .ht_params = &iwl6000_ht_params, | 351 | .ht_params = &iwl6000_ht_params, |
| 362 | }; | 352 | }; |
| 363 | 353 | ||
| 364 | struct iwl_cfg iwl6005_2abg_cfg = { | 354 | const struct iwl_cfg iwl6005_2abg_cfg = { |
| 365 | .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG", | 355 | .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG", |
| 366 | IWL_DEVICE_6005, | 356 | IWL_DEVICE_6005, |
| 367 | }; | 357 | }; |
| 368 | 358 | ||
| 369 | struct iwl_cfg iwl6005_2bg_cfg = { | 359 | const struct iwl_cfg iwl6005_2bg_cfg = { |
| 370 | .name = "Intel(R) Centrino(R) Advanced-N 6205 BG", | 360 | .name = "Intel(R) Centrino(R) Advanced-N 6205 BG", |
| 371 | IWL_DEVICE_6005, | 361 | IWL_DEVICE_6005, |
| 372 | }; | 362 | }; |
| 373 | 363 | ||
| 374 | struct iwl_cfg iwl6005_2agn_sff_cfg = { | 364 | const struct iwl_cfg iwl6005_2agn_sff_cfg = { |
| 375 | .name = "Intel(R) Centrino(R) Advanced-N 6205S AGN", | 365 | .name = "Intel(R) Centrino(R) Advanced-N 6205S AGN", |
| 376 | IWL_DEVICE_6005, | 366 | IWL_DEVICE_6005, |
| 377 | .ht_params = &iwl6000_ht_params, | 367 | .ht_params = &iwl6000_ht_params, |
| 378 | }; | 368 | }; |
| 379 | 369 | ||
| 380 | struct iwl_cfg iwl6005_2agn_d_cfg = { | 370 | const struct iwl_cfg iwl6005_2agn_d_cfg = { |
| 381 | .name = "Intel(R) Centrino(R) Advanced-N 6205D AGN", | 371 | .name = "Intel(R) Centrino(R) Advanced-N 6205D AGN", |
| 382 | IWL_DEVICE_6005, | 372 | IWL_DEVICE_6005, |
| 383 | .ht_params = &iwl6000_ht_params, | 373 | .ht_params = &iwl6000_ht_params, |
| 384 | }; | 374 | }; |
| 385 | 375 | ||
| 386 | struct iwl_cfg iwl6005_2agn_mow1_cfg = { | 376 | const struct iwl_cfg iwl6005_2agn_mow1_cfg = { |
| 387 | .name = "Intel(R) Centrino(R) Advanced-N 6206 AGN", | 377 | .name = "Intel(R) Centrino(R) Advanced-N 6206 AGN", |
| 388 | IWL_DEVICE_6005, | 378 | IWL_DEVICE_6005, |
| 389 | .ht_params = &iwl6000_ht_params, | 379 | .ht_params = &iwl6000_ht_params, |
| 390 | }; | 380 | }; |
| 391 | struct iwl_cfg iwl6005_2agn_mow2_cfg = { | 381 | |
| 382 | const struct iwl_cfg iwl6005_2agn_mow2_cfg = { | ||
| 392 | .name = "Intel(R) Centrino(R) Advanced-N 6207 AGN", | 383 | .name = "Intel(R) Centrino(R) Advanced-N 6207 AGN", |
| 393 | IWL_DEVICE_6005, | 384 | IWL_DEVICE_6005, |
| 394 | .ht_params = &iwl6000_ht_params, | 385 | .ht_params = &iwl6000_ht_params, |
| @@ -410,53 +401,53 @@ struct iwl_cfg iwl6005_2agn_mow2_cfg = { | |||
| 410 | .led_mode = IWL_LED_RF_STATE, \ | 401 | .led_mode = IWL_LED_RF_STATE, \ |
| 411 | .adv_pm = true \ | 402 | .adv_pm = true \ |
| 412 | 403 | ||
| 413 | struct iwl_cfg iwl6030_2agn_cfg = { | 404 | const struct iwl_cfg iwl6030_2agn_cfg = { |
| 414 | .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", | 405 | .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", |
| 415 | IWL_DEVICE_6030, | 406 | IWL_DEVICE_6030, |
| 416 | .ht_params = &iwl6000_ht_params, | 407 | .ht_params = &iwl6000_ht_params, |
| 417 | }; | 408 | }; |
| 418 | 409 | ||
| 419 | struct iwl_cfg iwl6030_2abg_cfg = { | 410 | const struct iwl_cfg iwl6030_2abg_cfg = { |
| 420 | .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG", | 411 | .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG", |
| 421 | IWL_DEVICE_6030, | 412 | IWL_DEVICE_6030, |
| 422 | }; | 413 | }; |
| 423 | 414 | ||
| 424 | struct iwl_cfg iwl6030_2bgn_cfg = { | 415 | const struct iwl_cfg iwl6030_2bgn_cfg = { |
| 425 | .name = "Intel(R) Centrino(R) Advanced-N 6230 BGN", | 416 | .name = "Intel(R) Centrino(R) Advanced-N 6230 BGN", |
| 426 | IWL_DEVICE_6030, | 417 | IWL_DEVICE_6030, |
| 427 | .ht_params = &iwl6000_ht_params, | 418 | .ht_params = &iwl6000_ht_params, |
| 428 | }; | 419 | }; |
| 429 | 420 | ||
| 430 | struct iwl_cfg iwl6030_2bg_cfg = { | 421 | const struct iwl_cfg iwl6030_2bg_cfg = { |
| 431 | .name = "Intel(R) Centrino(R) Advanced-N 6230 BG", | 422 | .name = "Intel(R) Centrino(R) Advanced-N 6230 BG", |
| 432 | IWL_DEVICE_6030, | 423 | IWL_DEVICE_6030, |
| 433 | }; | 424 | }; |
| 434 | 425 | ||
| 435 | struct iwl_cfg iwl6035_2agn_cfg = { | 426 | const struct iwl_cfg iwl6035_2agn_cfg = { |
| 436 | .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN", | 427 | .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN", |
| 437 | IWL_DEVICE_6030, | 428 | IWL_DEVICE_6030, |
| 438 | .ht_params = &iwl6000_ht_params, | 429 | .ht_params = &iwl6000_ht_params, |
| 439 | }; | 430 | }; |
| 440 | 431 | ||
| 441 | struct iwl_cfg iwl1030_bgn_cfg = { | 432 | const struct iwl_cfg iwl1030_bgn_cfg = { |
| 442 | .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", | 433 | .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", |
| 443 | IWL_DEVICE_6030, | 434 | IWL_DEVICE_6030, |
| 444 | .ht_params = &iwl6000_ht_params, | 435 | .ht_params = &iwl6000_ht_params, |
| 445 | }; | 436 | }; |
| 446 | 437 | ||
| 447 | struct iwl_cfg iwl1030_bg_cfg = { | 438 | const struct iwl_cfg iwl1030_bg_cfg = { |
| 448 | .name = "Intel(R) Centrino(R) Wireless-N 1030 BG", | 439 | .name = "Intel(R) Centrino(R) Wireless-N 1030 BG", |
| 449 | IWL_DEVICE_6030, | 440 | IWL_DEVICE_6030, |
| 450 | }; | 441 | }; |
| 451 | 442 | ||
| 452 | struct iwl_cfg iwl130_bgn_cfg = { | 443 | const struct iwl_cfg iwl130_bgn_cfg = { |
| 453 | .name = "Intel(R) Centrino(R) Wireless-N 130 BGN", | 444 | .name = "Intel(R) Centrino(R) Wireless-N 130 BGN", |
| 454 | IWL_DEVICE_6030, | 445 | IWL_DEVICE_6030, |
| 455 | .ht_params = &iwl6000_ht_params, | 446 | .ht_params = &iwl6000_ht_params, |
| 456 | .rx_with_siso_diversity = true, | 447 | .rx_with_siso_diversity = true, |
| 457 | }; | 448 | }; |
| 458 | 449 | ||
| 459 | struct iwl_cfg iwl130_bg_cfg = { | 450 | const struct iwl_cfg iwl130_bg_cfg = { |
| 460 | .name = "Intel(R) Centrino(R) Wireless-N 130 BG", | 451 | .name = "Intel(R) Centrino(R) Wireless-N 130 BG", |
| 461 | IWL_DEVICE_6030, | 452 | IWL_DEVICE_6030, |
| 462 | .rx_with_siso_diversity = true, | 453 | .rx_with_siso_diversity = true, |
| @@ -477,22 +468,22 @@ struct iwl_cfg iwl130_bg_cfg = { | |||
| 477 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \ | 468 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \ |
| 478 | .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ | 469 | .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ |
| 479 | .lib = &iwl6000_lib, \ | 470 | .lib = &iwl6000_lib, \ |
| 471 | .additional_nic_config = iwl6000i_additional_nic_config,\ | ||
| 480 | .base_params = &iwl6000_base_params, \ | 472 | .base_params = &iwl6000_base_params, \ |
| 481 | .pa_type = IWL_PA_INTERNAL, \ | ||
| 482 | .led_mode = IWL_LED_BLINK | 473 | .led_mode = IWL_LED_BLINK |
| 483 | 474 | ||
| 484 | struct iwl_cfg iwl6000i_2agn_cfg = { | 475 | const struct iwl_cfg iwl6000i_2agn_cfg = { |
| 485 | .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN", | 476 | .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN", |
| 486 | IWL_DEVICE_6000i, | 477 | IWL_DEVICE_6000i, |
| 487 | .ht_params = &iwl6000_ht_params, | 478 | .ht_params = &iwl6000_ht_params, |
| 488 | }; | 479 | }; |
| 489 | 480 | ||
| 490 | struct iwl_cfg iwl6000i_2abg_cfg = { | 481 | const struct iwl_cfg iwl6000i_2abg_cfg = { |
| 491 | .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG", | 482 | .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG", |
| 492 | IWL_DEVICE_6000i, | 483 | IWL_DEVICE_6000i, |
| 493 | }; | 484 | }; |
| 494 | 485 | ||
| 495 | struct iwl_cfg iwl6000i_2bg_cfg = { | 486 | const struct iwl_cfg iwl6000i_2bg_cfg = { |
| 496 | .name = "Intel(R) Centrino(R) Advanced-N 6200 BG", | 487 | .name = "Intel(R) Centrino(R) Advanced-N 6200 BG", |
| 497 | IWL_DEVICE_6000i, | 488 | IWL_DEVICE_6000i, |
| 498 | }; | 489 | }; |
| @@ -513,13 +504,13 @@ struct iwl_cfg iwl6000i_2bg_cfg = { | |||
| 513 | .led_mode = IWL_LED_BLINK, \ | 504 | .led_mode = IWL_LED_BLINK, \ |
| 514 | .internal_wimax_coex = true | 505 | .internal_wimax_coex = true |
| 515 | 506 | ||
| 516 | struct iwl_cfg iwl6050_2agn_cfg = { | 507 | const struct iwl_cfg iwl6050_2agn_cfg = { |
| 517 | .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN", | 508 | .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN", |
| 518 | IWL_DEVICE_6050, | 509 | IWL_DEVICE_6050, |
| 519 | .ht_params = &iwl6000_ht_params, | 510 | .ht_params = &iwl6000_ht_params, |
| 520 | }; | 511 | }; |
| 521 | 512 | ||
| 522 | struct iwl_cfg iwl6050_2abg_cfg = { | 513 | const struct iwl_cfg iwl6050_2abg_cfg = { |
| 523 | .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG", | 514 | .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG", |
| 524 | IWL_DEVICE_6050, | 515 | IWL_DEVICE_6050, |
| 525 | }; | 516 | }; |
| @@ -538,18 +529,18 @@ struct iwl_cfg iwl6050_2abg_cfg = { | |||
| 538 | .led_mode = IWL_LED_BLINK, \ | 529 | .led_mode = IWL_LED_BLINK, \ |
| 539 | .internal_wimax_coex = true | 530 | .internal_wimax_coex = true |
| 540 | 531 | ||
| 541 | struct iwl_cfg iwl6150_bgn_cfg = { | 532 | const struct iwl_cfg iwl6150_bgn_cfg = { |
| 542 | .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN", | 533 | .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN", |
| 543 | IWL_DEVICE_6150, | 534 | IWL_DEVICE_6150, |
| 544 | .ht_params = &iwl6000_ht_params, | 535 | .ht_params = &iwl6000_ht_params, |
| 545 | }; | 536 | }; |
| 546 | 537 | ||
| 547 | struct iwl_cfg iwl6150_bg_cfg = { | 538 | const struct iwl_cfg iwl6150_bg_cfg = { |
| 548 | .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG", | 539 | .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG", |
| 549 | IWL_DEVICE_6150, | 540 | IWL_DEVICE_6150, |
| 550 | }; | 541 | }; |
| 551 | 542 | ||
| 552 | struct iwl_cfg iwl6000_3agn_cfg = { | 543 | const struct iwl_cfg iwl6000_3agn_cfg = { |
| 553 | .name = "Intel(R) Centrino(R) Ultimate-N 6300 AGN", | 544 | .name = "Intel(R) Centrino(R) Ultimate-N 6300 AGN", |
| 554 | .fw_name_pre = IWL6000_FW_PRE, | 545 | .fw_name_pre = IWL6000_FW_PRE, |
| 555 | .ucode_api_max = IWL6000_UCODE_API_MAX, | 546 | .ucode_api_max = IWL6000_UCODE_API_MAX, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 988ee454a944..84cbe7bb504c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c | |||
| @@ -68,13 +68,19 @@ | |||
| 68 | #include "iwl-agn-calib.h" | 68 | #include "iwl-agn-calib.h" |
| 69 | #include "iwl-trans.h" | 69 | #include "iwl-trans.h" |
| 70 | #include "iwl-agn.h" | 70 | #include "iwl-agn.h" |
| 71 | #include "iwl-wifi.h" | ||
| 72 | #include "iwl-ucode.h" | ||
| 73 | 71 | ||
| 74 | /***************************************************************************** | 72 | /***************************************************************************** |
| 75 | * INIT calibrations framework | 73 | * INIT calibrations framework |
| 76 | *****************************************************************************/ | 74 | *****************************************************************************/ |
| 77 | 75 | ||
| 76 | /* Opaque calibration results */ | ||
| 77 | struct iwl_calib_result { | ||
| 78 | struct list_head list; | ||
| 79 | size_t cmd_len; | ||
| 80 | struct iwl_calib_hdr hdr; | ||
| 81 | /* data follows */ | ||
| 82 | }; | ||
| 83 | |||
| 78 | struct statistics_general_data { | 84 | struct statistics_general_data { |
| 79 | u32 beacon_silence_rssi_a; | 85 | u32 beacon_silence_rssi_a; |
| 80 | u32 beacon_silence_rssi_b; | 86 | u32 beacon_silence_rssi_b; |
| @@ -84,7 +90,7 @@ struct statistics_general_data { | |||
| 84 | u32 beacon_energy_c; | 90 | u32 beacon_energy_c; |
| 85 | }; | 91 | }; |
| 86 | 92 | ||
| 87 | int iwl_send_calib_results(struct iwl_trans *trans) | 93 | int iwl_send_calib_results(struct iwl_priv *priv) |
| 88 | { | 94 | { |
| 89 | struct iwl_host_cmd hcmd = { | 95 | struct iwl_host_cmd hcmd = { |
| 90 | .id = REPLY_PHY_CALIBRATION_CMD, | 96 | .id = REPLY_PHY_CALIBRATION_CMD, |
| @@ -92,15 +98,15 @@ int iwl_send_calib_results(struct iwl_trans *trans) | |||
| 92 | }; | 98 | }; |
| 93 | struct iwl_calib_result *res; | 99 | struct iwl_calib_result *res; |
| 94 | 100 | ||
| 95 | list_for_each_entry(res, &trans->calib_results, list) { | 101 | list_for_each_entry(res, &priv->calib_results, list) { |
| 96 | int ret; | 102 | int ret; |
| 97 | 103 | ||
| 98 | hcmd.len[0] = res->cmd_len; | 104 | hcmd.len[0] = res->cmd_len; |
| 99 | hcmd.data[0] = &res->hdr; | 105 | hcmd.data[0] = &res->hdr; |
| 100 | hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; | 106 | hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; |
| 101 | ret = iwl_trans_send_cmd(trans, &hcmd); | 107 | ret = iwl_dvm_send_cmd(priv, &hcmd); |
| 102 | if (ret) { | 108 | if (ret) { |
| 103 | IWL_ERR(trans, "Error %d on calib cmd %d\n", | 109 | IWL_ERR(priv, "Error %d on calib cmd %d\n", |
| 104 | ret, res->hdr.op_code); | 110 | ret, res->hdr.op_code); |
| 105 | return ret; | 111 | return ret; |
| 106 | } | 112 | } |
| @@ -109,7 +115,7 @@ int iwl_send_calib_results(struct iwl_trans *trans) | |||
| 109 | return 0; | 115 | return 0; |
| 110 | } | 116 | } |
| 111 | 117 | ||
| 112 | int iwl_calib_set(struct iwl_trans *trans, | 118 | int iwl_calib_set(struct iwl_priv *priv, |
| 113 | const struct iwl_calib_hdr *cmd, int len) | 119 | const struct iwl_calib_hdr *cmd, int len) |
| 114 | { | 120 | { |
| 115 | struct iwl_calib_result *res, *tmp; | 121 | struct iwl_calib_result *res, *tmp; |
| @@ -121,7 +127,7 @@ int iwl_calib_set(struct iwl_trans *trans, | |||
| 121 | memcpy(&res->hdr, cmd, len); | 127 | memcpy(&res->hdr, cmd, len); |
| 122 | res->cmd_len = len; | 128 | res->cmd_len = len; |
| 123 | 129 | ||
| 124 | list_for_each_entry(tmp, &trans->calib_results, list) { | 130 | list_for_each_entry(tmp, &priv->calib_results, list) { |
| 125 | if (tmp->hdr.op_code == res->hdr.op_code) { | 131 | if (tmp->hdr.op_code == res->hdr.op_code) { |
| 126 | list_replace(&tmp->list, &res->list); | 132 | list_replace(&tmp->list, &res->list); |
| 127 | kfree(tmp); | 133 | kfree(tmp); |
| @@ -130,16 +136,16 @@ int iwl_calib_set(struct iwl_trans *trans, | |||
| 130 | } | 136 | } |
| 131 | 137 | ||
| 132 | /* wasn't in list already */ | 138 | /* wasn't in list already */ |
| 133 | list_add_tail(&res->list, &trans->calib_results); | 139 | list_add_tail(&res->list, &priv->calib_results); |
| 134 | 140 | ||
| 135 | return 0; | 141 | return 0; |
| 136 | } | 142 | } |
| 137 | 143 | ||
| 138 | void iwl_calib_free_results(struct iwl_trans *trans) | 144 | void iwl_calib_free_results(struct iwl_priv *priv) |
| 139 | { | 145 | { |
| 140 | struct iwl_calib_result *res, *tmp; | 146 | struct iwl_calib_result *res, *tmp; |
| 141 | 147 | ||
| 142 | list_for_each_entry_safe(res, tmp, &trans->calib_results, list) { | 148 | list_for_each_entry_safe(res, tmp, &priv->calib_results, list) { |
| 143 | list_del(&res->list); | 149 | list_del(&res->list); |
| 144 | kfree(res); | 150 | kfree(res); |
| 145 | } | 151 | } |
| @@ -494,7 +500,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv) | |||
| 494 | memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]), | 500 | memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]), |
| 495 | sizeof(u16)*HD_TABLE_SIZE); | 501 | sizeof(u16)*HD_TABLE_SIZE); |
| 496 | 502 | ||
| 497 | return iwl_trans_send_cmd(trans(priv), &cmd_out); | 503 | return iwl_dvm_send_cmd(priv, &cmd_out); |
| 498 | } | 504 | } |
| 499 | 505 | ||
| 500 | /* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */ | 506 | /* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */ |
| @@ -583,7 +589,7 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv) | |||
| 583 | &(cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX]), | 589 | &(cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX]), |
| 584 | sizeof(u16)*ENHANCE_HD_TABLE_ENTRIES); | 590 | sizeof(u16)*ENHANCE_HD_TABLE_ENTRIES); |
| 585 | 591 | ||
| 586 | return iwl_trans_send_cmd(trans(priv), &cmd_out); | 592 | return iwl_dvm_send_cmd(priv, &cmd_out); |
| 587 | } | 593 | } |
| 588 | 594 | ||
| 589 | void iwl_init_sensitivity(struct iwl_priv *priv) | 595 | void iwl_init_sensitivity(struct iwl_priv *priv) |
| @@ -636,7 +642,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv) | |||
| 636 | data->last_bad_plcp_cnt_cck = 0; | 642 | data->last_bad_plcp_cnt_cck = 0; |
| 637 | data->last_fa_cnt_cck = 0; | 643 | data->last_fa_cnt_cck = 0; |
| 638 | 644 | ||
| 639 | if (nic(priv)->fw.enhance_sensitivity_table) | 645 | if (priv->fw->enhance_sensitivity_table) |
| 640 | ret |= iwl_enhance_sensitivity_write(priv); | 646 | ret |= iwl_enhance_sensitivity_write(priv); |
| 641 | else | 647 | else |
| 642 | ret |= iwl_sensitivity_write(priv); | 648 | ret |= iwl_sensitivity_write(priv); |
| @@ -655,7 +661,6 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv) | |||
| 655 | struct iwl_sensitivity_data *data = NULL; | 661 | struct iwl_sensitivity_data *data = NULL; |
| 656 | struct statistics_rx_non_phy *rx_info; | 662 | struct statistics_rx_non_phy *rx_info; |
| 657 | struct statistics_rx_phy *ofdm, *cck; | 663 | struct statistics_rx_phy *ofdm, *cck; |
| 658 | unsigned long flags; | ||
| 659 | struct statistics_general_data statis; | 664 | struct statistics_general_data statis; |
| 660 | 665 | ||
| 661 | if (priv->disable_sens_cal) | 666 | if (priv->disable_sens_cal) |
| @@ -668,13 +673,13 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv) | |||
| 668 | return; | 673 | return; |
| 669 | } | 674 | } |
| 670 | 675 | ||
| 671 | spin_lock_irqsave(&priv->shrd->lock, flags); | 676 | spin_lock_bh(&priv->statistics.lock); |
| 672 | rx_info = &priv->statistics.rx_non_phy; | 677 | rx_info = &priv->statistics.rx_non_phy; |
| 673 | ofdm = &priv->statistics.rx_ofdm; | 678 | ofdm = &priv->statistics.rx_ofdm; |
| 674 | cck = &priv->statistics.rx_cck; | 679 | cck = &priv->statistics.rx_cck; |
| 675 | if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { | 680 | if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { |
| 676 | IWL_DEBUG_CALIB(priv, "<< invalid data.\n"); | 681 | IWL_DEBUG_CALIB(priv, "<< invalid data.\n"); |
| 677 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | 682 | spin_unlock_bh(&priv->statistics.lock); |
| 678 | return; | 683 | return; |
| 679 | } | 684 | } |
| 680 | 685 | ||
| @@ -698,7 +703,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv) | |||
| 698 | statis.beacon_energy_c = | 703 | statis.beacon_energy_c = |
| 699 | le32_to_cpu(rx_info->beacon_energy_c); | 704 | le32_to_cpu(rx_info->beacon_energy_c); |
| 700 | 705 | ||
| 701 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | 706 | spin_unlock_bh(&priv->statistics.lock); |
| 702 | 707 | ||
| 703 | IWL_DEBUG_CALIB(priv, "rx_enable_time = %u usecs\n", rx_enable_time); | 708 | IWL_DEBUG_CALIB(priv, "rx_enable_time = %u usecs\n", rx_enable_time); |
| 704 | 709 | ||
| @@ -747,7 +752,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv) | |||
| 747 | 752 | ||
| 748 | iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time); | 753 | iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time); |
| 749 | iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis); | 754 | iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis); |
| 750 | if (nic(priv)->fw.enhance_sensitivity_table) | 755 | if (priv->fw->enhance_sensitivity_table) |
| 751 | iwl_enhance_sensitivity_write(priv); | 756 | iwl_enhance_sensitivity_write(priv); |
| 752 | else | 757 | else |
| 753 | iwl_sensitivity_write(priv); | 758 | iwl_sensitivity_write(priv); |
| @@ -849,7 +854,7 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, | |||
| 849 | * connect the first valid tx chain | 854 | * connect the first valid tx chain |
| 850 | */ | 855 | */ |
| 851 | first_chain = | 856 | first_chain = |
| 852 | find_first_chain(cfg(priv)->valid_tx_ant); | 857 | find_first_chain(hw_params(priv).valid_tx_ant); |
| 853 | data->disconn_array[first_chain] = 0; | 858 | data->disconn_array[first_chain] = 0; |
| 854 | active_chains |= BIT(first_chain); | 859 | active_chains |= BIT(first_chain); |
| 855 | IWL_DEBUG_CALIB(priv, | 860 | IWL_DEBUG_CALIB(priv, |
| @@ -874,10 +879,8 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, | |||
| 874 | } | 879 | } |
| 875 | 880 | ||
| 876 | static void iwlagn_gain_computation(struct iwl_priv *priv, | 881 | static void iwlagn_gain_computation(struct iwl_priv *priv, |
| 877 | u32 average_noise[NUM_RX_CHAINS], | 882 | u32 average_noise[NUM_RX_CHAINS], |
| 878 | u16 min_average_noise_antenna_i, | 883 | u8 default_chain) |
| 879 | u32 min_average_noise, | ||
| 880 | u8 default_chain) | ||
| 881 | { | 884 | { |
| 882 | int i; | 885 | int i; |
| 883 | s32 delta_g; | 886 | s32 delta_g; |
| @@ -925,7 +928,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv, | |||
| 925 | priv->phy_calib_chain_noise_gain_cmd); | 928 | priv->phy_calib_chain_noise_gain_cmd); |
| 926 | cmd.delta_gain_1 = data->delta_gain_code[1]; | 929 | cmd.delta_gain_1 = data->delta_gain_code[1]; |
| 927 | cmd.delta_gain_2 = data->delta_gain_code[2]; | 930 | cmd.delta_gain_2 = data->delta_gain_code[2]; |
| 928 | iwl_trans_send_cmd_pdu(trans(priv), REPLY_PHY_CALIBRATION_CMD, | 931 | iwl_dvm_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, |
| 929 | CMD_ASYNC, sizeof(cmd), &cmd); | 932 | CMD_ASYNC, sizeof(cmd), &cmd); |
| 930 | 933 | ||
| 931 | data->radio_write = 1; | 934 | data->radio_write = 1; |
| @@ -958,7 +961,6 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) | |||
| 958 | u16 stat_chnum = INITIALIZATION_VALUE; | 961 | u16 stat_chnum = INITIALIZATION_VALUE; |
| 959 | u8 rxon_band24; | 962 | u8 rxon_band24; |
| 960 | u8 stat_band24; | 963 | u8 stat_band24; |
| 961 | unsigned long flags; | ||
| 962 | struct statistics_rx_non_phy *rx_info; | 964 | struct statistics_rx_non_phy *rx_info; |
| 963 | 965 | ||
| 964 | /* | 966 | /* |
| @@ -983,13 +985,13 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) | |||
| 983 | return; | 985 | return; |
| 984 | } | 986 | } |
| 985 | 987 | ||
| 986 | spin_lock_irqsave(&priv->shrd->lock, flags); | 988 | spin_lock_bh(&priv->statistics.lock); |
| 987 | 989 | ||
| 988 | rx_info = &priv->statistics.rx_non_phy; | 990 | rx_info = &priv->statistics.rx_non_phy; |
| 989 | 991 | ||
| 990 | if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { | 992 | if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { |
| 991 | IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n"); | 993 | IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n"); |
| 992 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | 994 | spin_unlock_bh(&priv->statistics.lock); |
| 993 | return; | 995 | return; |
| 994 | } | 996 | } |
| 995 | 997 | ||
| @@ -1004,7 +1006,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) | |||
| 1004 | if ((rxon_chnum != stat_chnum) || (rxon_band24 != stat_band24)) { | 1006 | if ((rxon_chnum != stat_chnum) || (rxon_band24 != stat_band24)) { |
| 1005 | IWL_DEBUG_CALIB(priv, "Stats not from chan=%d, band24=%d\n", | 1007 | IWL_DEBUG_CALIB(priv, "Stats not from chan=%d, band24=%d\n", |
| 1006 | rxon_chnum, rxon_band24); | 1008 | rxon_chnum, rxon_band24); |
| 1007 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | 1009 | spin_unlock_bh(&priv->statistics.lock); |
| 1008 | return; | 1010 | return; |
| 1009 | } | 1011 | } |
| 1010 | 1012 | ||
| @@ -1023,7 +1025,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) | |||
| 1023 | chain_sig_b = le32_to_cpu(rx_info->beacon_rssi_b) & IN_BAND_FILTER; | 1025 | chain_sig_b = le32_to_cpu(rx_info->beacon_rssi_b) & IN_BAND_FILTER; |
| 1024 | chain_sig_c = le32_to_cpu(rx_info->beacon_rssi_c) & IN_BAND_FILTER; | 1026 | chain_sig_c = le32_to_cpu(rx_info->beacon_rssi_c) & IN_BAND_FILTER; |
| 1025 | 1027 | ||
| 1026 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | 1028 | spin_unlock_bh(&priv->statistics.lock); |
| 1027 | 1029 | ||
| 1028 | data->beacon_count++; | 1030 | data->beacon_count++; |
| 1029 | 1031 | ||
| @@ -1083,8 +1085,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) | |||
| 1083 | min_average_noise, min_average_noise_antenna_i); | 1085 | min_average_noise, min_average_noise_antenna_i); |
| 1084 | 1086 | ||
| 1085 | iwlagn_gain_computation(priv, average_noise, | 1087 | iwlagn_gain_computation(priv, average_noise, |
| 1086 | min_average_noise_antenna_i, min_average_noise, | 1088 | find_first_chain(hw_params(priv).valid_rx_ant)); |
| 1087 | find_first_chain(cfg(priv)->valid_rx_ant)); | ||
| 1088 | 1089 | ||
| 1089 | /* Some power changes may have been made during the calibration. | 1090 | /* Some power changes may have been made during the calibration. |
| 1090 | * Update and commit the RXON | 1091 | * Update and commit the RXON |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 5be0d3695d03..915183a3a873 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
| @@ -32,7 +32,6 @@ | |||
| 32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
| 33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
| 34 | 34 | ||
| 35 | #include "iwl-wifi.h" | ||
| 36 | #include "iwl-dev.h" | 35 | #include "iwl-dev.h" |
| 37 | #include "iwl-core.h" | 36 | #include "iwl-core.h" |
| 38 | #include "iwl-io.h" | 37 | #include "iwl-io.h" |
| @@ -52,7 +51,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) | |||
| 52 | struct iwlagn_tx_power_dbm_cmd tx_power_cmd; | 51 | struct iwlagn_tx_power_dbm_cmd tx_power_cmd; |
| 53 | u8 tx_ant_cfg_cmd; | 52 | u8 tx_ant_cfg_cmd; |
| 54 | 53 | ||
| 55 | if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->shrd->status), | 54 | if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status), |
| 56 | "TX Power requested while scanning!\n")) | 55 | "TX Power requested while scanning!\n")) |
| 57 | return -EAGAIN; | 56 | return -EAGAIN; |
| 58 | 57 | ||
| @@ -77,17 +76,19 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) | |||
| 77 | tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED; | 76 | tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED; |
| 78 | tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO; | 77 | tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO; |
| 79 | 78 | ||
| 80 | if (IWL_UCODE_API(nic(priv)->fw.ucode_ver) == 1) | 79 | if (IWL_UCODE_API(priv->fw->ucode_ver) == 1) |
| 81 | tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1; | 80 | tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1; |
| 82 | else | 81 | else |
| 83 | tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD; | 82 | tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD; |
| 84 | 83 | ||
| 85 | return iwl_trans_send_cmd_pdu(trans(priv), tx_ant_cfg_cmd, CMD_SYNC, | 84 | return iwl_dvm_send_cmd_pdu(priv, tx_ant_cfg_cmd, CMD_SYNC, |
| 86 | sizeof(tx_power_cmd), &tx_power_cmd); | 85 | sizeof(tx_power_cmd), &tx_power_cmd); |
| 87 | } | 86 | } |
| 88 | 87 | ||
| 89 | void iwlagn_temperature(struct iwl_priv *priv) | 88 | void iwlagn_temperature(struct iwl_priv *priv) |
| 90 | { | 89 | { |
| 90 | lockdep_assert_held(&priv->statistics.lock); | ||
| 91 | |||
| 91 | /* store temperature from correct statistics (in Celsius) */ | 92 | /* store temperature from correct statistics (in Celsius) */ |
| 92 | priv->temperature = le32_to_cpu(priv->statistics.common.temperature); | 93 | priv->temperature = le32_to_cpu(priv->statistics.common.temperature); |
| 93 | iwl_tt_handler(priv); | 94 | iwl_tt_handler(priv); |
| @@ -233,19 +234,19 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) | |||
| 233 | IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | | 234 | IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | |
| 234 | IWL_PAN_SCD_MULTICAST_MSK; | 235 | IWL_PAN_SCD_MULTICAST_MSK; |
| 235 | 236 | ||
| 236 | if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE) | 237 | if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) |
| 237 | flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; | 238 | flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; |
| 238 | 239 | ||
| 239 | IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n", | 240 | IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n", |
| 240 | flush_cmd.fifo_control); | 241 | flush_cmd.fifo_control); |
| 241 | flush_cmd.flush_control = cpu_to_le16(flush_control); | 242 | flush_cmd.flush_control = cpu_to_le16(flush_control); |
| 242 | 243 | ||
| 243 | return iwl_trans_send_cmd(trans(priv), &cmd); | 244 | return iwl_dvm_send_cmd(priv, &cmd); |
| 244 | } | 245 | } |
| 245 | 246 | ||
| 246 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) | 247 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) |
| 247 | { | 248 | { |
| 248 | mutex_lock(&priv->shrd->mutex); | 249 | mutex_lock(&priv->mutex); |
| 249 | ieee80211_stop_queues(priv->hw); | 250 | ieee80211_stop_queues(priv->hw); |
| 250 | if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { | 251 | if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { |
| 251 | IWL_ERR(priv, "flush request fail\n"); | 252 | IWL_ERR(priv, "flush request fail\n"); |
| @@ -255,7 +256,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) | |||
| 255 | iwl_trans_wait_tx_queue_empty(trans(priv)); | 256 | iwl_trans_wait_tx_queue_empty(trans(priv)); |
| 256 | done: | 257 | done: |
| 257 | ieee80211_wake_queues(priv->hw); | 258 | ieee80211_wake_queues(priv->hw); |
| 258 | mutex_unlock(&priv->shrd->mutex); | 259 | mutex_unlock(&priv->mutex); |
| 259 | } | 260 | } |
| 260 | 261 | ||
| 261 | /* | 262 | /* |
| @@ -434,12 +435,12 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) | |||
| 434 | if (cfg(priv)->bt_params->bt_session_2) { | 435 | if (cfg(priv)->bt_params->bt_session_2) { |
| 435 | memcpy(&bt_cmd_2000.basic, &basic, | 436 | memcpy(&bt_cmd_2000.basic, &basic, |
| 436 | sizeof(basic)); | 437 | sizeof(basic)); |
| 437 | ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG, | 438 | ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, |
| 438 | CMD_SYNC, sizeof(bt_cmd_2000), &bt_cmd_2000); | 439 | CMD_SYNC, sizeof(bt_cmd_2000), &bt_cmd_2000); |
| 439 | } else { | 440 | } else { |
| 440 | memcpy(&bt_cmd_6000.basic, &basic, | 441 | memcpy(&bt_cmd_6000.basic, &basic, |
| 441 | sizeof(basic)); | 442 | sizeof(basic)); |
| 442 | ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG, | 443 | ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, |
| 443 | CMD_SYNC, sizeof(bt_cmd_6000), &bt_cmd_6000); | 444 | CMD_SYNC, sizeof(bt_cmd_6000), &bt_cmd_6000); |
| 444 | } | 445 | } |
| 445 | if (ret) | 446 | if (ret) |
| @@ -452,7 +453,7 @@ void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena) | |||
| 452 | struct iwl_rxon_context *ctx, *found_ctx = NULL; | 453 | struct iwl_rxon_context *ctx, *found_ctx = NULL; |
| 453 | bool found_ap = false; | 454 | bool found_ap = false; |
| 454 | 455 | ||
| 455 | lockdep_assert_held(&priv->shrd->mutex); | 456 | lockdep_assert_held(&priv->mutex); |
| 456 | 457 | ||
| 457 | /* Check whether AP or GO mode is active. */ | 458 | /* Check whether AP or GO mode is active. */ |
| 458 | if (rssi_ena) { | 459 | if (rssi_ena) { |
| @@ -565,7 +566,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) | |||
| 565 | break; | 566 | break; |
| 566 | } | 567 | } |
| 567 | 568 | ||
| 568 | mutex_lock(&priv->shrd->mutex); | 569 | mutex_lock(&priv->mutex); |
| 569 | 570 | ||
| 570 | /* | 571 | /* |
| 571 | * We can not send command to firmware while scanning. When the scan | 572 | * We can not send command to firmware while scanning. When the scan |
| @@ -574,7 +575,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) | |||
| 574 | * STATUS_SCANNING to avoid race when queue_work two times from | 575 | * STATUS_SCANNING to avoid race when queue_work two times from |
| 575 | * different notifications, but quit and not perform any work at all. | 576 | * different notifications, but quit and not perform any work at all. |
| 576 | */ | 577 | */ |
| 577 | if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) | 578 | if (test_bit(STATUS_SCAN_HW, &priv->status)) |
| 578 | goto out; | 579 | goto out; |
| 579 | 580 | ||
| 580 | iwl_update_chain_flags(priv); | 581 | iwl_update_chain_flags(priv); |
| @@ -593,7 +594,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) | |||
| 593 | */ | 594 | */ |
| 594 | iwlagn_bt_coex_rssi_monitor(priv); | 595 | iwlagn_bt_coex_rssi_monitor(priv); |
| 595 | out: | 596 | out: |
| 596 | mutex_unlock(&priv->shrd->mutex); | 597 | mutex_unlock(&priv->mutex); |
| 597 | } | 598 | } |
| 598 | 599 | ||
| 599 | /* | 600 | /* |
| @@ -705,12 +706,11 @@ static void iwlagn_set_kill_msk(struct iwl_priv *priv, | |||
| 705 | } | 706 | } |
| 706 | 707 | ||
| 707 | int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, | 708 | int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, |
| 708 | struct iwl_rx_mem_buffer *rxb, | 709 | struct iwl_rx_cmd_buffer *rxb, |
| 709 | struct iwl_device_cmd *cmd) | 710 | struct iwl_device_cmd *cmd) |
| 710 | { | 711 | { |
| 711 | unsigned long flags; | ||
| 712 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 712 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 713 | struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; | 713 | struct iwl_bt_coex_profile_notif *coex = (void *)pkt->data; |
| 714 | struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; | 714 | struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; |
| 715 | 715 | ||
| 716 | if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) { | 716 | if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) { |
| @@ -754,9 +754,7 @@ int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, | |||
| 754 | 754 | ||
| 755 | /* FIXME: based on notification, adjust the prio_boost */ | 755 | /* FIXME: based on notification, adjust the prio_boost */ |
| 756 | 756 | ||
| 757 | spin_lock_irqsave(&priv->shrd->lock, flags); | ||
| 758 | priv->bt_ci_compliance = coex->bt_ci_compliance; | 757 | priv->bt_ci_compliance = coex->bt_ci_compliance; |
| 759 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | ||
| 760 | return 0; | 758 | return 0; |
| 761 | } | 759 | } |
| 762 | 760 | ||
| @@ -971,7 +969,7 @@ static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw, | |||
| 971 | u16 p1k[IWLAGN_P1K_SIZE]; | 969 | u16 p1k[IWLAGN_P1K_SIZE]; |
| 972 | int ret, i; | 970 | int ret, i; |
| 973 | 971 | ||
| 974 | mutex_lock(&priv->shrd->mutex); | 972 | mutex_lock(&priv->mutex); |
| 975 | 973 | ||
| 976 | if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || | 974 | if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || |
| 977 | key->cipher == WLAN_CIPHER_SUITE_WEP104) && | 975 | key->cipher == WLAN_CIPHER_SUITE_WEP104) && |
| @@ -1077,7 +1075,7 @@ static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw, | |||
| 1077 | break; | 1075 | break; |
| 1078 | } | 1076 | } |
| 1079 | 1077 | ||
| 1080 | mutex_unlock(&priv->shrd->mutex); | 1078 | mutex_unlock(&priv->mutex); |
| 1081 | } | 1079 | } |
| 1082 | 1080 | ||
| 1083 | int iwlagn_send_patterns(struct iwl_priv *priv, | 1081 | int iwlagn_send_patterns(struct iwl_priv *priv, |
| @@ -1117,13 +1115,12 @@ int iwlagn_send_patterns(struct iwl_priv *priv, | |||
| 1117 | } | 1115 | } |
| 1118 | 1116 | ||
| 1119 | cmd.data[0] = pattern_cmd; | 1117 | cmd.data[0] = pattern_cmd; |
| 1120 | err = iwl_trans_send_cmd(trans(priv), &cmd); | 1118 | err = iwl_dvm_send_cmd(priv, &cmd); |
| 1121 | kfree(pattern_cmd); | 1119 | kfree(pattern_cmd); |
| 1122 | return err; | 1120 | return err; |
| 1123 | } | 1121 | } |
| 1124 | 1122 | ||
| 1125 | int iwlagn_suspend(struct iwl_priv *priv, | 1123 | int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan) |
| 1126 | struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | ||
| 1127 | { | 1124 | { |
| 1128 | struct iwlagn_wowlan_wakeup_filter_cmd wakeup_filter_cmd; | 1125 | struct iwlagn_wowlan_wakeup_filter_cmd wakeup_filter_cmd; |
| 1129 | struct iwl_rxon_cmd rxon; | 1126 | struct iwl_rxon_cmd rxon; |
| @@ -1194,9 +1191,9 @@ int iwlagn_suspend(struct iwl_priv *priv, | |||
| 1194 | 1191 | ||
| 1195 | iwl_trans_stop_device(trans(priv)); | 1192 | iwl_trans_stop_device(trans(priv)); |
| 1196 | 1193 | ||
| 1197 | priv->shrd->wowlan = true; | 1194 | priv->wowlan = true; |
| 1198 | 1195 | ||
| 1199 | ret = iwl_load_ucode_wait_alive(trans(priv), IWL_UCODE_WOWLAN); | 1196 | ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); |
| 1200 | if (ret) | 1197 | if (ret) |
| 1201 | goto out; | 1198 | goto out; |
| 1202 | 1199 | ||
| @@ -1224,11 +1221,11 @@ int iwlagn_suspend(struct iwl_priv *priv, | |||
| 1224 | * constraints. Since we're in the suspend path | 1221 | * constraints. Since we're in the suspend path |
| 1225 | * that isn't really a problem though. | 1222 | * that isn't really a problem though. |
| 1226 | */ | 1223 | */ |
| 1227 | mutex_unlock(&priv->shrd->mutex); | 1224 | mutex_unlock(&priv->mutex); |
| 1228 | ieee80211_iter_keys(priv->hw, ctx->vif, | 1225 | ieee80211_iter_keys(priv->hw, ctx->vif, |
| 1229 | iwlagn_wowlan_program_keys, | 1226 | iwlagn_wowlan_program_keys, |
| 1230 | &key_data); | 1227 | &key_data); |
| 1231 | mutex_lock(&priv->shrd->mutex); | 1228 | mutex_lock(&priv->mutex); |
| 1232 | if (key_data.error) { | 1229 | if (key_data.error) { |
| 1233 | ret = -EIO; | 1230 | ret = -EIO; |
| 1234 | goto out; | 1231 | goto out; |
| @@ -1243,13 +1240,13 @@ int iwlagn_suspend(struct iwl_priv *priv, | |||
| 1243 | .len[0] = sizeof(key_data.rsc_tsc), | 1240 | .len[0] = sizeof(key_data.rsc_tsc), |
| 1244 | }; | 1241 | }; |
| 1245 | 1242 | ||
| 1246 | ret = iwl_trans_send_cmd(trans(priv), &rsc_tsc_cmd); | 1243 | ret = iwl_dvm_send_cmd(priv, &rsc_tsc_cmd); |
| 1247 | if (ret) | 1244 | if (ret) |
| 1248 | goto out; | 1245 | goto out; |
| 1249 | } | 1246 | } |
| 1250 | 1247 | ||
| 1251 | if (key_data.use_tkip) { | 1248 | if (key_data.use_tkip) { |
| 1252 | ret = iwl_trans_send_cmd_pdu(trans(priv), | 1249 | ret = iwl_dvm_send_cmd_pdu(priv, |
| 1253 | REPLY_WOWLAN_TKIP_PARAMS, | 1250 | REPLY_WOWLAN_TKIP_PARAMS, |
| 1254 | CMD_SYNC, sizeof(tkip_cmd), | 1251 | CMD_SYNC, sizeof(tkip_cmd), |
| 1255 | &tkip_cmd); | 1252 | &tkip_cmd); |
| @@ -1265,7 +1262,7 @@ int iwlagn_suspend(struct iwl_priv *priv, | |||
| 1265 | kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN); | 1262 | kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN); |
| 1266 | kek_kck_cmd.replay_ctr = priv->replay_ctr; | 1263 | kek_kck_cmd.replay_ctr = priv->replay_ctr; |
| 1267 | 1264 | ||
| 1268 | ret = iwl_trans_send_cmd_pdu(trans(priv), | 1265 | ret = iwl_dvm_send_cmd_pdu(priv, |
| 1269 | REPLY_WOWLAN_KEK_KCK_MATERIAL, | 1266 | REPLY_WOWLAN_KEK_KCK_MATERIAL, |
| 1270 | CMD_SYNC, sizeof(kek_kck_cmd), | 1267 | CMD_SYNC, sizeof(kek_kck_cmd), |
| 1271 | &kek_kck_cmd); | 1268 | &kek_kck_cmd); |
| @@ -1274,12 +1271,12 @@ int iwlagn_suspend(struct iwl_priv *priv, | |||
| 1274 | } | 1271 | } |
| 1275 | } | 1272 | } |
| 1276 | 1273 | ||
| 1277 | ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_D3_CONFIG, CMD_SYNC, | 1274 | ret = iwl_dvm_send_cmd_pdu(priv, REPLY_D3_CONFIG, CMD_SYNC, |
| 1278 | sizeof(d3_cfg_cmd), &d3_cfg_cmd); | 1275 | sizeof(d3_cfg_cmd), &d3_cfg_cmd); |
| 1279 | if (ret) | 1276 | if (ret) |
| 1280 | goto out; | 1277 | goto out; |
| 1281 | 1278 | ||
| 1282 | ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_WOWLAN_WAKEUP_FILTER, | 1279 | ret = iwl_dvm_send_cmd_pdu(priv, REPLY_WOWLAN_WAKEUP_FILTER, |
| 1283 | CMD_SYNC, sizeof(wakeup_filter_cmd), | 1280 | CMD_SYNC, sizeof(wakeup_filter_cmd), |
| 1284 | &wakeup_filter_cmd); | 1281 | &wakeup_filter_cmd); |
| 1285 | if (ret) | 1282 | if (ret) |
| @@ -1291,3 +1288,41 @@ int iwlagn_suspend(struct iwl_priv *priv, | |||
| 1291 | return ret; | 1288 | return ret; |
| 1292 | } | 1289 | } |
| 1293 | #endif | 1290 | #endif |
| 1291 | |||
| 1292 | int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | ||
| 1293 | { | ||
| 1294 | if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) { | ||
| 1295 | IWL_WARN(priv, "Not sending command - %s KILL\n", | ||
| 1296 | iwl_is_rfkill(priv) ? "RF" : "CT"); | ||
| 1297 | return -EIO; | ||
| 1298 | } | ||
| 1299 | |||
| 1300 | /* | ||
| 1301 | * Synchronous commands from this op-mode must hold | ||
| 1302 | * the mutex, this ensures we don't try to send two | ||
| 1303 | * (or more) synchronous commands at a time. | ||
| 1304 | */ | ||
| 1305 | if (cmd->flags & CMD_SYNC) | ||
| 1306 | lockdep_assert_held(&priv->mutex); | ||
| 1307 | |||
| 1308 | if (priv->ucode_owner == IWL_OWNERSHIP_TM && | ||
| 1309 | !(cmd->flags & CMD_ON_DEMAND)) { | ||
| 1310 | IWL_DEBUG_HC(priv, "tm own the uCode, no regular hcmd send\n"); | ||
| 1311 | return -EIO; | ||
| 1312 | } | ||
| 1313 | |||
| 1314 | return iwl_trans_send_cmd(trans(priv), cmd); | ||
| 1315 | } | ||
| 1316 | |||
| 1317 | int iwl_dvm_send_cmd_pdu(struct iwl_priv *priv, u8 id, | ||
| 1318 | u32 flags, u16 len, const void *data) | ||
| 1319 | { | ||
| 1320 | struct iwl_host_cmd cmd = { | ||
| 1321 | .id = id, | ||
| 1322 | .len = { len, }, | ||
| 1323 | .data = { data, }, | ||
| 1324 | .flags = flags, | ||
| 1325 | }; | ||
| 1326 | |||
| 1327 | return iwl_dvm_send_cmd(priv, &cmd); | ||
| 1328 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index a7d67135e3dc..53f8c51cfcdb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
| @@ -870,19 +870,16 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
| 870 | { | 870 | { |
| 871 | struct iwl_scale_tbl_info *tbl; | 871 | struct iwl_scale_tbl_info *tbl; |
| 872 | bool full_concurrent = priv->bt_full_concurrent; | 872 | bool full_concurrent = priv->bt_full_concurrent; |
| 873 | unsigned long flags; | ||
| 874 | 873 | ||
| 875 | if (priv->bt_ant_couple_ok) { | 874 | if (priv->bt_ant_couple_ok) { |
| 876 | /* | 875 | /* |
| 877 | * Is there a need to switch between | 876 | * Is there a need to switch between |
| 878 | * full concurrency and 3-wire? | 877 | * full concurrency and 3-wire? |
| 879 | */ | 878 | */ |
| 880 | spin_lock_irqsave(&priv->shrd->lock, flags); | ||
| 881 | if (priv->bt_ci_compliance && priv->bt_ant_couple_ok) | 879 | if (priv->bt_ci_compliance && priv->bt_ant_couple_ok) |
| 882 | full_concurrent = true; | 880 | full_concurrent = true; |
| 883 | else | 881 | else |
| 884 | full_concurrent = false; | 882 | full_concurrent = false; |
| 885 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | ||
| 886 | } | 883 | } |
| 887 | if ((priv->bt_traffic_load != priv->last_bt_traffic_load) || | 884 | if ((priv->bt_traffic_load != priv->last_bt_traffic_load) || |
| 888 | (priv->bt_full_concurrent != full_concurrent)) { | 885 | (priv->bt_full_concurrent != full_concurrent)) { |
| @@ -2680,7 +2677,6 @@ out: | |||
| 2680 | * which requires station table entry to exist). | 2677 | * which requires station table entry to exist). |
| 2681 | */ | 2678 | */ |
| 2682 | static void rs_initialize_lq(struct iwl_priv *priv, | 2679 | static void rs_initialize_lq(struct iwl_priv *priv, |
| 2683 | struct ieee80211_conf *conf, | ||
| 2684 | struct ieee80211_sta *sta, | 2680 | struct ieee80211_sta *sta, |
| 2685 | struct iwl_lq_sta *lq_sta) | 2681 | struct iwl_lq_sta *lq_sta) |
| 2686 | { | 2682 | { |
| @@ -2915,7 +2911,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i | |||
| 2915 | lq_sta->dbg_fixed_rate = 0; | 2911 | lq_sta->dbg_fixed_rate = 0; |
| 2916 | #endif | 2912 | #endif |
| 2917 | 2913 | ||
| 2918 | rs_initialize_lq(priv, conf, sta, lq_sta); | 2914 | rs_initialize_lq(priv, sta, lq_sta); |
| 2919 | } | 2915 | } |
| 2920 | 2916 | ||
| 2921 | static void rs_fill_link_cmd(struct iwl_priv *priv, | 2917 | static void rs_fill_link_cmd(struct iwl_priv *priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index 30bb5bbb0cd7..cc0227c1f352 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c | |||
| @@ -131,26 +131,27 @@ const char *get_cmd_string(u8 cmd) | |||
| 131 | ******************************************************************************/ | 131 | ******************************************************************************/ |
| 132 | 132 | ||
| 133 | static int iwlagn_rx_reply_error(struct iwl_priv *priv, | 133 | static int iwlagn_rx_reply_error(struct iwl_priv *priv, |
| 134 | struct iwl_rx_mem_buffer *rxb, | 134 | struct iwl_rx_cmd_buffer *rxb, |
| 135 | struct iwl_device_cmd *cmd) | 135 | struct iwl_device_cmd *cmd) |
| 136 | { | 136 | { |
| 137 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 137 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 138 | struct iwl_error_resp *err_resp = (void *)pkt->data; | ||
| 138 | 139 | ||
| 139 | IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) " | 140 | IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) " |
| 140 | "seq 0x%04X ser 0x%08X\n", | 141 | "seq 0x%04X ser 0x%08X\n", |
| 141 | le32_to_cpu(pkt->u.err_resp.error_type), | 142 | le32_to_cpu(err_resp->error_type), |
| 142 | get_cmd_string(pkt->u.err_resp.cmd_id), | 143 | get_cmd_string(err_resp->cmd_id), |
| 143 | pkt->u.err_resp.cmd_id, | 144 | err_resp->cmd_id, |
| 144 | le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num), | 145 | le16_to_cpu(err_resp->bad_cmd_seq_num), |
| 145 | le32_to_cpu(pkt->u.err_resp.error_info)); | 146 | le32_to_cpu(err_resp->error_info)); |
| 146 | return 0; | 147 | return 0; |
| 147 | } | 148 | } |
| 148 | 149 | ||
| 149 | static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | 150 | static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, |
| 150 | struct iwl_device_cmd *cmd) | 151 | struct iwl_device_cmd *cmd) |
| 151 | { | 152 | { |
| 152 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 153 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 153 | struct iwl_csa_notification *csa = &(pkt->u.csa_notif); | 154 | struct iwl_csa_notification *csa = (void *)pkt->data; |
| 154 | /* | 155 | /* |
| 155 | * MULTI-FIXME | 156 | * MULTI-FIXME |
| 156 | * See iwlagn_mac_channel_switch. | 157 | * See iwlagn_mac_channel_switch. |
| @@ -158,7 +159,7 @@ static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
| 158 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 159 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
| 159 | struct iwl_rxon_cmd *rxon = (void *)&ctx->active; | 160 | struct iwl_rxon_cmd *rxon = (void *)&ctx->active; |
| 160 | 161 | ||
| 161 | if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status)) | 162 | if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) |
| 162 | return 0; | 163 | return 0; |
| 163 | 164 | ||
| 164 | if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) { | 165 | if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) { |
| @@ -177,11 +178,11 @@ static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
| 177 | 178 | ||
| 178 | 179 | ||
| 179 | static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv, | 180 | static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv, |
| 180 | struct iwl_rx_mem_buffer *rxb, | 181 | struct iwl_rx_cmd_buffer *rxb, |
| 181 | struct iwl_device_cmd *cmd) | 182 | struct iwl_device_cmd *cmd) |
| 182 | { | 183 | { |
| 183 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 184 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 184 | struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif); | 185 | struct iwl_spectrum_notification *report = (void *)pkt->data; |
| 185 | 186 | ||
| 186 | if (!report->state) { | 187 | if (!report->state) { |
| 187 | IWL_DEBUG_11H(priv, | 188 | IWL_DEBUG_11H(priv, |
| @@ -195,12 +196,12 @@ static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv, | |||
| 195 | } | 196 | } |
| 196 | 197 | ||
| 197 | static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv, | 198 | static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv, |
| 198 | struct iwl_rx_mem_buffer *rxb, | 199 | struct iwl_rx_cmd_buffer *rxb, |
| 199 | struct iwl_device_cmd *cmd) | 200 | struct iwl_device_cmd *cmd) |
| 200 | { | 201 | { |
| 201 | #ifdef CONFIG_IWLWIFI_DEBUG | 202 | #ifdef CONFIG_IWLWIFI_DEBUG |
| 202 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 203 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 203 | struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif); | 204 | struct iwl_sleep_notification *sleep = (void *)pkt->data; |
| 204 | IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n", | 205 | IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n", |
| 205 | sleep->pm_sleep_mode, sleep->pm_wakeup_src); | 206 | sleep->pm_sleep_mode, sleep->pm_wakeup_src); |
| 206 | #endif | 207 | #endif |
| @@ -208,7 +209,7 @@ static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv, | |||
| 208 | } | 209 | } |
| 209 | 210 | ||
| 210 | static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv, | 211 | static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv, |
| 211 | struct iwl_rx_mem_buffer *rxb, | 212 | struct iwl_rx_cmd_buffer *rxb, |
| 212 | struct iwl_device_cmd *cmd) | 213 | struct iwl_device_cmd *cmd) |
| 213 | { | 214 | { |
| 214 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 215 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| @@ -217,16 +218,16 @@ static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv, | |||
| 217 | IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " | 218 | IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " |
| 218 | "notification for %s:\n", len, | 219 | "notification for %s:\n", len, |
| 219 | get_cmd_string(pkt->hdr.cmd)); | 220 | get_cmd_string(pkt->hdr.cmd)); |
| 220 | iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len); | 221 | iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->data, len); |
| 221 | return 0; | 222 | return 0; |
| 222 | } | 223 | } |
| 223 | 224 | ||
| 224 | static int iwlagn_rx_beacon_notif(struct iwl_priv *priv, | 225 | static int iwlagn_rx_beacon_notif(struct iwl_priv *priv, |
| 225 | struct iwl_rx_mem_buffer *rxb, | 226 | struct iwl_rx_cmd_buffer *rxb, |
| 226 | struct iwl_device_cmd *cmd) | 227 | struct iwl_device_cmd *cmd) |
| 227 | { | 228 | { |
| 228 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 229 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 229 | struct iwlagn_beacon_notif *beacon = (void *)pkt->u.raw; | 230 | struct iwlagn_beacon_notif *beacon = (void *)pkt->data; |
| 230 | #ifdef CONFIG_IWLWIFI_DEBUG | 231 | #ifdef CONFIG_IWLWIFI_DEBUG |
| 231 | u16 status = le16_to_cpu(beacon->beacon_notify_hdr.status.status); | 232 | u16 status = le16_to_cpu(beacon->beacon_notify_hdr.status.status); |
| 232 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); | 233 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); |
| @@ -266,6 +267,8 @@ static bool iwlagn_good_ack_health(struct iwl_priv *priv, | |||
| 266 | if (priv->agg_tids_count) | 267 | if (priv->agg_tids_count) |
| 267 | return true; | 268 | return true; |
| 268 | 269 | ||
| 270 | lockdep_assert_held(&priv->statistics.lock); | ||
| 271 | |||
| 269 | old = &priv->statistics.tx; | 272 | old = &priv->statistics.tx; |
| 270 | 273 | ||
| 271 | actual_delta = le32_to_cpu(cur->actual_ack_cnt) - | 274 | actual_delta = le32_to_cpu(cur->actual_ack_cnt) - |
| @@ -318,7 +321,7 @@ static bool iwlagn_good_plcp_health(struct iwl_priv *priv, | |||
| 318 | unsigned int msecs) | 321 | unsigned int msecs) |
| 319 | { | 322 | { |
| 320 | int delta; | 323 | int delta; |
| 321 | int threshold = cfg(priv)->base_params->plcp_delta_threshold; | 324 | int threshold = priv->plcp_delta_threshold; |
| 322 | 325 | ||
| 323 | if (threshold == IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { | 326 | if (threshold == IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { |
| 324 | IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); | 327 | IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); |
| @@ -352,7 +355,7 @@ static void iwlagn_recover_from_statistics(struct iwl_priv *priv, | |||
| 352 | { | 355 | { |
| 353 | unsigned int msecs; | 356 | unsigned int msecs; |
| 354 | 357 | ||
| 355 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 358 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 356 | return; | 359 | return; |
| 357 | 360 | ||
| 358 | msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies); | 361 | msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies); |
| @@ -487,7 +490,7 @@ iwlagn_accumulative_statistics(struct iwl_priv *priv, | |||
| 487 | #endif | 490 | #endif |
| 488 | 491 | ||
| 489 | static int iwlagn_rx_statistics(struct iwl_priv *priv, | 492 | static int iwlagn_rx_statistics(struct iwl_priv *priv, |
| 490 | struct iwl_rx_mem_buffer *rxb, | 493 | struct iwl_rx_cmd_buffer *rxb, |
| 491 | struct iwl_device_cmd *cmd) | 494 | struct iwl_device_cmd *cmd) |
| 492 | { | 495 | { |
| 493 | unsigned long stamp = jiffies; | 496 | unsigned long stamp = jiffies; |
| @@ -509,9 +512,11 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, | |||
| 509 | IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n", | 512 | IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n", |
| 510 | len); | 513 | len); |
| 511 | 514 | ||
| 515 | spin_lock(&priv->statistics.lock); | ||
| 516 | |||
| 512 | if (len == sizeof(struct iwl_bt_notif_statistics)) { | 517 | if (len == sizeof(struct iwl_bt_notif_statistics)) { |
| 513 | struct iwl_bt_notif_statistics *stats; | 518 | struct iwl_bt_notif_statistics *stats; |
| 514 | stats = &pkt->u.stats_bt; | 519 | stats = (void *)&pkt->data; |
| 515 | flag = &stats->flag; | 520 | flag = &stats->flag; |
| 516 | common = &stats->general.common; | 521 | common = &stats->general.common; |
| 517 | rx_non_phy = &stats->rx.general.common; | 522 | rx_non_phy = &stats->rx.general.common; |
| @@ -529,7 +534,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, | |||
| 529 | #endif | 534 | #endif |
| 530 | } else if (len == sizeof(struct iwl_notif_statistics)) { | 535 | } else if (len == sizeof(struct iwl_notif_statistics)) { |
| 531 | struct iwl_notif_statistics *stats; | 536 | struct iwl_notif_statistics *stats; |
| 532 | stats = &pkt->u.stats; | 537 | stats = (void *)&pkt->data; |
| 533 | flag = &stats->flag; | 538 | flag = &stats->flag; |
| 534 | common = &stats->general.common; | 539 | common = &stats->general.common; |
| 535 | rx_non_phy = &stats->rx.general; | 540 | rx_non_phy = &stats->rx.general; |
| @@ -542,6 +547,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, | |||
| 542 | WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n", | 547 | WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n", |
| 543 | len, sizeof(struct iwl_bt_notif_statistics), | 548 | len, sizeof(struct iwl_bt_notif_statistics), |
| 544 | sizeof(struct iwl_notif_statistics)); | 549 | sizeof(struct iwl_notif_statistics)); |
| 550 | spin_unlock(&priv->statistics.lock); | ||
| 545 | return 0; | 551 | return 0; |
| 546 | } | 552 | } |
| 547 | 553 | ||
| @@ -569,7 +575,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, | |||
| 569 | 575 | ||
| 570 | priv->rx_statistics_jiffies = stamp; | 576 | priv->rx_statistics_jiffies = stamp; |
| 571 | 577 | ||
| 572 | set_bit(STATUS_STATISTICS, &priv->shrd->status); | 578 | set_bit(STATUS_STATISTICS, &priv->status); |
| 573 | 579 | ||
| 574 | /* Reschedule the statistics timer to occur in | 580 | /* Reschedule the statistics timer to occur in |
| 575 | * reg_recalib_period seconds to ensure we get a | 581 | * reg_recalib_period seconds to ensure we get a |
| @@ -578,23 +584,27 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, | |||
| 578 | mod_timer(&priv->statistics_periodic, jiffies + | 584 | mod_timer(&priv->statistics_periodic, jiffies + |
| 579 | msecs_to_jiffies(reg_recalib_period * 1000)); | 585 | msecs_to_jiffies(reg_recalib_period * 1000)); |
| 580 | 586 | ||
| 581 | if (unlikely(!test_bit(STATUS_SCANNING, &priv->shrd->status)) && | 587 | if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && |
| 582 | (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { | 588 | (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { |
| 583 | iwlagn_rx_calc_noise(priv); | 589 | iwlagn_rx_calc_noise(priv); |
| 584 | queue_work(priv->workqueue, &priv->run_time_calib_work); | 590 | queue_work(priv->workqueue, &priv->run_time_calib_work); |
| 585 | } | 591 | } |
| 586 | if (cfg(priv)->lib->temperature && change) | 592 | if (cfg(priv)->lib->temperature && change) |
| 587 | cfg(priv)->lib->temperature(priv); | 593 | cfg(priv)->lib->temperature(priv); |
| 594 | |||
| 595 | spin_unlock(&priv->statistics.lock); | ||
| 596 | |||
| 588 | return 0; | 597 | return 0; |
| 589 | } | 598 | } |
| 590 | 599 | ||
| 591 | static int iwlagn_rx_reply_statistics(struct iwl_priv *priv, | 600 | static int iwlagn_rx_reply_statistics(struct iwl_priv *priv, |
| 592 | struct iwl_rx_mem_buffer *rxb, | 601 | struct iwl_rx_cmd_buffer *rxb, |
| 593 | struct iwl_device_cmd *cmd) | 602 | struct iwl_device_cmd *cmd) |
| 594 | { | 603 | { |
| 595 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 604 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 605 | struct iwl_notif_statistics *stats = (void *)pkt->data; | ||
| 596 | 606 | ||
| 597 | if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { | 607 | if (le32_to_cpu(stats->flag) & UCODE_STATISTICS_CLEAR_MSK) { |
| 598 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 608 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
| 599 | memset(&priv->accum_stats, 0, | 609 | memset(&priv->accum_stats, 0, |
| 600 | sizeof(priv->accum_stats)); | 610 | sizeof(priv->accum_stats)); |
| @@ -612,12 +622,13 @@ static int iwlagn_rx_reply_statistics(struct iwl_priv *priv, | |||
| 612 | /* Handle notification from uCode that card's power state is changing | 622 | /* Handle notification from uCode that card's power state is changing |
| 613 | * due to software, hardware, or critical temperature RFKILL */ | 623 | * due to software, hardware, or critical temperature RFKILL */ |
| 614 | static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, | 624 | static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, |
| 615 | struct iwl_rx_mem_buffer *rxb, | 625 | struct iwl_rx_cmd_buffer *rxb, |
| 616 | struct iwl_device_cmd *cmd) | 626 | struct iwl_device_cmd *cmd) |
| 617 | { | 627 | { |
| 618 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 628 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 619 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); | 629 | struct iwl_card_state_notif *card_state_notif = (void *)pkt->data; |
| 620 | unsigned long status = priv->shrd->status; | 630 | u32 flags = le32_to_cpu(card_state_notif->flags); |
| 631 | unsigned long status = priv->status; | ||
| 621 | 632 | ||
| 622 | IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n", | 633 | IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n", |
| 623 | (flags & HW_CARD_DISABLED) ? "Kill" : "On", | 634 | (flags & HW_CARD_DISABLED) ? "Kill" : "On", |
| @@ -647,32 +658,31 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, | |||
| 647 | iwl_tt_exit_ct_kill(priv); | 658 | iwl_tt_exit_ct_kill(priv); |
| 648 | 659 | ||
| 649 | if (flags & HW_CARD_DISABLED) | 660 | if (flags & HW_CARD_DISABLED) |
| 650 | set_bit(STATUS_RF_KILL_HW, &priv->shrd->status); | 661 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
| 651 | else | 662 | else |
| 652 | clear_bit(STATUS_RF_KILL_HW, &priv->shrd->status); | 663 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
| 653 | 664 | ||
| 654 | 665 | ||
| 655 | if (!(flags & RXON_CARD_DISABLED)) | 666 | if (!(flags & RXON_CARD_DISABLED)) |
| 656 | iwl_scan_cancel(priv); | 667 | iwl_scan_cancel(priv); |
| 657 | 668 | ||
| 658 | if ((test_bit(STATUS_RF_KILL_HW, &status) != | 669 | if ((test_bit(STATUS_RF_KILL_HW, &status) != |
| 659 | test_bit(STATUS_RF_KILL_HW, &priv->shrd->status))) | 670 | test_bit(STATUS_RF_KILL_HW, &priv->status))) |
| 660 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, | 671 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, |
| 661 | test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)); | 672 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
| 662 | else | 673 | else |
| 663 | wake_up(&priv->shrd->wait_command_queue); | 674 | wake_up(&priv->shrd->wait_command_queue); |
| 664 | return 0; | 675 | return 0; |
| 665 | } | 676 | } |
| 666 | 677 | ||
| 667 | static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, | 678 | static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, |
| 668 | struct iwl_rx_mem_buffer *rxb, | 679 | struct iwl_rx_cmd_buffer *rxb, |
| 669 | struct iwl_device_cmd *cmd) | 680 | struct iwl_device_cmd *cmd) |
| 670 | 681 | ||
| 671 | { | 682 | { |
| 672 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 683 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 673 | struct iwl_missed_beacon_notif *missed_beacon; | 684 | struct iwl_missed_beacon_notif *missed_beacon = (void *)pkt->data; |
| 674 | 685 | ||
| 675 | missed_beacon = &pkt->u.missed_beacon; | ||
| 676 | if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) > | 686 | if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) > |
| 677 | priv->missed_beacon_threshold) { | 687 | priv->missed_beacon_threshold) { |
| 678 | IWL_DEBUG_CALIB(priv, | 688 | IWL_DEBUG_CALIB(priv, |
| @@ -681,7 +691,7 @@ static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, | |||
| 681 | le32_to_cpu(missed_beacon->total_missed_becons), | 691 | le32_to_cpu(missed_beacon->total_missed_becons), |
| 682 | le32_to_cpu(missed_beacon->num_recvd_beacons), | 692 | le32_to_cpu(missed_beacon->num_recvd_beacons), |
| 683 | le32_to_cpu(missed_beacon->num_expected_beacons)); | 693 | le32_to_cpu(missed_beacon->num_expected_beacons)); |
| 684 | if (!test_bit(STATUS_SCANNING, &priv->shrd->status)) | 694 | if (!test_bit(STATUS_SCANNING, &priv->status)) |
| 685 | iwl_init_sensitivity(priv); | 695 | iwl_init_sensitivity(priv); |
| 686 | } | 696 | } |
| 687 | return 0; | 697 | return 0; |
| @@ -690,13 +700,13 @@ static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, | |||
| 690 | /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). | 700 | /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). |
| 691 | * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ | 701 | * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ |
| 692 | static int iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, | 702 | static int iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, |
| 693 | struct iwl_rx_mem_buffer *rxb, | 703 | struct iwl_rx_cmd_buffer *rxb, |
| 694 | struct iwl_device_cmd *cmd) | 704 | struct iwl_device_cmd *cmd) |
| 695 | { | 705 | { |
| 696 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 706 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 697 | 707 | ||
| 698 | priv->last_phy_res_valid = true; | 708 | priv->last_phy_res_valid = true; |
| 699 | memcpy(&priv->last_phy_res, pkt->u.raw, | 709 | memcpy(&priv->last_phy_res, pkt->data, |
| 700 | sizeof(struct iwl_rx_phy_res)); | 710 | sizeof(struct iwl_rx_phy_res)); |
| 701 | return 0; | 711 | return 0; |
| 702 | } | 712 | } |
| @@ -757,12 +767,14 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
| 757 | struct ieee80211_hdr *hdr, | 767 | struct ieee80211_hdr *hdr, |
| 758 | u16 len, | 768 | u16 len, |
| 759 | u32 ampdu_status, | 769 | u32 ampdu_status, |
| 760 | struct iwl_rx_mem_buffer *rxb, | 770 | struct iwl_rx_cmd_buffer *rxb, |
| 761 | struct ieee80211_rx_status *stats) | 771 | struct ieee80211_rx_status *stats) |
| 762 | { | 772 | { |
| 763 | struct sk_buff *skb; | 773 | struct sk_buff *skb; |
| 764 | __le16 fc = hdr->frame_control; | 774 | __le16 fc = hdr->frame_control; |
| 765 | struct iwl_rxon_context *ctx; | 775 | struct iwl_rxon_context *ctx; |
| 776 | struct page *p; | ||
| 777 | int offset; | ||
| 766 | 778 | ||
| 767 | /* We only process data packets if the interface is open */ | 779 | /* We only process data packets if the interface is open */ |
| 768 | if (unlikely(!priv->is_open)) { | 780 | if (unlikely(!priv->is_open)) { |
| @@ -782,7 +794,9 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
| 782 | return; | 794 | return; |
| 783 | } | 795 | } |
| 784 | 796 | ||
| 785 | skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); | 797 | offset = (void *)hdr - rxb_addr(rxb); |
| 798 | p = rxb_steal_page(rxb); | ||
| 799 | skb_add_rx_frag(skb, 0, p, offset, len); | ||
| 786 | 800 | ||
| 787 | iwl_update_stats(priv, false, fc, len); | 801 | iwl_update_stats(priv, false, fc, len); |
| 788 | 802 | ||
| @@ -793,23 +807,18 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
| 793 | * sometimes even after already having transmitted frames for the | 807 | * sometimes even after already having transmitted frames for the |
| 794 | * association because the new RXON may reset the information. | 808 | * association because the new RXON may reset the information. |
| 795 | */ | 809 | */ |
| 796 | if (unlikely(ieee80211_is_beacon(fc))) { | 810 | if (unlikely(ieee80211_is_beacon(fc) && priv->passive_no_rx)) { |
| 797 | for_each_context(priv, ctx) { | 811 | for_each_context(priv, ctx) { |
| 798 | if (!ctx->last_tx_rejected) | ||
| 799 | continue; | ||
| 800 | if (compare_ether_addr(hdr->addr3, | 812 | if (compare_ether_addr(hdr->addr3, |
| 801 | ctx->active.bssid_addr)) | 813 | ctx->active.bssid_addr)) |
| 802 | continue; | 814 | continue; |
| 803 | ctx->last_tx_rejected = false; | 815 | iwlagn_lift_passive_no_rx(priv); |
| 804 | iwl_trans_wake_any_queue(trans(priv), ctx->ctxid, | ||
| 805 | "channel got active"); | ||
| 806 | } | 816 | } |
| 807 | } | 817 | } |
| 808 | 818 | ||
| 809 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); | 819 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); |
| 810 | 820 | ||
| 811 | ieee80211_rx(priv->hw, skb); | 821 | ieee80211_rx(priv->hw, skb); |
| 812 | rxb->page = NULL; | ||
| 813 | } | 822 | } |
| 814 | 823 | ||
| 815 | static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) | 824 | static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) |
| @@ -915,7 +924,7 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv, | |||
| 915 | /* Called for REPLY_RX (legacy ABG frames), or | 924 | /* Called for REPLY_RX (legacy ABG frames), or |
| 916 | * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ | 925 | * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ |
| 917 | static int iwlagn_rx_reply_rx(struct iwl_priv *priv, | 926 | static int iwlagn_rx_reply_rx(struct iwl_priv *priv, |
| 918 | struct iwl_rx_mem_buffer *rxb, | 927 | struct iwl_rx_cmd_buffer *rxb, |
| 919 | struct iwl_device_cmd *cmd) | 928 | struct iwl_device_cmd *cmd) |
| 920 | { | 929 | { |
| 921 | struct ieee80211_hdr *header; | 930 | struct ieee80211_hdr *header; |
| @@ -938,12 +947,12 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, | |||
| 938 | * received. | 947 | * received. |
| 939 | */ | 948 | */ |
| 940 | if (pkt->hdr.cmd == REPLY_RX) { | 949 | if (pkt->hdr.cmd == REPLY_RX) { |
| 941 | phy_res = (struct iwl_rx_phy_res *)pkt->u.raw; | 950 | phy_res = (struct iwl_rx_phy_res *)pkt->data; |
| 942 | header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res) | 951 | header = (struct ieee80211_hdr *)(pkt->data + sizeof(*phy_res) |
| 943 | + phy_res->cfg_phy_cnt); | 952 | + phy_res->cfg_phy_cnt); |
| 944 | 953 | ||
| 945 | len = le16_to_cpu(phy_res->byte_count); | 954 | len = le16_to_cpu(phy_res->byte_count); |
| 946 | rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) + | 955 | rx_pkt_status = *(__le32 *)(pkt->data + sizeof(*phy_res) + |
| 947 | phy_res->cfg_phy_cnt + len); | 956 | phy_res->cfg_phy_cnt + len); |
| 948 | ampdu_status = le32_to_cpu(rx_pkt_status); | 957 | ampdu_status = le32_to_cpu(rx_pkt_status); |
| 949 | } else { | 958 | } else { |
| @@ -952,10 +961,10 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, | |||
| 952 | return 0; | 961 | return 0; |
| 953 | } | 962 | } |
| 954 | phy_res = &priv->last_phy_res; | 963 | phy_res = &priv->last_phy_res; |
| 955 | amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw; | 964 | amsdu = (struct iwl_rx_mpdu_res_start *)pkt->data; |
| 956 | header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu)); | 965 | header = (struct ieee80211_hdr *)(pkt->data + sizeof(*amsdu)); |
| 957 | len = le16_to_cpu(amsdu->byte_count); | 966 | len = le16_to_cpu(amsdu->byte_count); |
| 958 | rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len); | 967 | rx_pkt_status = *(__le32 *)(pkt->data + sizeof(*amsdu) + len); |
| 959 | ampdu_status = iwlagn_translate_rx_status(priv, | 968 | ampdu_status = iwlagn_translate_rx_status(priv, |
| 960 | le32_to_cpu(rx_pkt_status)); | 969 | le32_to_cpu(rx_pkt_status)); |
| 961 | } | 970 | } |
| @@ -1035,12 +1044,12 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, | |||
| 1035 | } | 1044 | } |
| 1036 | 1045 | ||
| 1037 | static int iwlagn_rx_noa_notification(struct iwl_priv *priv, | 1046 | static int iwlagn_rx_noa_notification(struct iwl_priv *priv, |
| 1038 | struct iwl_rx_mem_buffer *rxb, | 1047 | struct iwl_rx_cmd_buffer *rxb, |
| 1039 | struct iwl_device_cmd *cmd) | 1048 | struct iwl_device_cmd *cmd) |
| 1040 | { | 1049 | { |
| 1041 | struct iwl_wipan_noa_data *new_data, *old_data; | 1050 | struct iwl_wipan_noa_data *new_data, *old_data; |
| 1042 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 1051 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 1043 | struct iwl_wipan_noa_notification *noa_notif = (void *)pkt->u.raw; | 1052 | struct iwl_wipan_noa_notification *noa_notif = (void *)pkt->data; |
| 1044 | 1053 | ||
| 1045 | /* no condition -- we're in softirq */ | 1054 | /* no condition -- we're in softirq */ |
| 1046 | old_data = rcu_dereference_protected(priv->noa_data, true); | 1055 | old_data = rcu_dereference_protected(priv->noa_data, true); |
| @@ -1086,7 +1095,7 @@ static int iwlagn_rx_noa_notification(struct iwl_priv *priv, | |||
| 1086 | */ | 1095 | */ |
| 1087 | void iwl_setup_rx_handlers(struct iwl_priv *priv) | 1096 | void iwl_setup_rx_handlers(struct iwl_priv *priv) |
| 1088 | { | 1097 | { |
| 1089 | int (**handlers)(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | 1098 | int (**handlers)(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, |
| 1090 | struct iwl_device_cmd *cmd); | 1099 | struct iwl_device_cmd *cmd); |
| 1091 | 1100 | ||
| 1092 | handlers = priv->rx_handlers; | 1101 | handlers = priv->rx_handlers; |
| @@ -1131,21 +1140,20 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv) | |||
| 1131 | priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx; | 1140 | priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx; |
| 1132 | 1141 | ||
| 1133 | /* set up notification wait support */ | 1142 | /* set up notification wait support */ |
| 1134 | spin_lock_init(&priv->shrd->notif_wait_lock); | 1143 | iwl_notification_wait_init(&priv->notif_wait); |
| 1135 | INIT_LIST_HEAD(&priv->shrd->notif_waits); | ||
| 1136 | init_waitqueue_head(&priv->shrd->notif_waitq); | ||
| 1137 | 1144 | ||
| 1138 | /* Set up BT Rx handlers */ | 1145 | /* Set up BT Rx handlers */ |
| 1139 | if (cfg(priv)->lib->bt_rx_handler_setup) | 1146 | if (cfg(priv)->bt_params) |
| 1140 | cfg(priv)->lib->bt_rx_handler_setup(priv); | 1147 | iwlagn_bt_rx_handler_setup(priv); |
| 1141 | |||
| 1142 | } | 1148 | } |
| 1143 | 1149 | ||
| 1144 | int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_mem_buffer *rxb, | 1150 | int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, |
| 1145 | struct iwl_device_cmd *cmd) | 1151 | struct iwl_device_cmd *cmd) |
| 1146 | { | 1152 | { |
| 1147 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 1153 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 1148 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 1154 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
| 1155 | void (*pre_rx_handler)(struct iwl_priv *, | ||
| 1156 | struct iwl_rx_cmd_buffer *); | ||
| 1149 | int err = 0; | 1157 | int err = 0; |
| 1150 | 1158 | ||
| 1151 | /* | 1159 | /* |
| @@ -1153,30 +1161,22 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_mem_buffer *rxb, | |||
| 1153 | * even if the RX handler consumes the RXB we have | 1161 | * even if the RX handler consumes the RXB we have |
| 1154 | * access to it in the notification wait entry. | 1162 | * access to it in the notification wait entry. |
| 1155 | */ | 1163 | */ |
| 1156 | if (!list_empty(&priv->shrd->notif_waits)) { | 1164 | iwl_notification_wait_notify(&priv->notif_wait, pkt); |
| 1157 | struct iwl_notification_wait *w; | 1165 | |
| 1158 | 1166 | /* RX data may be forwarded to userspace (using pre_rx_handler) in one | |
| 1159 | spin_lock(&priv->shrd->notif_wait_lock); | 1167 | * of two cases: the first, that the user owns the uCode through |
| 1160 | list_for_each_entry(w, &priv->shrd->notif_waits, list) { | 1168 | * testmode - in such case the pre_rx_handler is set and no further |
| 1161 | if (w->cmd != pkt->hdr.cmd) | 1169 | * processing takes place. The other case is when the user want to |
| 1162 | continue; | 1170 | * monitor the rx w/o affecting the regular flow - the pre_rx_handler |
| 1163 | IWL_DEBUG_RX(priv, | 1171 | * will be set but the ownership flag != IWL_OWNERSHIP_TM and the flow |
| 1164 | "Notif: %s, 0x%02x - wake the callers up\n", | 1172 | * continues. |
| 1165 | get_cmd_string(pkt->hdr.cmd), | 1173 | * We need to use ACCESS_ONCE to prevent a case where the handler |
| 1166 | pkt->hdr.cmd); | 1174 | * changes between the check and the call. |
| 1167 | w->triggered = true; | 1175 | */ |
| 1168 | if (w->fn) | 1176 | pre_rx_handler = ACCESS_ONCE(priv->pre_rx_handler); |
| 1169 | w->fn(trans(priv), pkt, w->fn_data); | 1177 | if (pre_rx_handler) |
| 1170 | } | 1178 | pre_rx_handler(priv, rxb); |
| 1171 | spin_unlock(&priv->shrd->notif_wait_lock); | 1179 | if (priv->ucode_owner != IWL_OWNERSHIP_TM) { |
| 1172 | |||
| 1173 | wake_up_all(&priv->shrd->notif_waitq); | ||
| 1174 | } | ||
| 1175 | |||
| 1176 | if (priv->pre_rx_handler && | ||
| 1177 | priv->shrd->ucode_owner == IWL_OWNERSHIP_TM) | ||
| 1178 | priv->pre_rx_handler(priv, rxb); | ||
| 1179 | else { | ||
| 1180 | /* Based on type of command response or notification, | 1180 | /* Based on type of command response or notification, |
| 1181 | * handle those that need handling via function in | 1181 | * handle those that need handling via function in |
| 1182 | * rx_handlers table. See iwl_setup_rx_handlers() */ | 1182 | * rx_handlers table. See iwl_setup_rx_handlers() */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 73653a6cf32d..36909077f994 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | |||
| @@ -39,7 +39,7 @@ static int iwlagn_disable_bss(struct iwl_priv *priv, | |||
| 39 | int ret; | 39 | int ret; |
| 40 | 40 | ||
| 41 | send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 41 | send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
| 42 | ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd, | 42 | ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, |
| 43 | CMD_SYNC, sizeof(*send), send); | 43 | CMD_SYNC, sizeof(*send), send); |
| 44 | 44 | ||
| 45 | send->filter_flags = old_filter; | 45 | send->filter_flags = old_filter; |
| @@ -60,13 +60,13 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, | |||
| 60 | u8 old_dev_type = send->dev_type; | 60 | u8 old_dev_type = send->dev_type; |
| 61 | int ret; | 61 | int ret; |
| 62 | 62 | ||
| 63 | iwl_init_notification_wait(priv->shrd, &disable_wait, | 63 | iwl_init_notification_wait(&priv->notif_wait, &disable_wait, |
| 64 | REPLY_WIPAN_DEACTIVATION_COMPLETE, | 64 | REPLY_WIPAN_DEACTIVATION_COMPLETE, |
| 65 | NULL, NULL); | 65 | NULL, NULL); |
| 66 | 66 | ||
| 67 | send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 67 | send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
| 68 | send->dev_type = RXON_DEV_TYPE_P2P; | 68 | send->dev_type = RXON_DEV_TYPE_P2P; |
| 69 | ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd, | 69 | ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, |
| 70 | CMD_SYNC, sizeof(*send), send); | 70 | CMD_SYNC, sizeof(*send), send); |
| 71 | 71 | ||
| 72 | send->filter_flags = old_filter; | 72 | send->filter_flags = old_filter; |
| @@ -74,9 +74,10 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, | |||
| 74 | 74 | ||
| 75 | if (ret) { | 75 | if (ret) { |
| 76 | IWL_ERR(priv, "Error disabling PAN (%d)\n", ret); | 76 | IWL_ERR(priv, "Error disabling PAN (%d)\n", ret); |
| 77 | iwl_remove_notification(priv->shrd, &disable_wait); | 77 | iwl_remove_notification(&priv->notif_wait, &disable_wait); |
| 78 | } else { | 78 | } else { |
| 79 | ret = iwl_wait_notification(priv->shrd, &disable_wait, HZ); | 79 | ret = iwl_wait_notification(&priv->notif_wait, |
| 80 | &disable_wait, HZ); | ||
| 80 | if (ret) | 81 | if (ret) |
| 81 | IWL_ERR(priv, "Timed out waiting for PAN disable\n"); | 82 | IWL_ERR(priv, "Timed out waiting for PAN disable\n"); |
| 82 | } | 83 | } |
| @@ -92,7 +93,7 @@ static int iwlagn_disconn_pan(struct iwl_priv *priv, | |||
| 92 | int ret; | 93 | int ret; |
| 93 | 94 | ||
| 94 | send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 95 | send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
| 95 | ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd, CMD_SYNC, | 96 | ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, |
| 96 | sizeof(*send), send); | 97 | sizeof(*send), send); |
| 97 | 98 | ||
| 98 | send->filter_flags = old_filter; | 99 | send->filter_flags = old_filter; |
| @@ -121,7 +122,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv, | |||
| 121 | ctx->qos_data.qos_active, | 122 | ctx->qos_data.qos_active, |
| 122 | ctx->qos_data.def_qos_parm.qos_flags); | 123 | ctx->qos_data.def_qos_parm.qos_flags); |
| 123 | 124 | ||
| 124 | ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->qos_cmd, CMD_SYNC, | 125 | ret = iwl_dvm_send_cmd_pdu(priv, ctx->qos_cmd, CMD_SYNC, |
| 125 | sizeof(struct iwl_qosparam_cmd), | 126 | sizeof(struct iwl_qosparam_cmd), |
| 126 | &ctx->qos_data.def_qos_parm); | 127 | &ctx->qos_data.def_qos_parm); |
| 127 | if (ret) | 128 | if (ret) |
| @@ -131,7 +132,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv, | |||
| 131 | static int iwlagn_update_beacon(struct iwl_priv *priv, | 132 | static int iwlagn_update_beacon(struct iwl_priv *priv, |
| 132 | struct ieee80211_vif *vif) | 133 | struct ieee80211_vif *vif) |
| 133 | { | 134 | { |
| 134 | lockdep_assert_held(&priv->shrd->mutex); | 135 | lockdep_assert_held(&priv->mutex); |
| 135 | 136 | ||
| 136 | dev_kfree_skb(priv->beacon_skb); | 137 | dev_kfree_skb(priv->beacon_skb); |
| 137 | priv->beacon_skb = ieee80211_beacon_get(priv->hw, vif); | 138 | priv->beacon_skb = ieee80211_beacon_get(priv->hw, vif); |
| @@ -180,7 +181,7 @@ static int iwlagn_send_rxon_assoc(struct iwl_priv *priv, | |||
| 180 | ctx->staging.ofdm_ht_triple_stream_basic_rates; | 181 | ctx->staging.ofdm_ht_triple_stream_basic_rates; |
| 181 | rxon_assoc.acquisition_data = ctx->staging.acquisition_data; | 182 | rxon_assoc.acquisition_data = ctx->staging.acquisition_data; |
| 182 | 183 | ||
| 183 | ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_assoc_cmd, | 184 | ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_assoc_cmd, |
| 184 | CMD_ASYNC, sizeof(rxon_assoc), &rxon_assoc); | 185 | CMD_ASYNC, sizeof(rxon_assoc), &rxon_assoc); |
| 185 | return ret; | 186 | return ret; |
| 186 | } | 187 | } |
| @@ -266,7 +267,7 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv, | |||
| 266 | * Associated RXON doesn't clear the station table in uCode, | 267 | * Associated RXON doesn't clear the station table in uCode, |
| 267 | * so we don't need to restore stations etc. after this. | 268 | * so we don't need to restore stations etc. after this. |
| 268 | */ | 269 | */ |
| 269 | ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd, CMD_SYNC, | 270 | ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, |
| 270 | sizeof(struct iwl_rxon_cmd), &ctx->staging); | 271 | sizeof(struct iwl_rxon_cmd), &ctx->staging); |
| 271 | if (ret) { | 272 | if (ret) { |
| 272 | IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); | 273 | IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); |
| @@ -274,8 +275,6 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv, | |||
| 274 | } | 275 | } |
| 275 | memcpy(active, &ctx->staging, sizeof(*active)); | 276 | memcpy(active, &ctx->staging, sizeof(*active)); |
| 276 | 277 | ||
| 277 | iwl_reprogram_ap_sta(priv, ctx); | ||
| 278 | |||
| 279 | /* IBSS beacon needs to be sent after setting assoc */ | 278 | /* IBSS beacon needs to be sent after setting assoc */ |
| 280 | if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC)) | 279 | if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC)) |
| 281 | if (iwlagn_update_beacon(priv, ctx->vif)) | 280 | if (iwlagn_update_beacon(priv, ctx->vif)) |
| @@ -315,7 +314,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) | |||
| 315 | 314 | ||
| 316 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | 315 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); |
| 317 | 316 | ||
| 318 | lockdep_assert_held(&priv->shrd->mutex); | 317 | lockdep_assert_held(&priv->mutex); |
| 319 | 318 | ||
| 320 | ctx_bss = &priv->contexts[IWL_RXON_CTX_BSS]; | 319 | ctx_bss = &priv->contexts[IWL_RXON_CTX_BSS]; |
| 321 | ctx_pan = &priv->contexts[IWL_RXON_CTX_PAN]; | 320 | ctx_pan = &priv->contexts[IWL_RXON_CTX_PAN]; |
| @@ -362,7 +361,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) | |||
| 362 | slot0 = bcnint / 2; | 361 | slot0 = bcnint / 2; |
| 363 | slot1 = bcnint - slot0; | 362 | slot1 = bcnint - slot0; |
| 364 | 363 | ||
| 365 | if (test_bit(STATUS_SCAN_HW, &priv->shrd->status) || | 364 | if (test_bit(STATUS_SCAN_HW, &priv->status) || |
| 366 | (!ctx_bss->vif->bss_conf.idle && | 365 | (!ctx_bss->vif->bss_conf.idle && |
| 367 | !ctx_bss->vif->bss_conf.assoc)) { | 366 | !ctx_bss->vif->bss_conf.assoc)) { |
| 368 | slot0 = dtim * bcnint * 3 - IWL_MIN_SLOT_TIME; | 367 | slot0 = dtim * bcnint * 3 - IWL_MIN_SLOT_TIME; |
| @@ -378,7 +377,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) | |||
| 378 | ctx_pan->beacon_int; | 377 | ctx_pan->beacon_int; |
| 379 | slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1); | 378 | slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1); |
| 380 | 379 | ||
| 381 | if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { | 380 | if (test_bit(STATUS_SCAN_HW, &priv->status)) { |
| 382 | slot0 = slot1 * 3 - IWL_MIN_SLOT_TIME; | 381 | slot0 = slot1 * 3 - IWL_MIN_SLOT_TIME; |
| 383 | slot1 = IWL_MIN_SLOT_TIME; | 382 | slot1 = IWL_MIN_SLOT_TIME; |
| 384 | } | 383 | } |
| @@ -387,7 +386,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) | |||
| 387 | cmd.slots[0].width = cpu_to_le16(slot0); | 386 | cmd.slots[0].width = cpu_to_le16(slot0); |
| 388 | cmd.slots[1].width = cpu_to_le16(slot1); | 387 | cmd.slots[1].width = cpu_to_le16(slot1); |
| 389 | 388 | ||
| 390 | ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_WIPAN_PARAMS, CMD_SYNC, | 389 | ret = iwl_dvm_send_cmd_pdu(priv, REPLY_WIPAN_PARAMS, CMD_SYNC, |
| 391 | sizeof(cmd), &cmd); | 390 | sizeof(cmd), &cmd); |
| 392 | if (ret) | 391 | if (ret) |
| 393 | IWL_ERR(priv, "Error setting PAN parameters (%d)\n", ret); | 392 | IWL_ERR(priv, "Error setting PAN parameters (%d)\n", ret); |
| @@ -420,12 +419,9 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 420 | bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); | 419 | bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); |
| 421 | int ret; | 420 | int ret; |
| 422 | 421 | ||
| 423 | lockdep_assert_held(&priv->shrd->mutex); | 422 | lockdep_assert_held(&priv->mutex); |
| 424 | |||
| 425 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | ||
| 426 | return -EINVAL; | ||
| 427 | 423 | ||
| 428 | if (!iwl_is_alive(priv->shrd)) | 424 | if (!iwl_is_alive(priv)) |
| 429 | return -EBUSY; | 425 | return -EBUSY; |
| 430 | 426 | ||
| 431 | /* This function hardcodes a bunch of dual-mode assumptions */ | 427 | /* This function hardcodes a bunch of dual-mode assumptions */ |
| @@ -434,10 +430,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 434 | if (!ctx->is_active) | 430 | if (!ctx->is_active) |
| 435 | return 0; | 431 | return 0; |
| 436 | 432 | ||
| 437 | /* override BSSID if necessary due to preauth */ | ||
| 438 | if (ctx->preauth_bssid) | ||
| 439 | memcpy(ctx->staging.bssid_addr, ctx->bssid, ETH_ALEN); | ||
| 440 | |||
| 441 | /* always get timestamp with Rx frame */ | 433 | /* always get timestamp with Rx frame */ |
| 442 | ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; | 434 | ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; |
| 443 | 435 | ||
| @@ -445,8 +437,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 445 | * force CTS-to-self frames protection if RTS-CTS is not preferred | 437 | * force CTS-to-self frames protection if RTS-CTS is not preferred |
| 446 | * one aggregation protection method | 438 | * one aggregation protection method |
| 447 | */ | 439 | */ |
| 448 | if (!(cfg(priv)->ht_params && | 440 | if (!hw_params(priv).use_rts_for_aggregation) |
| 449 | cfg(priv)->ht_params->use_rts_for_aggregation)) | ||
| 450 | ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; | 441 | ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; |
| 451 | 442 | ||
| 452 | if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || | 443 | if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || |
| @@ -466,7 +457,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 466 | * receive commit_rxon request | 457 | * receive commit_rxon request |
| 467 | * abort any previous channel switch if still in process | 458 | * abort any previous channel switch if still in process |
| 468 | */ | 459 | */ |
| 469 | if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status) && | 460 | if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) && |
| 470 | (priv->switch_channel != ctx->staging.channel)) { | 461 | (priv->switch_channel != ctx->staging.channel)) { |
| 471 | IWL_DEBUG_11H(priv, "abort channel switch on %d\n", | 462 | IWL_DEBUG_11H(priv, "abort channel switch on %d\n", |
| 472 | le16_to_cpu(priv->switch_channel)); | 463 | le16_to_cpu(priv->switch_channel)); |
| @@ -558,17 +549,14 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
| 558 | 549 | ||
| 559 | IWL_DEBUG_MAC80211(priv, "enter: changed %#x", changed); | 550 | IWL_DEBUG_MAC80211(priv, "enter: changed %#x", changed); |
| 560 | 551 | ||
| 561 | mutex_lock(&priv->shrd->mutex); | 552 | mutex_lock(&priv->mutex); |
| 562 | |||
| 563 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | ||
| 564 | goto out; | ||
| 565 | 553 | ||
| 566 | if (unlikely(test_bit(STATUS_SCANNING, &priv->shrd->status))) { | 554 | if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) { |
| 567 | IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); | 555 | IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); |
| 568 | goto out; | 556 | goto out; |
| 569 | } | 557 | } |
| 570 | 558 | ||
| 571 | if (!iwl_is_ready(priv->shrd)) { | 559 | if (!iwl_is_ready(priv)) { |
| 572 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); | 560 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); |
| 573 | goto out; | 561 | goto out; |
| 574 | } | 562 | } |
| @@ -590,8 +578,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
| 590 | } | 578 | } |
| 591 | 579 | ||
| 592 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 580 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
| 593 | unsigned long flags; | ||
| 594 | |||
| 595 | ch_info = iwl_get_channel_info(priv, channel->band, | 581 | ch_info = iwl_get_channel_info(priv, channel->band, |
| 596 | channel->hw_value); | 582 | channel->hw_value); |
| 597 | if (!is_channel_valid(ch_info)) { | 583 | if (!is_channel_valid(ch_info)) { |
| @@ -600,8 +586,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
| 600 | goto out; | 586 | goto out; |
| 601 | } | 587 | } |
| 602 | 588 | ||
| 603 | spin_lock_irqsave(&priv->shrd->lock, flags); | ||
| 604 | |||
| 605 | for_each_context(priv, ctx) { | 589 | for_each_context(priv, ctx) { |
| 606 | /* Configure HT40 channels */ | 590 | /* Configure HT40 channels */ |
| 607 | if (ctx->ht.enabled != conf_is_ht(conf)) | 591 | if (ctx->ht.enabled != conf_is_ht(conf)) |
| @@ -636,8 +620,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
| 636 | ctx->vif); | 620 | ctx->vif); |
| 637 | } | 621 | } |
| 638 | 622 | ||
| 639 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | ||
| 640 | |||
| 641 | iwl_update_bcast_stations(priv); | 623 | iwl_update_bcast_stations(priv); |
| 642 | 624 | ||
| 643 | /* | 625 | /* |
| @@ -668,7 +650,7 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
| 668 | iwlagn_commit_rxon(priv, ctx); | 650 | iwlagn_commit_rxon(priv, ctx); |
| 669 | } | 651 | } |
| 670 | out: | 652 | out: |
| 671 | mutex_unlock(&priv->shrd->mutex); | 653 | mutex_unlock(&priv->mutex); |
| 672 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 654 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
| 673 | 655 | ||
| 674 | return ret; | 656 | return ret; |
| @@ -685,7 +667,7 @@ static void iwlagn_check_needed_chains(struct iwl_priv *priv, | |||
| 685 | struct ieee80211_sta_ht_cap *ht_cap; | 667 | struct ieee80211_sta_ht_cap *ht_cap; |
| 686 | bool need_multiple; | 668 | bool need_multiple; |
| 687 | 669 | ||
| 688 | lockdep_assert_held(&priv->shrd->mutex); | 670 | lockdep_assert_held(&priv->mutex); |
| 689 | 671 | ||
| 690 | switch (vif->type) { | 672 | switch (vif->type) { |
| 691 | case NL80211_IFTYPE_STATION: | 673 | case NL80211_IFTYPE_STATION: |
| @@ -789,7 +771,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv) | |||
| 789 | memset(&cmd, 0, sizeof(cmd)); | 771 | memset(&cmd, 0, sizeof(cmd)); |
| 790 | iwl_set_calib_hdr(&cmd.hdr, | 772 | iwl_set_calib_hdr(&cmd.hdr, |
| 791 | priv->phy_calib_chain_noise_reset_cmd); | 773 | priv->phy_calib_chain_noise_reset_cmd); |
| 792 | ret = iwl_trans_send_cmd_pdu(trans(priv), | 774 | ret = iwl_dvm_send_cmd_pdu(priv, |
| 793 | REPLY_PHY_CALIBRATION_CMD, | 775 | REPLY_PHY_CALIBRATION_CMD, |
| 794 | CMD_SYNC, sizeof(cmd), &cmd); | 776 | CMD_SYNC, sizeof(cmd), &cmd); |
| 795 | if (ret) | 777 | if (ret) |
| @@ -810,17 +792,17 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
| 810 | int ret; | 792 | int ret; |
| 811 | bool force = false; | 793 | bool force = false; |
| 812 | 794 | ||
| 813 | mutex_lock(&priv->shrd->mutex); | 795 | mutex_lock(&priv->mutex); |
| 814 | 796 | ||
| 815 | if (unlikely(!iwl_is_ready(priv->shrd))) { | 797 | if (unlikely(!iwl_is_ready(priv))) { |
| 816 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); | 798 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); |
| 817 | mutex_unlock(&priv->shrd->mutex); | 799 | mutex_unlock(&priv->mutex); |
| 818 | return; | 800 | return; |
| 819 | } | 801 | } |
| 820 | 802 | ||
| 821 | if (unlikely(!ctx->vif)) { | 803 | if (unlikely(!ctx->vif)) { |
| 822 | IWL_DEBUG_MAC80211(priv, "leave - vif is NULL\n"); | 804 | IWL_DEBUG_MAC80211(priv, "leave - vif is NULL\n"); |
| 823 | mutex_unlock(&priv->shrd->mutex); | 805 | mutex_unlock(&priv->mutex); |
| 824 | return; | 806 | return; |
| 825 | } | 807 | } |
| 826 | 808 | ||
| @@ -851,12 +833,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
| 851 | * not get stuck in this case either since it | 833 | * not get stuck in this case either since it |
| 852 | * can happen if userspace gets confused. | 834 | * can happen if userspace gets confused. |
| 853 | */ | 835 | */ |
| 854 | if (ctx->last_tx_rejected) { | 836 | iwlagn_lift_passive_no_rx(priv); |
| 855 | ctx->last_tx_rejected = false; | 837 | |
| 856 | iwl_trans_wake_any_queue(trans(priv), | ||
| 857 | ctx->ctxid, | ||
| 858 | "Disassoc: flush queue"); | ||
| 859 | } | ||
| 860 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 838 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
| 861 | 839 | ||
| 862 | if (ctx->ctxid == IWL_RXON_CTX_BSS) | 840 | if (ctx->ctxid == IWL_RXON_CTX_BSS) |
| @@ -932,7 +910,6 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
| 932 | if (!priv->disable_chain_noise_cal) | 910 | if (!priv->disable_chain_noise_cal) |
| 933 | iwlagn_chain_noise_reset(priv); | 911 | iwlagn_chain_noise_reset(priv); |
| 934 | priv->start_calib = 1; | 912 | priv->start_calib = 1; |
| 935 | WARN_ON(ctx->preauth_bssid); | ||
| 936 | } | 913 | } |
| 937 | 914 | ||
| 938 | if (changes & BSS_CHANGED_IBSS) { | 915 | if (changes & BSS_CHANGED_IBSS) { |
| @@ -950,7 +927,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
| 950 | IWL_ERR(priv, "Error sending IBSS beacon\n"); | 927 | IWL_ERR(priv, "Error sending IBSS beacon\n"); |
| 951 | } | 928 | } |
| 952 | 929 | ||
| 953 | mutex_unlock(&priv->shrd->mutex); | 930 | mutex_unlock(&priv->mutex); |
| 954 | } | 931 | } |
| 955 | 932 | ||
| 956 | void iwlagn_post_scan(struct iwl_priv *priv) | 933 | void iwlagn_post_scan(struct iwl_priv *priv) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index f1298cd6a19a..c4175603864b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | 26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 |
| 27 | * | 27 | * |
| 28 | *****************************************************************************/ | 28 | *****************************************************************************/ |
| 29 | 29 | #include <linux/etherdevice.h> | |
| 30 | #include <net/mac80211.h> | 30 | #include <net/mac80211.h> |
| 31 | 31 | ||
| 32 | #include "iwl-dev.h" | 32 | #include "iwl-dev.h" |
| @@ -34,9 +34,10 @@ | |||
| 34 | #include "iwl-agn.h" | 34 | #include "iwl-agn.h" |
| 35 | #include "iwl-trans.h" | 35 | #include "iwl-trans.h" |
| 36 | 36 | ||
| 37 | /* priv->shrd->sta_lock must be held */ | ||
| 38 | static int iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) | 37 | static int iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) |
| 39 | { | 38 | { |
| 39 | lockdep_assert_held(&priv->sta_lock); | ||
| 40 | |||
| 40 | if (sta_id >= IWLAGN_STATION_COUNT) { | 41 | if (sta_id >= IWLAGN_STATION_COUNT) { |
| 41 | IWL_ERR(priv, "invalid sta_id %u", sta_id); | 42 | IWL_ERR(priv, "invalid sta_id %u", sta_id); |
| 42 | return -EINVAL; | 43 | return -EINVAL; |
| @@ -63,8 +64,8 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, | |||
| 63 | struct iwl_addsta_cmd *addsta, | 64 | struct iwl_addsta_cmd *addsta, |
| 64 | struct iwl_rx_packet *pkt) | 65 | struct iwl_rx_packet *pkt) |
| 65 | { | 66 | { |
| 67 | struct iwl_add_sta_resp *add_sta_resp = (void *)pkt->data; | ||
| 66 | u8 sta_id = addsta->sta.sta_id; | 68 | u8 sta_id = addsta->sta.sta_id; |
| 67 | unsigned long flags; | ||
| 68 | int ret = -EIO; | 69 | int ret = -EIO; |
| 69 | 70 | ||
| 70 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { | 71 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { |
| @@ -76,9 +77,9 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, | |||
| 76 | IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n", | 77 | IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n", |
| 77 | sta_id); | 78 | sta_id); |
| 78 | 79 | ||
| 79 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 80 | spin_lock(&priv->sta_lock); |
| 80 | 81 | ||
| 81 | switch (pkt->u.add_sta.status) { | 82 | switch (add_sta_resp->status) { |
| 82 | case ADD_STA_SUCCESS_MSK: | 83 | case ADD_STA_SUCCESS_MSK: |
| 83 | IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n"); | 84 | IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n"); |
| 84 | ret = iwl_sta_ucode_activate(priv, sta_id); | 85 | ret = iwl_sta_ucode_activate(priv, sta_id); |
| @@ -97,7 +98,7 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, | |||
| 97 | break; | 98 | break; |
| 98 | default: | 99 | default: |
| 99 | IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n", | 100 | IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n", |
| 100 | pkt->u.add_sta.status); | 101 | add_sta_resp->status); |
| 101 | break; | 102 | break; |
| 102 | } | 103 | } |
| 103 | 104 | ||
| @@ -118,12 +119,12 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, | |||
| 118 | priv->stations[sta_id].sta.mode == | 119 | priv->stations[sta_id].sta.mode == |
| 119 | STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", | 120 | STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", |
| 120 | addsta->sta.addr); | 121 | addsta->sta.addr); |
| 121 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 122 | spin_unlock(&priv->sta_lock); |
| 122 | 123 | ||
| 123 | return ret; | 124 | return ret; |
| 124 | } | 125 | } |
| 125 | 126 | ||
| 126 | int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | 127 | int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, |
| 127 | struct iwl_device_cmd *cmd) | 128 | struct iwl_device_cmd *cmd) |
| 128 | { | 129 | { |
| 129 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 130 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| @@ -153,14 +154,14 @@ int iwl_send_add_sta(struct iwl_priv *priv, | |||
| 153 | might_sleep(); | 154 | might_sleep(); |
| 154 | } | 155 | } |
| 155 | 156 | ||
| 156 | ret = iwl_trans_send_cmd(trans(priv), &cmd); | 157 | ret = iwl_dvm_send_cmd(priv, &cmd); |
| 157 | 158 | ||
| 158 | if (ret || (flags & CMD_ASYNC)) | 159 | if (ret || (flags & CMD_ASYNC)) |
| 159 | return ret; | 160 | return ret; |
| 160 | /*else the command was successfully sent in SYNC mode, need to free | 161 | /*else the command was successfully sent in SYNC mode, need to free |
| 161 | * the reply page */ | 162 | * the reply page */ |
| 162 | 163 | ||
| 163 | iwl_free_pages(priv->shrd, cmd.reply_page); | 164 | iwl_free_resp(&cmd); |
| 164 | 165 | ||
| 165 | if (cmd.handler_status) | 166 | if (cmd.handler_status) |
| 166 | IWL_ERR(priv, "%s - error in the CMD response %d", __func__, | 167 | IWL_ERR(priv, "%s - error in the CMD response %d", __func__, |
| @@ -169,34 +170,38 @@ int iwl_send_add_sta(struct iwl_priv *priv, | |||
| 169 | return cmd.handler_status; | 170 | return cmd.handler_status; |
| 170 | } | 171 | } |
| 171 | 172 | ||
| 172 | static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, | 173 | static void iwl_sta_calc_ht_flags(struct iwl_priv *priv, |
| 173 | struct ieee80211_sta *sta, | 174 | struct ieee80211_sta *sta, |
| 174 | struct iwl_rxon_context *ctx) | 175 | struct iwl_rxon_context *ctx, |
| 176 | __le32 *flags, __le32 *mask) | ||
| 175 | { | 177 | { |
| 176 | struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap; | 178 | struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap; |
| 177 | __le32 sta_flags; | ||
| 178 | u8 mimo_ps_mode; | 179 | u8 mimo_ps_mode; |
| 179 | 180 | ||
| 181 | *mask = STA_FLG_RTS_MIMO_PROT_MSK | | ||
| 182 | STA_FLG_MIMO_DIS_MSK | | ||
| 183 | STA_FLG_HT40_EN_MSK | | ||
| 184 | STA_FLG_MAX_AGG_SIZE_MSK | | ||
| 185 | STA_FLG_AGG_MPDU_DENSITY_MSK; | ||
| 186 | *flags = 0; | ||
| 187 | |||
| 180 | if (!sta || !sta_ht_inf->ht_supported) | 188 | if (!sta || !sta_ht_inf->ht_supported) |
| 181 | goto done; | 189 | return; |
| 182 | 190 | ||
| 183 | mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2; | 191 | mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2; |
| 184 | IWL_DEBUG_ASSOC(priv, "spatial multiplexing power save mode: %s\n", | 192 | |
| 193 | IWL_DEBUG_INFO(priv, "STA %pM SM PS mode: %s\n", | ||
| 185 | (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ? | 194 | (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ? |
| 186 | "static" : | 195 | "static" : |
| 187 | (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ? | 196 | (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ? |
| 188 | "dynamic" : "disabled"); | 197 | "dynamic" : "disabled"); |
| 189 | 198 | ||
| 190 | sta_flags = priv->stations[index].sta.station_flags; | ||
| 191 | |||
| 192 | sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK); | ||
| 193 | |||
| 194 | switch (mimo_ps_mode) { | 199 | switch (mimo_ps_mode) { |
| 195 | case WLAN_HT_CAP_SM_PS_STATIC: | 200 | case WLAN_HT_CAP_SM_PS_STATIC: |
| 196 | sta_flags |= STA_FLG_MIMO_DIS_MSK; | 201 | *flags |= STA_FLG_MIMO_DIS_MSK; |
| 197 | break; | 202 | break; |
| 198 | case WLAN_HT_CAP_SM_PS_DYNAMIC: | 203 | case WLAN_HT_CAP_SM_PS_DYNAMIC: |
| 199 | sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK; | 204 | *flags |= STA_FLG_RTS_MIMO_PROT_MSK; |
| 200 | break; | 205 | break; |
| 201 | case WLAN_HT_CAP_SM_PS_DISABLED: | 206 | case WLAN_HT_CAP_SM_PS_DISABLED: |
| 202 | break; | 207 | break; |
| @@ -205,20 +210,53 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, | |||
| 205 | break; | 210 | break; |
| 206 | } | 211 | } |
| 207 | 212 | ||
| 208 | sta_flags |= cpu_to_le32( | 213 | *flags |= cpu_to_le32( |
| 209 | (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS); | 214 | (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS); |
| 210 | 215 | ||
| 211 | sta_flags |= cpu_to_le32( | 216 | *flags |= cpu_to_le32( |
| 212 | (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); | 217 | (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); |
| 213 | 218 | ||
| 214 | if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap)) | 219 | if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap)) |
| 215 | sta_flags |= STA_FLG_HT40_EN_MSK; | 220 | *flags |= STA_FLG_HT40_EN_MSK; |
| 216 | else | 221 | } |
| 217 | sta_flags &= ~STA_FLG_HT40_EN_MSK; | ||
| 218 | 222 | ||
| 219 | priv->stations[index].sta.station_flags = sta_flags; | 223 | int iwl_sta_update_ht(struct iwl_priv *priv, struct iwl_rxon_context *ctx, |
| 220 | done: | 224 | struct ieee80211_sta *sta) |
| 221 | return; | 225 | { |
| 226 | u8 sta_id = iwl_sta_id(sta); | ||
| 227 | __le32 flags, mask; | ||
| 228 | struct iwl_addsta_cmd cmd; | ||
| 229 | |||
| 230 | if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION)) | ||
| 231 | return -EINVAL; | ||
| 232 | |||
| 233 | iwl_sta_calc_ht_flags(priv, sta, ctx, &flags, &mask); | ||
| 234 | |||
| 235 | spin_lock_bh(&priv->sta_lock); | ||
| 236 | priv->stations[sta_id].sta.station_flags &= ~mask; | ||
| 237 | priv->stations[sta_id].sta.station_flags |= flags; | ||
| 238 | spin_unlock_bh(&priv->sta_lock); | ||
| 239 | |||
| 240 | memset(&cmd, 0, sizeof(cmd)); | ||
| 241 | cmd.mode = STA_CONTROL_MODIFY_MSK; | ||
| 242 | cmd.station_flags_msk = mask; | ||
| 243 | cmd.station_flags = flags; | ||
| 244 | cmd.sta.sta_id = sta_id; | ||
| 245 | |||
| 246 | return iwl_send_add_sta(priv, &cmd, CMD_SYNC); | ||
| 247 | } | ||
| 248 | |||
| 249 | static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, | ||
| 250 | struct ieee80211_sta *sta, | ||
| 251 | struct iwl_rxon_context *ctx) | ||
| 252 | { | ||
| 253 | __le32 flags, mask; | ||
| 254 | |||
| 255 | iwl_sta_calc_ht_flags(priv, sta, ctx, &flags, &mask); | ||
| 256 | |||
| 257 | lockdep_assert_held(&priv->sta_lock); | ||
| 258 | priv->stations[index].sta.station_flags &= ~mask; | ||
| 259 | priv->stations[index].sta.station_flags |= flags; | ||
| 222 | } | 260 | } |
| 223 | 261 | ||
| 224 | /** | 262 | /** |
| @@ -317,18 +355,17 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
| 317 | const u8 *addr, bool is_ap, | 355 | const u8 *addr, bool is_ap, |
| 318 | struct ieee80211_sta *sta, u8 *sta_id_r) | 356 | struct ieee80211_sta *sta, u8 *sta_id_r) |
| 319 | { | 357 | { |
| 320 | unsigned long flags_spin; | ||
| 321 | int ret = 0; | 358 | int ret = 0; |
| 322 | u8 sta_id; | 359 | u8 sta_id; |
| 323 | struct iwl_addsta_cmd sta_cmd; | 360 | struct iwl_addsta_cmd sta_cmd; |
| 324 | 361 | ||
| 325 | *sta_id_r = 0; | 362 | *sta_id_r = 0; |
| 326 | spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); | 363 | spin_lock_bh(&priv->sta_lock); |
| 327 | sta_id = iwl_prep_station(priv, ctx, addr, is_ap, sta); | 364 | sta_id = iwl_prep_station(priv, ctx, addr, is_ap, sta); |
| 328 | if (sta_id == IWL_INVALID_STATION) { | 365 | if (sta_id == IWL_INVALID_STATION) { |
| 329 | IWL_ERR(priv, "Unable to prepare station %pM for addition\n", | 366 | IWL_ERR(priv, "Unable to prepare station %pM for addition\n", |
| 330 | addr); | 367 | addr); |
| 331 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); | 368 | spin_unlock_bh(&priv->sta_lock); |
| 332 | return -EINVAL; | 369 | return -EINVAL; |
| 333 | } | 370 | } |
| 334 | 371 | ||
| @@ -340,7 +377,7 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
| 340 | if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) { | 377 | if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) { |
| 341 | IWL_DEBUG_INFO(priv, "STA %d already in process of being " | 378 | IWL_DEBUG_INFO(priv, "STA %d already in process of being " |
| 342 | "added.\n", sta_id); | 379 | "added.\n", sta_id); |
| 343 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); | 380 | spin_unlock_bh(&priv->sta_lock); |
| 344 | return -EEXIST; | 381 | return -EEXIST; |
| 345 | } | 382 | } |
| 346 | 383 | ||
| @@ -348,24 +385,24 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
| 348 | (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) { | 385 | (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) { |
| 349 | IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not " | 386 | IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not " |
| 350 | "adding again.\n", sta_id, addr); | 387 | "adding again.\n", sta_id, addr); |
| 351 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); | 388 | spin_unlock_bh(&priv->sta_lock); |
| 352 | return -EEXIST; | 389 | return -EEXIST; |
| 353 | } | 390 | } |
| 354 | 391 | ||
| 355 | priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS; | 392 | priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS; |
| 356 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, | 393 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, |
| 357 | sizeof(struct iwl_addsta_cmd)); | 394 | sizeof(struct iwl_addsta_cmd)); |
| 358 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); | 395 | spin_unlock_bh(&priv->sta_lock); |
| 359 | 396 | ||
| 360 | /* Add station to device's station table */ | 397 | /* Add station to device's station table */ |
| 361 | ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); | 398 | ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); |
| 362 | if (ret) { | 399 | if (ret) { |
| 363 | spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); | 400 | spin_lock_bh(&priv->sta_lock); |
| 364 | IWL_ERR(priv, "Adding station %pM failed.\n", | 401 | IWL_ERR(priv, "Adding station %pM failed.\n", |
| 365 | priv->stations[sta_id].sta.sta.addr); | 402 | priv->stations[sta_id].sta.sta.addr); |
| 366 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; | 403 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; |
| 367 | priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; | 404 | priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; |
| 368 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); | 405 | spin_unlock_bh(&priv->sta_lock); |
| 369 | } | 406 | } |
| 370 | *sta_id_r = sta_id; | 407 | *sta_id_r = sta_id; |
| 371 | return ret; | 408 | return ret; |
| @@ -373,11 +410,11 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
| 373 | 410 | ||
| 374 | /** | 411 | /** |
| 375 | * iwl_sta_ucode_deactivate - deactivate ucode status for a station | 412 | * iwl_sta_ucode_deactivate - deactivate ucode status for a station |
| 376 | * | ||
| 377 | * priv->shrd->sta_lock must be held | ||
| 378 | */ | 413 | */ |
| 379 | static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id) | 414 | static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id) |
| 380 | { | 415 | { |
| 416 | lockdep_assert_held(&priv->sta_lock); | ||
| 417 | |||
| 381 | /* Ucode must be active and driver must be non active */ | 418 | /* Ucode must be active and driver must be non active */ |
| 382 | if ((priv->stations[sta_id].used & | 419 | if ((priv->stations[sta_id].used & |
| 383 | (IWL_STA_UCODE_ACTIVE | IWL_STA_DRIVER_ACTIVE)) != | 420 | (IWL_STA_UCODE_ACTIVE | IWL_STA_DRIVER_ACTIVE)) != |
| @@ -396,8 +433,6 @@ static int iwl_send_remove_station(struct iwl_priv *priv, | |||
| 396 | { | 433 | { |
| 397 | struct iwl_rx_packet *pkt; | 434 | struct iwl_rx_packet *pkt; |
| 398 | int ret; | 435 | int ret; |
| 399 | |||
| 400 | unsigned long flags_spin; | ||
| 401 | struct iwl_rem_sta_cmd rm_sta_cmd; | 436 | struct iwl_rem_sta_cmd rm_sta_cmd; |
| 402 | 437 | ||
| 403 | struct iwl_host_cmd cmd = { | 438 | struct iwl_host_cmd cmd = { |
| @@ -413,12 +448,12 @@ static int iwl_send_remove_station(struct iwl_priv *priv, | |||
| 413 | 448 | ||
| 414 | cmd.flags |= CMD_WANT_SKB; | 449 | cmd.flags |= CMD_WANT_SKB; |
| 415 | 450 | ||
| 416 | ret = iwl_trans_send_cmd(trans(priv), &cmd); | 451 | ret = iwl_dvm_send_cmd(priv, &cmd); |
| 417 | 452 | ||
| 418 | if (ret) | 453 | if (ret) |
| 419 | return ret; | 454 | return ret; |
| 420 | 455 | ||
| 421 | pkt = (struct iwl_rx_packet *)cmd.reply_page; | 456 | pkt = cmd.resp_pkt; |
| 422 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { | 457 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { |
| 423 | IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", | 458 | IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", |
| 424 | pkt->hdr.flags); | 459 | pkt->hdr.flags); |
| @@ -426,14 +461,13 @@ static int iwl_send_remove_station(struct iwl_priv *priv, | |||
| 426 | } | 461 | } |
| 427 | 462 | ||
| 428 | if (!ret) { | 463 | if (!ret) { |
| 429 | switch (pkt->u.rem_sta.status) { | 464 | struct iwl_rem_sta_resp *rem_sta_resp = (void *)pkt->data; |
| 465 | switch (rem_sta_resp->status) { | ||
| 430 | case REM_STA_SUCCESS_MSK: | 466 | case REM_STA_SUCCESS_MSK: |
| 431 | if (!temporary) { | 467 | if (!temporary) { |
| 432 | spin_lock_irqsave(&priv->shrd->sta_lock, | 468 | spin_lock_bh(&priv->sta_lock); |
| 433 | flags_spin); | ||
| 434 | iwl_sta_ucode_deactivate(priv, sta_id); | 469 | iwl_sta_ucode_deactivate(priv, sta_id); |
| 435 | spin_unlock_irqrestore(&priv->shrd->sta_lock, | 470 | spin_unlock_bh(&priv->sta_lock); |
| 436 | flags_spin); | ||
| 437 | } | 471 | } |
| 438 | IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); | 472 | IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); |
| 439 | break; | 473 | break; |
| @@ -443,7 +477,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, | |||
| 443 | break; | 477 | break; |
| 444 | } | 478 | } |
| 445 | } | 479 | } |
| 446 | iwl_free_pages(priv->shrd, cmd.reply_page); | 480 | iwl_free_resp(&cmd); |
| 447 | 481 | ||
| 448 | return ret; | 482 | return ret; |
| 449 | } | 483 | } |
| @@ -454,10 +488,9 @@ static int iwl_send_remove_station(struct iwl_priv *priv, | |||
| 454 | int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, | 488 | int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, |
| 455 | const u8 *addr) | 489 | const u8 *addr) |
| 456 | { | 490 | { |
| 457 | unsigned long flags; | ||
| 458 | u8 tid; | 491 | u8 tid; |
| 459 | 492 | ||
| 460 | if (!iwl_is_ready(priv->shrd)) { | 493 | if (!iwl_is_ready(priv)) { |
| 461 | IWL_DEBUG_INFO(priv, | 494 | IWL_DEBUG_INFO(priv, |
| 462 | "Unable to remove station %pM, device not ready.\n", | 495 | "Unable to remove station %pM, device not ready.\n", |
| 463 | addr); | 496 | addr); |
| @@ -475,7 +508,7 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, | |||
| 475 | if (WARN_ON(sta_id == IWL_INVALID_STATION)) | 508 | if (WARN_ON(sta_id == IWL_INVALID_STATION)) |
| 476 | return -EINVAL; | 509 | return -EINVAL; |
| 477 | 510 | ||
| 478 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 511 | spin_lock_bh(&priv->sta_lock); |
| 479 | 512 | ||
| 480 | if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { | 513 | if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { |
| 481 | IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n", | 514 | IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n", |
| @@ -505,14 +538,49 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, | |||
| 505 | if (WARN_ON(priv->num_stations < 0)) | 538 | if (WARN_ON(priv->num_stations < 0)) |
| 506 | priv->num_stations = 0; | 539 | priv->num_stations = 0; |
| 507 | 540 | ||
| 508 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 541 | spin_unlock_bh(&priv->sta_lock); |
| 509 | 542 | ||
| 510 | return iwl_send_remove_station(priv, addr, sta_id, false); | 543 | return iwl_send_remove_station(priv, addr, sta_id, false); |
| 511 | out_err: | 544 | out_err: |
| 512 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 545 | spin_unlock_bh(&priv->sta_lock); |
| 513 | return -EINVAL; | 546 | return -EINVAL; |
| 514 | } | 547 | } |
| 515 | 548 | ||
| 549 | void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id, | ||
| 550 | const u8 *addr) | ||
| 551 | { | ||
| 552 | u8 tid; | ||
| 553 | |||
| 554 | if (!iwl_is_ready(priv)) { | ||
| 555 | IWL_DEBUG_INFO(priv, | ||
| 556 | "Unable to remove station %pM, device not ready.\n", | ||
| 557 | addr); | ||
| 558 | return; | ||
| 559 | } | ||
| 560 | |||
| 561 | IWL_DEBUG_ASSOC(priv, "Deactivating STA: %pM (%d)\n", addr, sta_id); | ||
| 562 | |||
| 563 | if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION)) | ||
| 564 | return; | ||
| 565 | |||
| 566 | spin_lock_bh(&priv->sta_lock); | ||
| 567 | |||
| 568 | WARN_ON_ONCE(!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)); | ||
| 569 | |||
| 570 | for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) | ||
| 571 | memset(&priv->tid_data[sta_id][tid], 0, | ||
| 572 | sizeof(priv->tid_data[sta_id][tid])); | ||
| 573 | |||
| 574 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; | ||
| 575 | |||
| 576 | priv->num_stations--; | ||
| 577 | |||
| 578 | if (WARN_ON_ONCE(priv->num_stations < 0)) | ||
| 579 | priv->num_stations = 0; | ||
| 580 | |||
| 581 | spin_unlock_bh(&priv->sta_lock); | ||
| 582 | } | ||
| 583 | |||
| 516 | /** | 584 | /** |
| 517 | * iwl_clear_ucode_stations - clear ucode station table bits | 585 | * iwl_clear_ucode_stations - clear ucode station table bits |
| 518 | * | 586 | * |
| @@ -525,12 +593,11 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv, | |||
| 525 | struct iwl_rxon_context *ctx) | 593 | struct iwl_rxon_context *ctx) |
| 526 | { | 594 | { |
| 527 | int i; | 595 | int i; |
| 528 | unsigned long flags_spin; | ||
| 529 | bool cleared = false; | 596 | bool cleared = false; |
| 530 | 597 | ||
| 531 | IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver\n"); | 598 | IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver\n"); |
| 532 | 599 | ||
| 533 | spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); | 600 | spin_lock_bh(&priv->sta_lock); |
| 534 | for (i = 0; i < IWLAGN_STATION_COUNT; i++) { | 601 | for (i = 0; i < IWLAGN_STATION_COUNT; i++) { |
| 535 | if (ctx && ctx->ctxid != priv->stations[i].ctxid) | 602 | if (ctx && ctx->ctxid != priv->stations[i].ctxid) |
| 536 | continue; | 603 | continue; |
| @@ -542,7 +609,7 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv, | |||
| 542 | cleared = true; | 609 | cleared = true; |
| 543 | } | 610 | } |
| 544 | } | 611 | } |
| 545 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); | 612 | spin_unlock_bh(&priv->sta_lock); |
| 546 | 613 | ||
| 547 | if (!cleared) | 614 | if (!cleared) |
| 548 | IWL_DEBUG_INFO(priv, | 615 | IWL_DEBUG_INFO(priv, |
| @@ -561,20 +628,19 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 561 | { | 628 | { |
| 562 | struct iwl_addsta_cmd sta_cmd; | 629 | struct iwl_addsta_cmd sta_cmd; |
| 563 | struct iwl_link_quality_cmd lq; | 630 | struct iwl_link_quality_cmd lq; |
| 564 | unsigned long flags_spin; | ||
| 565 | int i; | 631 | int i; |
| 566 | bool found = false; | 632 | bool found = false; |
| 567 | int ret; | 633 | int ret; |
| 568 | bool send_lq; | 634 | bool send_lq; |
| 569 | 635 | ||
| 570 | if (!iwl_is_ready(priv->shrd)) { | 636 | if (!iwl_is_ready(priv)) { |
| 571 | IWL_DEBUG_INFO(priv, | 637 | IWL_DEBUG_INFO(priv, |
| 572 | "Not ready yet, not restoring any stations.\n"); | 638 | "Not ready yet, not restoring any stations.\n"); |
| 573 | return; | 639 | return; |
| 574 | } | 640 | } |
| 575 | 641 | ||
| 576 | IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n"); | 642 | IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n"); |
| 577 | spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); | 643 | spin_lock_bh(&priv->sta_lock); |
| 578 | for (i = 0; i < IWLAGN_STATION_COUNT; i++) { | 644 | for (i = 0; i < IWLAGN_STATION_COUNT; i++) { |
| 579 | if (ctx->ctxid != priv->stations[i].ctxid) | 645 | if (ctx->ctxid != priv->stations[i].ctxid) |
| 580 | continue; | 646 | continue; |
| @@ -594,27 +660,24 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 594 | sizeof(struct iwl_addsta_cmd)); | 660 | sizeof(struct iwl_addsta_cmd)); |
| 595 | send_lq = false; | 661 | send_lq = false; |
| 596 | if (priv->stations[i].lq) { | 662 | if (priv->stations[i].lq) { |
| 597 | if (priv->shrd->wowlan) | 663 | if (priv->wowlan) |
| 598 | iwl_sta_fill_lq(priv, ctx, i, &lq); | 664 | iwl_sta_fill_lq(priv, ctx, i, &lq); |
| 599 | else | 665 | else |
| 600 | memcpy(&lq, priv->stations[i].lq, | 666 | memcpy(&lq, priv->stations[i].lq, |
| 601 | sizeof(struct iwl_link_quality_cmd)); | 667 | sizeof(struct iwl_link_quality_cmd)); |
| 602 | send_lq = true; | 668 | send_lq = true; |
| 603 | } | 669 | } |
| 604 | spin_unlock_irqrestore(&priv->shrd->sta_lock, | 670 | spin_unlock_bh(&priv->sta_lock); |
| 605 | flags_spin); | ||
| 606 | ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); | 671 | ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); |
| 607 | if (ret) { | 672 | if (ret) { |
| 608 | spin_lock_irqsave(&priv->shrd->sta_lock, | 673 | spin_lock_bh(&priv->sta_lock); |
| 609 | flags_spin); | ||
| 610 | IWL_ERR(priv, "Adding station %pM failed.\n", | 674 | IWL_ERR(priv, "Adding station %pM failed.\n", |
| 611 | priv->stations[i].sta.sta.addr); | 675 | priv->stations[i].sta.sta.addr); |
| 612 | priv->stations[i].used &= | 676 | priv->stations[i].used &= |
| 613 | ~IWL_STA_DRIVER_ACTIVE; | 677 | ~IWL_STA_DRIVER_ACTIVE; |
| 614 | priv->stations[i].used &= | 678 | priv->stations[i].used &= |
| 615 | ~IWL_STA_UCODE_INPROGRESS; | 679 | ~IWL_STA_UCODE_INPROGRESS; |
| 616 | spin_unlock_irqrestore(&priv->shrd->sta_lock, | 680 | spin_unlock_bh(&priv->sta_lock); |
| 617 | flags_spin); | ||
| 618 | } | 681 | } |
| 619 | /* | 682 | /* |
| 620 | * Rate scaling has already been initialized, send | 683 | * Rate scaling has already been initialized, send |
| @@ -623,12 +686,12 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 623 | if (send_lq) | 686 | if (send_lq) |
| 624 | iwl_send_lq_cmd(priv, ctx, &lq, | 687 | iwl_send_lq_cmd(priv, ctx, &lq, |
| 625 | CMD_SYNC, true); | 688 | CMD_SYNC, true); |
| 626 | spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); | 689 | spin_lock_bh(&priv->sta_lock); |
| 627 | priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; | 690 | priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; |
| 628 | } | 691 | } |
| 629 | } | 692 | } |
| 630 | 693 | ||
| 631 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); | 694 | spin_unlock_bh(&priv->sta_lock); |
| 632 | if (!found) | 695 | if (!found) |
| 633 | IWL_DEBUG_INFO(priv, "Restoring all known stations .... " | 696 | IWL_DEBUG_INFO(priv, "Restoring all known stations .... " |
| 634 | "no stations to be restored.\n"); | 697 | "no stations to be restored.\n"); |
| @@ -637,52 +700,6 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 637 | "complete.\n"); | 700 | "complete.\n"); |
| 638 | } | 701 | } |
| 639 | 702 | ||
| 640 | void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | ||
| 641 | { | ||
| 642 | unsigned long flags; | ||
| 643 | int sta_id = ctx->ap_sta_id; | ||
| 644 | int ret; | ||
| 645 | struct iwl_addsta_cmd sta_cmd; | ||
| 646 | struct iwl_link_quality_cmd lq; | ||
| 647 | bool active, have_lq = false; | ||
| 648 | |||
| 649 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | ||
| 650 | if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { | ||
| 651 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
| 652 | return; | ||
| 653 | } | ||
| 654 | |||
| 655 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); | ||
| 656 | sta_cmd.mode = 0; | ||
| 657 | if (priv->stations[sta_id].lq) { | ||
| 658 | memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq)); | ||
| 659 | have_lq = true; | ||
| 660 | } | ||
| 661 | |||
| 662 | active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE; | ||
| 663 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; | ||
| 664 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
| 665 | |||
| 666 | if (active) { | ||
| 667 | ret = iwl_send_remove_station( | ||
| 668 | priv, priv->stations[sta_id].sta.sta.addr, | ||
| 669 | sta_id, true); | ||
| 670 | if (ret) | ||
| 671 | IWL_ERR(priv, "failed to remove STA %pM (%d)\n", | ||
| 672 | priv->stations[sta_id].sta.sta.addr, ret); | ||
| 673 | } | ||
| 674 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | ||
| 675 | priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; | ||
| 676 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
| 677 | |||
| 678 | ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); | ||
| 679 | if (ret) | ||
| 680 | IWL_ERR(priv, "failed to re-add STA %pM (%d)\n", | ||
| 681 | priv->stations[sta_id].sta.sta.addr, ret); | ||
| 682 | if (have_lq) | ||
| 683 | iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true); | ||
| 684 | } | ||
| 685 | |||
| 686 | int iwl_get_free_ucode_key_offset(struct iwl_priv *priv) | 703 | int iwl_get_free_ucode_key_offset(struct iwl_priv *priv) |
| 687 | { | 704 | { |
| 688 | int i; | 705 | int i; |
| @@ -696,10 +713,9 @@ int iwl_get_free_ucode_key_offset(struct iwl_priv *priv) | |||
| 696 | 713 | ||
| 697 | void iwl_dealloc_bcast_stations(struct iwl_priv *priv) | 714 | void iwl_dealloc_bcast_stations(struct iwl_priv *priv) |
| 698 | { | 715 | { |
| 699 | unsigned long flags; | ||
| 700 | int i; | 716 | int i; |
| 701 | 717 | ||
| 702 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 718 | spin_lock_bh(&priv->sta_lock); |
| 703 | for (i = 0; i < IWLAGN_STATION_COUNT; i++) { | 719 | for (i = 0; i < IWLAGN_STATION_COUNT; i++) { |
| 704 | if (!(priv->stations[i].used & IWL_STA_BCAST)) | 720 | if (!(priv->stations[i].used & IWL_STA_BCAST)) |
| 705 | continue; | 721 | continue; |
| @@ -711,7 +727,7 @@ void iwl_dealloc_bcast_stations(struct iwl_priv *priv) | |||
| 711 | kfree(priv->stations[i].lq); | 727 | kfree(priv->stations[i].lq); |
| 712 | priv->stations[i].lq = NULL; | 728 | priv->stations[i].lq = NULL; |
| 713 | } | 729 | } |
| 714 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 730 | spin_unlock_bh(&priv->sta_lock); |
| 715 | } | 731 | } |
| 716 | 732 | ||
| 717 | #ifdef CONFIG_IWLWIFI_DEBUG | 733 | #ifdef CONFIG_IWLWIFI_DEBUG |
| @@ -783,8 +799,6 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
| 783 | struct iwl_link_quality_cmd *lq, u8 flags, bool init) | 799 | struct iwl_link_quality_cmd *lq, u8 flags, bool init) |
| 784 | { | 800 | { |
| 785 | int ret = 0; | 801 | int ret = 0; |
| 786 | unsigned long flags_spin; | ||
| 787 | |||
| 788 | struct iwl_host_cmd cmd = { | 802 | struct iwl_host_cmd cmd = { |
| 789 | .id = REPLY_TX_LINK_QUALITY_CMD, | 803 | .id = REPLY_TX_LINK_QUALITY_CMD, |
| 790 | .len = { sizeof(struct iwl_link_quality_cmd), }, | 804 | .len = { sizeof(struct iwl_link_quality_cmd), }, |
| @@ -796,19 +810,19 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
| 796 | return -EINVAL; | 810 | return -EINVAL; |
| 797 | 811 | ||
| 798 | 812 | ||
| 799 | spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); | 813 | spin_lock_bh(&priv->sta_lock); |
| 800 | if (!(priv->stations[lq->sta_id].used & IWL_STA_DRIVER_ACTIVE)) { | 814 | if (!(priv->stations[lq->sta_id].used & IWL_STA_DRIVER_ACTIVE)) { |
| 801 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); | 815 | spin_unlock_bh(&priv->sta_lock); |
| 802 | return -EINVAL; | 816 | return -EINVAL; |
| 803 | } | 817 | } |
| 804 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); | 818 | spin_unlock_bh(&priv->sta_lock); |
| 805 | 819 | ||
| 806 | iwl_dump_lq_cmd(priv, lq); | 820 | iwl_dump_lq_cmd(priv, lq); |
| 807 | if (WARN_ON(init && (cmd.flags & CMD_ASYNC))) | 821 | if (WARN_ON(init && (cmd.flags & CMD_ASYNC))) |
| 808 | return -EINVAL; | 822 | return -EINVAL; |
| 809 | 823 | ||
| 810 | if (is_lq_table_valid(priv, ctx, lq)) | 824 | if (is_lq_table_valid(priv, ctx, lq)) |
| 811 | ret = iwl_trans_send_cmd(trans(priv), &cmd); | 825 | ret = iwl_dvm_send_cmd(priv, &cmd); |
| 812 | else | 826 | else |
| 813 | ret = -EINVAL; | 827 | ret = -EINVAL; |
| 814 | 828 | ||
| @@ -819,9 +833,9 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
| 819 | IWL_DEBUG_INFO(priv, "init LQ command complete, " | 833 | IWL_DEBUG_INFO(priv, "init LQ command complete, " |
| 820 | "clearing sta addition status for sta %d\n", | 834 | "clearing sta addition status for sta %d\n", |
| 821 | lq->sta_id); | 835 | lq->sta_id); |
| 822 | spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); | 836 | spin_lock_bh(&priv->sta_lock); |
| 823 | priv->stations[lq->sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; | 837 | priv->stations[lq->sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; |
| 824 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); | 838 | spin_unlock_bh(&priv->sta_lock); |
| 825 | } | 839 | } |
| 826 | return ret; | 840 | return ret; |
| 827 | } | 841 | } |
| @@ -834,7 +848,7 @@ void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
| 834 | u32 rate_flags = 0; | 848 | u32 rate_flags = 0; |
| 835 | __le32 rate_n_flags; | 849 | __le32 rate_n_flags; |
| 836 | 850 | ||
| 837 | lockdep_assert_held(&priv->shrd->mutex); | 851 | lockdep_assert_held(&priv->mutex); |
| 838 | 852 | ||
| 839 | memset(link_cmd, 0, sizeof(*link_cmd)); | 853 | memset(link_cmd, 0, sizeof(*link_cmd)); |
| 840 | 854 | ||
| @@ -906,7 +920,6 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv, | |||
| 906 | int ret; | 920 | int ret; |
| 907 | u8 sta_id; | 921 | u8 sta_id; |
| 908 | struct iwl_link_quality_cmd *link_cmd; | 922 | struct iwl_link_quality_cmd *link_cmd; |
| 909 | unsigned long flags; | ||
| 910 | 923 | ||
| 911 | if (sta_id_r) | 924 | if (sta_id_r) |
| 912 | *sta_id_r = IWL_INVALID_STATION; | 925 | *sta_id_r = IWL_INVALID_STATION; |
| @@ -920,9 +933,9 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv, | |||
| 920 | if (sta_id_r) | 933 | if (sta_id_r) |
| 921 | *sta_id_r = sta_id; | 934 | *sta_id_r = sta_id; |
| 922 | 935 | ||
| 923 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 936 | spin_lock_bh(&priv->sta_lock); |
| 924 | priv->stations[sta_id].used |= IWL_STA_LOCAL; | 937 | priv->stations[sta_id].used |= IWL_STA_LOCAL; |
| 925 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 938 | spin_unlock_bh(&priv->sta_lock); |
| 926 | 939 | ||
| 927 | /* Set up default rate scaling table in device's station table */ | 940 | /* Set up default rate scaling table in device's station table */ |
| 928 | link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); | 941 | link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); |
| @@ -937,9 +950,9 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv, | |||
| 937 | if (ret) | 950 | if (ret) |
| 938 | IWL_ERR(priv, "Link quality command failed (%d)\n", ret); | 951 | IWL_ERR(priv, "Link quality command failed (%d)\n", ret); |
| 939 | 952 | ||
| 940 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 953 | spin_lock_bh(&priv->sta_lock); |
| 941 | priv->stations[sta_id].lq = link_cmd; | 954 | priv->stations[sta_id].lq = link_cmd; |
| 942 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 955 | spin_unlock_bh(&priv->sta_lock); |
| 943 | 956 | ||
| 944 | return 0; | 957 | return 0; |
| 945 | } | 958 | } |
| @@ -994,7 +1007,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, | |||
| 994 | cmd.len[0] = cmd_size; | 1007 | cmd.len[0] = cmd_size; |
| 995 | 1008 | ||
| 996 | if (not_empty || send_if_empty) | 1009 | if (not_empty || send_if_empty) |
| 997 | return iwl_trans_send_cmd(trans(priv), &cmd); | 1010 | return iwl_dvm_send_cmd(priv, &cmd); |
| 998 | else | 1011 | else |
| 999 | return 0; | 1012 | return 0; |
| 1000 | } | 1013 | } |
| @@ -1002,7 +1015,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, | |||
| 1002 | int iwl_restore_default_wep_keys(struct iwl_priv *priv, | 1015 | int iwl_restore_default_wep_keys(struct iwl_priv *priv, |
| 1003 | struct iwl_rxon_context *ctx) | 1016 | struct iwl_rxon_context *ctx) |
| 1004 | { | 1017 | { |
| 1005 | lockdep_assert_held(&priv->shrd->mutex); | 1018 | lockdep_assert_held(&priv->mutex); |
| 1006 | 1019 | ||
| 1007 | return iwl_send_static_wepkey_cmd(priv, ctx, false); | 1020 | return iwl_send_static_wepkey_cmd(priv, ctx, false); |
| 1008 | } | 1021 | } |
| @@ -1013,13 +1026,13 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, | |||
| 1013 | { | 1026 | { |
| 1014 | int ret; | 1027 | int ret; |
| 1015 | 1028 | ||
| 1016 | lockdep_assert_held(&priv->shrd->mutex); | 1029 | lockdep_assert_held(&priv->mutex); |
| 1017 | 1030 | ||
| 1018 | IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", | 1031 | IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", |
| 1019 | keyconf->keyidx); | 1032 | keyconf->keyidx); |
| 1020 | 1033 | ||
| 1021 | memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0])); | 1034 | memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0])); |
| 1022 | if (iwl_is_rfkill(priv->shrd)) { | 1035 | if (iwl_is_rfkill(priv)) { |
| 1023 | IWL_DEBUG_WEP(priv, | 1036 | IWL_DEBUG_WEP(priv, |
| 1024 | "Not sending REPLY_WEPKEY command due to RFKILL.\n"); | 1037 | "Not sending REPLY_WEPKEY command due to RFKILL.\n"); |
| 1025 | /* but keys in device are clear anyway so return success */ | 1038 | /* but keys in device are clear anyway so return success */ |
| @@ -1038,7 +1051,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, | |||
| 1038 | { | 1051 | { |
| 1039 | int ret; | 1052 | int ret; |
| 1040 | 1053 | ||
| 1041 | lockdep_assert_held(&priv->shrd->mutex); | 1054 | lockdep_assert_held(&priv->mutex); |
| 1042 | 1055 | ||
| 1043 | if (keyconf->keylen != WEP_KEY_LEN_128 && | 1056 | if (keyconf->keylen != WEP_KEY_LEN_128 && |
| 1044 | keyconf->keylen != WEP_KEY_LEN_64) { | 1057 | keyconf->keylen != WEP_KEY_LEN_64) { |
| @@ -1080,32 +1093,19 @@ static u8 iwlagn_key_sta_id(struct iwl_priv *priv, | |||
| 1080 | struct ieee80211_sta *sta) | 1093 | struct ieee80211_sta *sta) |
| 1081 | { | 1094 | { |
| 1082 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | 1095 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; |
| 1083 | u8 sta_id = IWL_INVALID_STATION; | ||
| 1084 | 1096 | ||
| 1085 | if (sta) | 1097 | if (sta) |
| 1086 | sta_id = iwl_sta_id(sta); | 1098 | return iwl_sta_id(sta); |
| 1087 | 1099 | ||
| 1088 | /* | 1100 | /* |
| 1089 | * The device expects GTKs for station interfaces to be | 1101 | * The device expects GTKs for station interfaces to be |
| 1090 | * installed as GTKs for the AP station. If we have no | 1102 | * installed as GTKs for the AP station. If we have no |
| 1091 | * station ID, then use the ap_sta_id in that case. | 1103 | * station ID, then use the ap_sta_id in that case. |
| 1092 | */ | 1104 | */ |
| 1093 | if (!sta && vif && vif_priv->ctx) { | 1105 | if (vif->type == NL80211_IFTYPE_STATION && vif_priv->ctx) |
| 1094 | switch (vif->type) { | 1106 | return vif_priv->ctx->ap_sta_id; |
| 1095 | case NL80211_IFTYPE_STATION: | ||
| 1096 | sta_id = vif_priv->ctx->ap_sta_id; | ||
| 1097 | break; | ||
| 1098 | default: | ||
| 1099 | /* | ||
| 1100 | * In all other cases, the key will be | ||
| 1101 | * used either for TX only or is bound | ||
| 1102 | * to a station already. | ||
| 1103 | */ | ||
| 1104 | break; | ||
| 1105 | } | ||
| 1106 | } | ||
| 1107 | 1107 | ||
| 1108 | return sta_id; | 1108 | return IWL_INVALID_STATION; |
| 1109 | } | 1109 | } |
| 1110 | 1110 | ||
| 1111 | static int iwlagn_send_sta_key(struct iwl_priv *priv, | 1111 | static int iwlagn_send_sta_key(struct iwl_priv *priv, |
| @@ -1113,14 +1113,13 @@ static int iwlagn_send_sta_key(struct iwl_priv *priv, | |||
| 1113 | u8 sta_id, u32 tkip_iv32, u16 *tkip_p1k, | 1113 | u8 sta_id, u32 tkip_iv32, u16 *tkip_p1k, |
| 1114 | u32 cmd_flags) | 1114 | u32 cmd_flags) |
| 1115 | { | 1115 | { |
| 1116 | unsigned long flags; | ||
| 1117 | __le16 key_flags; | 1116 | __le16 key_flags; |
| 1118 | struct iwl_addsta_cmd sta_cmd; | 1117 | struct iwl_addsta_cmd sta_cmd; |
| 1119 | int i; | 1118 | int i; |
| 1120 | 1119 | ||
| 1121 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1120 | spin_lock_bh(&priv->sta_lock); |
| 1122 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); | 1121 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); |
| 1123 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1122 | spin_unlock_bh(&priv->sta_lock); |
| 1124 | 1123 | ||
| 1125 | key_flags = cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); | 1124 | key_flags = cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); |
| 1126 | key_flags |= STA_KEY_FLG_MAP_KEY_MSK; | 1125 | key_flags |= STA_KEY_FLG_MAP_KEY_MSK; |
| @@ -1187,7 +1186,6 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, | |||
| 1187 | struct ieee80211_key_conf *keyconf, | 1186 | struct ieee80211_key_conf *keyconf, |
| 1188 | struct ieee80211_sta *sta) | 1187 | struct ieee80211_sta *sta) |
| 1189 | { | 1188 | { |
| 1190 | unsigned long flags; | ||
| 1191 | struct iwl_addsta_cmd sta_cmd; | 1189 | struct iwl_addsta_cmd sta_cmd; |
| 1192 | u8 sta_id = iwlagn_key_sta_id(priv, ctx->vif, sta); | 1190 | u8 sta_id = iwlagn_key_sta_id(priv, ctx->vif, sta); |
| 1193 | __le16 key_flags; | 1191 | __le16 key_flags; |
| @@ -1196,16 +1194,16 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, | |||
| 1196 | if (sta_id == IWL_INVALID_STATION) | 1194 | if (sta_id == IWL_INVALID_STATION) |
| 1197 | return -ENOENT; | 1195 | return -ENOENT; |
| 1198 | 1196 | ||
| 1199 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1197 | spin_lock_bh(&priv->sta_lock); |
| 1200 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); | 1198 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); |
| 1201 | if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) | 1199 | if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) |
| 1202 | sta_id = IWL_INVALID_STATION; | 1200 | sta_id = IWL_INVALID_STATION; |
| 1203 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1201 | spin_unlock_bh(&priv->sta_lock); |
| 1204 | 1202 | ||
| 1205 | if (sta_id == IWL_INVALID_STATION) | 1203 | if (sta_id == IWL_INVALID_STATION) |
| 1206 | return 0; | 1204 | return 0; |
| 1207 | 1205 | ||
| 1208 | lockdep_assert_held(&priv->shrd->mutex); | 1206 | lockdep_assert_held(&priv->mutex); |
| 1209 | 1207 | ||
| 1210 | ctx->key_mapping_keys--; | 1208 | ctx->key_mapping_keys--; |
| 1211 | 1209 | ||
| @@ -1245,7 +1243,7 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, | |||
| 1245 | if (sta_id == IWL_INVALID_STATION) | 1243 | if (sta_id == IWL_INVALID_STATION) |
| 1246 | return -EINVAL; | 1244 | return -EINVAL; |
| 1247 | 1245 | ||
| 1248 | lockdep_assert_held(&priv->shrd->mutex); | 1246 | lockdep_assert_held(&priv->mutex); |
| 1249 | 1247 | ||
| 1250 | keyconf->hw_key_idx = iwl_get_free_ucode_key_offset(priv); | 1248 | keyconf->hw_key_idx = iwl_get_free_ucode_key_offset(priv); |
| 1251 | if (keyconf->hw_key_idx == WEP_INVALID_OFFSET) | 1249 | if (keyconf->hw_key_idx == WEP_INVALID_OFFSET) |
| @@ -1300,21 +1298,20 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv, | |||
| 1300 | struct iwl_rxon_context *ctx) | 1298 | struct iwl_rxon_context *ctx) |
| 1301 | { | 1299 | { |
| 1302 | struct iwl_link_quality_cmd *link_cmd; | 1300 | struct iwl_link_quality_cmd *link_cmd; |
| 1303 | unsigned long flags; | ||
| 1304 | u8 sta_id; | 1301 | u8 sta_id; |
| 1305 | 1302 | ||
| 1306 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1303 | spin_lock_bh(&priv->sta_lock); |
| 1307 | sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL); | 1304 | sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL); |
| 1308 | if (sta_id == IWL_INVALID_STATION) { | 1305 | if (sta_id == IWL_INVALID_STATION) { |
| 1309 | IWL_ERR(priv, "Unable to prepare broadcast station\n"); | 1306 | IWL_ERR(priv, "Unable to prepare broadcast station\n"); |
| 1310 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1307 | spin_unlock_bh(&priv->sta_lock); |
| 1311 | 1308 | ||
| 1312 | return -EINVAL; | 1309 | return -EINVAL; |
| 1313 | } | 1310 | } |
| 1314 | 1311 | ||
| 1315 | priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; | 1312 | priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; |
| 1316 | priv->stations[sta_id].used |= IWL_STA_BCAST; | 1313 | priv->stations[sta_id].used |= IWL_STA_BCAST; |
| 1317 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1314 | spin_unlock_bh(&priv->sta_lock); |
| 1318 | 1315 | ||
| 1319 | link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); | 1316 | link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); |
| 1320 | if (!link_cmd) { | 1317 | if (!link_cmd) { |
| @@ -1323,9 +1320,9 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv, | |||
| 1323 | return -ENOMEM; | 1320 | return -ENOMEM; |
| 1324 | } | 1321 | } |
| 1325 | 1322 | ||
| 1326 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1323 | spin_lock_bh(&priv->sta_lock); |
| 1327 | priv->stations[sta_id].lq = link_cmd; | 1324 | priv->stations[sta_id].lq = link_cmd; |
| 1328 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1325 | spin_unlock_bh(&priv->sta_lock); |
| 1329 | 1326 | ||
| 1330 | return 0; | 1327 | return 0; |
| 1331 | } | 1328 | } |
| @@ -1339,7 +1336,6 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv, | |||
| 1339 | int iwl_update_bcast_station(struct iwl_priv *priv, | 1336 | int iwl_update_bcast_station(struct iwl_priv *priv, |
| 1340 | struct iwl_rxon_context *ctx) | 1337 | struct iwl_rxon_context *ctx) |
| 1341 | { | 1338 | { |
| 1342 | unsigned long flags; | ||
| 1343 | struct iwl_link_quality_cmd *link_cmd; | 1339 | struct iwl_link_quality_cmd *link_cmd; |
| 1344 | u8 sta_id = ctx->bcast_sta_id; | 1340 | u8 sta_id = ctx->bcast_sta_id; |
| 1345 | 1341 | ||
| @@ -1349,13 +1345,13 @@ int iwl_update_bcast_station(struct iwl_priv *priv, | |||
| 1349 | return -ENOMEM; | 1345 | return -ENOMEM; |
| 1350 | } | 1346 | } |
| 1351 | 1347 | ||
| 1352 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1348 | spin_lock_bh(&priv->sta_lock); |
| 1353 | if (priv->stations[sta_id].lq) | 1349 | if (priv->stations[sta_id].lq) |
| 1354 | kfree(priv->stations[sta_id].lq); | 1350 | kfree(priv->stations[sta_id].lq); |
| 1355 | else | 1351 | else |
| 1356 | IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n"); | 1352 | IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n"); |
| 1357 | priv->stations[sta_id].lq = link_cmd; | 1353 | priv->stations[sta_id].lq = link_cmd; |
| 1358 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1354 | spin_unlock_bh(&priv->sta_lock); |
| 1359 | 1355 | ||
| 1360 | return 0; | 1356 | return 0; |
| 1361 | } | 1357 | } |
| @@ -1379,18 +1375,17 @@ int iwl_update_bcast_stations(struct iwl_priv *priv) | |||
| 1379 | */ | 1375 | */ |
| 1380 | int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) | 1376 | int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) |
| 1381 | { | 1377 | { |
| 1382 | unsigned long flags; | ||
| 1383 | struct iwl_addsta_cmd sta_cmd; | 1378 | struct iwl_addsta_cmd sta_cmd; |
| 1384 | 1379 | ||
| 1385 | lockdep_assert_held(&priv->shrd->mutex); | 1380 | lockdep_assert_held(&priv->mutex); |
| 1386 | 1381 | ||
| 1387 | /* Remove "disable" flag, to enable Tx for this TID */ | 1382 | /* Remove "disable" flag, to enable Tx for this TID */ |
| 1388 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1383 | spin_lock_bh(&priv->sta_lock); |
| 1389 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX; | 1384 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX; |
| 1390 | priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid)); | 1385 | priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid)); |
| 1391 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 1386 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
| 1392 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); | 1387 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); |
| 1393 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1388 | spin_unlock_bh(&priv->sta_lock); |
| 1394 | 1389 | ||
| 1395 | return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); | 1390 | return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); |
| 1396 | } | 1391 | } |
| @@ -1398,24 +1393,23 @@ int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) | |||
| 1398 | int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, | 1393 | int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, |
| 1399 | int tid, u16 ssn) | 1394 | int tid, u16 ssn) |
| 1400 | { | 1395 | { |
| 1401 | unsigned long flags; | ||
| 1402 | int sta_id; | 1396 | int sta_id; |
| 1403 | struct iwl_addsta_cmd sta_cmd; | 1397 | struct iwl_addsta_cmd sta_cmd; |
| 1404 | 1398 | ||
| 1405 | lockdep_assert_held(&priv->shrd->mutex); | 1399 | lockdep_assert_held(&priv->mutex); |
| 1406 | 1400 | ||
| 1407 | sta_id = iwl_sta_id(sta); | 1401 | sta_id = iwl_sta_id(sta); |
| 1408 | if (sta_id == IWL_INVALID_STATION) | 1402 | if (sta_id == IWL_INVALID_STATION) |
| 1409 | return -ENXIO; | 1403 | return -ENXIO; |
| 1410 | 1404 | ||
| 1411 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1405 | spin_lock_bh(&priv->sta_lock); |
| 1412 | priv->stations[sta_id].sta.station_flags_msk = 0; | 1406 | priv->stations[sta_id].sta.station_flags_msk = 0; |
| 1413 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK; | 1407 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK; |
| 1414 | priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid; | 1408 | priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid; |
| 1415 | priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn); | 1409 | priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn); |
| 1416 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 1410 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
| 1417 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); | 1411 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); |
| 1418 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1412 | spin_unlock_bh(&priv->sta_lock); |
| 1419 | 1413 | ||
| 1420 | return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); | 1414 | return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); |
| 1421 | } | 1415 | } |
| @@ -1423,11 +1417,10 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, | |||
| 1423 | int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, | 1417 | int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, |
| 1424 | int tid) | 1418 | int tid) |
| 1425 | { | 1419 | { |
| 1426 | unsigned long flags; | ||
| 1427 | int sta_id; | 1420 | int sta_id; |
| 1428 | struct iwl_addsta_cmd sta_cmd; | 1421 | struct iwl_addsta_cmd sta_cmd; |
| 1429 | 1422 | ||
| 1430 | lockdep_assert_held(&priv->shrd->mutex); | 1423 | lockdep_assert_held(&priv->mutex); |
| 1431 | 1424 | ||
| 1432 | sta_id = iwl_sta_id(sta); | 1425 | sta_id = iwl_sta_id(sta); |
| 1433 | if (sta_id == IWL_INVALID_STATION) { | 1426 | if (sta_id == IWL_INVALID_STATION) { |
| @@ -1435,13 +1428,13 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, | |||
| 1435 | return -ENXIO; | 1428 | return -ENXIO; |
| 1436 | } | 1429 | } |
| 1437 | 1430 | ||
| 1438 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1431 | spin_lock_bh(&priv->sta_lock); |
| 1439 | priv->stations[sta_id].sta.station_flags_msk = 0; | 1432 | priv->stations[sta_id].sta.station_flags_msk = 0; |
| 1440 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; | 1433 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; |
| 1441 | priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; | 1434 | priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; |
| 1442 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 1435 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
| 1443 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); | 1436 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); |
| 1444 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1437 | spin_unlock_bh(&priv->sta_lock); |
| 1445 | 1438 | ||
| 1446 | return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); | 1439 | return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); |
| 1447 | } | 1440 | } |
| @@ -1450,16 +1443,14 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, | |||
| 1450 | 1443 | ||
| 1451 | void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) | 1444 | void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) |
| 1452 | { | 1445 | { |
| 1453 | unsigned long flags; | 1446 | struct iwl_addsta_cmd cmd = { |
| 1454 | 1447 | .mode = STA_CONTROL_MODIFY_MSK, | |
| 1455 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1448 | .station_flags = STA_FLG_PWR_SAVE_MSK, |
| 1456 | priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK; | 1449 | .station_flags_msk = STA_FLG_PWR_SAVE_MSK, |
| 1457 | priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; | 1450 | .sta.sta_id = sta_id, |
| 1458 | priv->stations[sta_id].sta.sta.modify_mask = | 1451 | .sta.modify_mask = STA_MODIFY_SLEEP_TX_COUNT_MSK, |
| 1459 | STA_MODIFY_SLEEP_TX_COUNT_MSK; | 1452 | .sleep_tx_count = cpu_to_le16(cnt), |
| 1460 | priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt); | 1453 | }; |
| 1461 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | ||
| 1462 | iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | ||
| 1463 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
| 1464 | 1454 | ||
| 1455 | iwl_send_add_sta(priv, &cmd, CMD_ASYNC); | ||
| 1465 | } | 1456 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index 56d7c0e38163..baaf5ba2fc38 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | #include <net/mac80211.h> | 35 | #include <net/mac80211.h> |
| 36 | 36 | ||
| 37 | #include "iwl-agn.h" | ||
| 37 | #include "iwl-eeprom.h" | 38 | #include "iwl-eeprom.h" |
| 38 | #include "iwl-dev.h" | 39 | #include "iwl-dev.h" |
| 39 | #include "iwl-core.h" | 40 | #include "iwl-core.h" |
| @@ -173,7 +174,7 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data) | |||
| 173 | struct iwl_tt_mgmt *tt = &priv->thermal_throttle; | 174 | struct iwl_tt_mgmt *tt = &priv->thermal_throttle; |
| 174 | unsigned long flags; | 175 | unsigned long flags; |
| 175 | 176 | ||
| 176 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 177 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 177 | return; | 178 | return; |
| 178 | 179 | ||
| 179 | if (tt->state == IWL_TI_CT_KILL) { | 180 | if (tt->state == IWL_TI_CT_KILL) { |
| @@ -188,7 +189,7 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data) | |||
| 188 | } | 189 | } |
| 189 | iwl_read32(trans(priv), CSR_UCODE_DRV_GP1); | 190 | iwl_read32(trans(priv), CSR_UCODE_DRV_GP1); |
| 190 | spin_lock_irqsave(&trans(priv)->reg_lock, flags); | 191 | spin_lock_irqsave(&trans(priv)->reg_lock, flags); |
| 191 | if (!iwl_grab_nic_access(trans(priv))) | 192 | if (likely(iwl_grab_nic_access(trans(priv)))) |
| 192 | iwl_release_nic_access(trans(priv)); | 193 | iwl_release_nic_access(trans(priv)); |
| 193 | spin_unlock_irqrestore(&trans(priv)->reg_lock, flags); | 194 | spin_unlock_irqrestore(&trans(priv)->reg_lock, flags); |
| 194 | 195 | ||
| @@ -224,7 +225,7 @@ static void iwl_tt_ready_for_ct_kill(unsigned long data) | |||
| 224 | struct iwl_priv *priv = (struct iwl_priv *)data; | 225 | struct iwl_priv *priv = (struct iwl_priv *)data; |
| 225 | struct iwl_tt_mgmt *tt = &priv->thermal_throttle; | 226 | struct iwl_tt_mgmt *tt = &priv->thermal_throttle; |
| 226 | 227 | ||
| 227 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 228 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 228 | return; | 229 | return; |
| 229 | 230 | ||
| 230 | /* temperature timer expired, ready to go into CT_KILL state */ | 231 | /* temperature timer expired, ready to go into CT_KILL state */ |
| @@ -232,7 +233,7 @@ static void iwl_tt_ready_for_ct_kill(unsigned long data) | |||
| 232 | IWL_DEBUG_TEMP(priv, "entering CT_KILL state when " | 233 | IWL_DEBUG_TEMP(priv, "entering CT_KILL state when " |
| 233 | "temperature timer expired\n"); | 234 | "temperature timer expired\n"); |
| 234 | tt->state = IWL_TI_CT_KILL; | 235 | tt->state = IWL_TI_CT_KILL; |
| 235 | set_bit(STATUS_CT_KILL, &priv->shrd->status); | 236 | set_bit(STATUS_CT_KILL, &priv->status); |
| 236 | iwl_perform_ct_kill_task(priv, true); | 237 | iwl_perform_ct_kill_task(priv, true); |
| 237 | } | 238 | } |
| 238 | } | 239 | } |
| @@ -310,24 +311,23 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force) | |||
| 310 | tt->tt_power_mode = IWL_POWER_INDEX_5; | 311 | tt->tt_power_mode = IWL_POWER_INDEX_5; |
| 311 | break; | 312 | break; |
| 312 | } | 313 | } |
| 313 | mutex_lock(&priv->shrd->mutex); | 314 | mutex_lock(&priv->mutex); |
| 314 | if (old_state == IWL_TI_CT_KILL) | 315 | if (old_state == IWL_TI_CT_KILL) |
| 315 | clear_bit(STATUS_CT_KILL, &priv->shrd->status); | 316 | clear_bit(STATUS_CT_KILL, &priv->status); |
| 316 | if (tt->state != IWL_TI_CT_KILL && | 317 | if (tt->state != IWL_TI_CT_KILL && |
| 317 | iwl_power_update_mode(priv, true)) { | 318 | iwl_power_update_mode(priv, true)) { |
| 318 | /* TT state not updated | 319 | /* TT state not updated |
| 319 | * try again during next temperature read | 320 | * try again during next temperature read |
| 320 | */ | 321 | */ |
| 321 | if (old_state == IWL_TI_CT_KILL) | 322 | if (old_state == IWL_TI_CT_KILL) |
| 322 | set_bit(STATUS_CT_KILL, &priv->shrd->status); | 323 | set_bit(STATUS_CT_KILL, &priv->status); |
| 323 | tt->state = old_state; | 324 | tt->state = old_state; |
| 324 | IWL_ERR(priv, "Cannot update power mode, " | 325 | IWL_ERR(priv, "Cannot update power mode, " |
| 325 | "TT state not updated\n"); | 326 | "TT state not updated\n"); |
| 326 | } else { | 327 | } else { |
| 327 | if (tt->state == IWL_TI_CT_KILL) { | 328 | if (tt->state == IWL_TI_CT_KILL) { |
| 328 | if (force) { | 329 | if (force) { |
| 329 | set_bit(STATUS_CT_KILL, | 330 | set_bit(STATUS_CT_KILL, &priv->status); |
| 330 | &priv->shrd->status); | ||
| 331 | iwl_perform_ct_kill_task(priv, true); | 331 | iwl_perform_ct_kill_task(priv, true); |
| 332 | } else { | 332 | } else { |
| 333 | iwl_prepare_ct_kill_task(priv); | 333 | iwl_prepare_ct_kill_task(priv); |
| @@ -341,7 +341,7 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force) | |||
| 341 | IWL_DEBUG_TEMP(priv, "Power Index change to %u\n", | 341 | IWL_DEBUG_TEMP(priv, "Power Index change to %u\n", |
| 342 | tt->tt_power_mode); | 342 | tt->tt_power_mode); |
| 343 | } | 343 | } |
| 344 | mutex_unlock(&priv->shrd->mutex); | 344 | mutex_unlock(&priv->mutex); |
| 345 | } | 345 | } |
| 346 | } | 346 | } |
| 347 | 347 | ||
| @@ -451,9 +451,9 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) | |||
| 451 | * in case get disabled before */ | 451 | * in case get disabled before */ |
| 452 | iwl_set_rxon_ht(priv, &priv->current_ht_config); | 452 | iwl_set_rxon_ht(priv, &priv->current_ht_config); |
| 453 | } | 453 | } |
| 454 | mutex_lock(&priv->shrd->mutex); | 454 | mutex_lock(&priv->mutex); |
| 455 | if (old_state == IWL_TI_CT_KILL) | 455 | if (old_state == IWL_TI_CT_KILL) |
| 456 | clear_bit(STATUS_CT_KILL, &priv->shrd->status); | 456 | clear_bit(STATUS_CT_KILL, &priv->status); |
| 457 | if (tt->state != IWL_TI_CT_KILL && | 457 | if (tt->state != IWL_TI_CT_KILL && |
| 458 | iwl_power_update_mode(priv, true)) { | 458 | iwl_power_update_mode(priv, true)) { |
| 459 | /* TT state not updated | 459 | /* TT state not updated |
| @@ -462,7 +462,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) | |||
| 462 | IWL_ERR(priv, "Cannot update power mode, " | 462 | IWL_ERR(priv, "Cannot update power mode, " |
| 463 | "TT state not updated\n"); | 463 | "TT state not updated\n"); |
| 464 | if (old_state == IWL_TI_CT_KILL) | 464 | if (old_state == IWL_TI_CT_KILL) |
| 465 | set_bit(STATUS_CT_KILL, &priv->shrd->status); | 465 | set_bit(STATUS_CT_KILL, &priv->status); |
| 466 | tt->state = old_state; | 466 | tt->state = old_state; |
| 467 | } else { | 467 | } else { |
| 468 | IWL_DEBUG_TEMP(priv, | 468 | IWL_DEBUG_TEMP(priv, |
| @@ -473,8 +473,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) | |||
| 473 | if (force) { | 473 | if (force) { |
| 474 | IWL_DEBUG_TEMP(priv, | 474 | IWL_DEBUG_TEMP(priv, |
| 475 | "Enter IWL_TI_CT_KILL\n"); | 475 | "Enter IWL_TI_CT_KILL\n"); |
| 476 | set_bit(STATUS_CT_KILL, | 476 | set_bit(STATUS_CT_KILL, &priv->status); |
| 477 | &priv->shrd->status); | ||
| 478 | iwl_perform_ct_kill_task(priv, true); | 477 | iwl_perform_ct_kill_task(priv, true); |
| 479 | } else { | 478 | } else { |
| 480 | iwl_prepare_ct_kill_task(priv); | 479 | iwl_prepare_ct_kill_task(priv); |
| @@ -486,7 +485,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) | |||
| 486 | iwl_perform_ct_kill_task(priv, false); | 485 | iwl_perform_ct_kill_task(priv, false); |
| 487 | } | 486 | } |
| 488 | } | 487 | } |
| 489 | mutex_unlock(&priv->shrd->mutex); | 488 | mutex_unlock(&priv->mutex); |
| 490 | } | 489 | } |
| 491 | } | 490 | } |
| 492 | 491 | ||
| @@ -505,10 +504,10 @@ static void iwl_bg_ct_enter(struct work_struct *work) | |||
| 505 | struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter); | 504 | struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter); |
| 506 | struct iwl_tt_mgmt *tt = &priv->thermal_throttle; | 505 | struct iwl_tt_mgmt *tt = &priv->thermal_throttle; |
| 507 | 506 | ||
| 508 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 507 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 509 | return; | 508 | return; |
| 510 | 509 | ||
| 511 | if (!iwl_is_ready(priv->shrd)) | 510 | if (!iwl_is_ready(priv)) |
| 512 | return; | 511 | return; |
| 513 | 512 | ||
| 514 | if (tt->state != IWL_TI_CT_KILL) { | 513 | if (tt->state != IWL_TI_CT_KILL) { |
| @@ -534,10 +533,10 @@ static void iwl_bg_ct_exit(struct work_struct *work) | |||
| 534 | struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit); | 533 | struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit); |
| 535 | struct iwl_tt_mgmt *tt = &priv->thermal_throttle; | 534 | struct iwl_tt_mgmt *tt = &priv->thermal_throttle; |
| 536 | 535 | ||
| 537 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 536 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 538 | return; | 537 | return; |
| 539 | 538 | ||
| 540 | if (!iwl_is_ready(priv->shrd)) | 539 | if (!iwl_is_ready(priv)) |
| 541 | return; | 540 | return; |
| 542 | 541 | ||
| 543 | /* stop ct_kill_exit_tm timer */ | 542 | /* stop ct_kill_exit_tm timer */ |
| @@ -564,7 +563,7 @@ static void iwl_bg_ct_exit(struct work_struct *work) | |||
| 564 | 563 | ||
| 565 | void iwl_tt_enter_ct_kill(struct iwl_priv *priv) | 564 | void iwl_tt_enter_ct_kill(struct iwl_priv *priv) |
| 566 | { | 565 | { |
| 567 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 566 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 568 | return; | 567 | return; |
| 569 | 568 | ||
| 570 | IWL_DEBUG_TEMP(priv, "Queueing critical temperature enter.\n"); | 569 | IWL_DEBUG_TEMP(priv, "Queueing critical temperature enter.\n"); |
| @@ -573,7 +572,7 @@ void iwl_tt_enter_ct_kill(struct iwl_priv *priv) | |||
| 573 | 572 | ||
| 574 | void iwl_tt_exit_ct_kill(struct iwl_priv *priv) | 573 | void iwl_tt_exit_ct_kill(struct iwl_priv *priv) |
| 575 | { | 574 | { |
| 576 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 575 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 577 | return; | 576 | return; |
| 578 | 577 | ||
| 579 | IWL_DEBUG_TEMP(priv, "Queueing critical temperature exit.\n"); | 578 | IWL_DEBUG_TEMP(priv, "Queueing critical temperature exit.\n"); |
| @@ -585,7 +584,7 @@ static void iwl_bg_tt_work(struct work_struct *work) | |||
| 585 | struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work); | 584 | struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work); |
| 586 | s32 temp = priv->temperature; /* degrees CELSIUS except specified */ | 585 | s32 temp = priv->temperature; /* degrees CELSIUS except specified */ |
| 587 | 586 | ||
| 588 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 587 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 589 | return; | 588 | return; |
| 590 | 589 | ||
| 591 | if (!priv->thermal_throttle.advanced_tt) | 590 | if (!priv->thermal_throttle.advanced_tt) |
| @@ -596,7 +595,7 @@ static void iwl_bg_tt_work(struct work_struct *work) | |||
| 596 | 595 | ||
| 597 | void iwl_tt_handler(struct iwl_priv *priv) | 596 | void iwl_tt_handler(struct iwl_priv *priv) |
| 598 | { | 597 | { |
| 599 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 598 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 600 | return; | 599 | return; |
| 601 | 600 | ||
| 602 | IWL_DEBUG_TEMP(priv, "Queueing thermal throttling work.\n"); | 601 | IWL_DEBUG_TEMP(priv, "Queueing thermal throttling work.\n"); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 5f78567f4180..34adedc74d35 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c | |||
| @@ -126,7 +126,7 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, | |||
| 126 | u8 data_retry_limit; | 126 | u8 data_retry_limit; |
| 127 | u8 rate_plcp; | 127 | u8 rate_plcp; |
| 128 | 128 | ||
| 129 | if (priv->shrd->wowlan) { | 129 | if (priv->wowlan) { |
| 130 | rts_retry_limit = IWLAGN_LOW_RETRY_LIMIT; | 130 | rts_retry_limit = IWLAGN_LOW_RETRY_LIMIT; |
| 131 | data_retry_limit = IWLAGN_LOW_RETRY_LIMIT; | 131 | data_retry_limit = IWLAGN_LOW_RETRY_LIMIT; |
| 132 | } else { | 132 | } else { |
| @@ -208,10 +208,9 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, | |||
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, | 210 | static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, |
| 211 | struct ieee80211_tx_info *info, | 211 | struct ieee80211_tx_info *info, |
| 212 | struct iwl_tx_cmd *tx_cmd, | 212 | struct iwl_tx_cmd *tx_cmd, |
| 213 | struct sk_buff *skb_frag, | 213 | struct sk_buff *skb_frag) |
| 214 | int sta_id) | ||
| 215 | { | 214 | { |
| 216 | struct ieee80211_key_conf *keyconf = info->control.hw_key; | 215 | struct ieee80211_key_conf *keyconf = info->control.hw_key; |
| 217 | 216 | ||
| @@ -249,6 +248,35 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, | |||
| 249 | } | 248 | } |
| 250 | } | 249 | } |
| 251 | 250 | ||
| 251 | /** | ||
| 252 | * iwl_sta_id_or_broadcast - return sta_id or broadcast sta | ||
| 253 | * @context: the current context | ||
| 254 | * @sta: mac80211 station | ||
| 255 | * | ||
| 256 | * In certain circumstances mac80211 passes a station pointer | ||
| 257 | * that may be %NULL, for example during TX or key setup. In | ||
| 258 | * that case, we need to use the broadcast station, so this | ||
| 259 | * inline wraps that pattern. | ||
| 260 | */ | ||
| 261 | static int iwl_sta_id_or_broadcast(struct iwl_rxon_context *context, | ||
| 262 | struct ieee80211_sta *sta) | ||
| 263 | { | ||
| 264 | int sta_id; | ||
| 265 | |||
| 266 | if (!sta) | ||
| 267 | return context->bcast_sta_id; | ||
| 268 | |||
| 269 | sta_id = iwl_sta_id(sta); | ||
| 270 | |||
| 271 | /* | ||
| 272 | * mac80211 should not be passing a partially | ||
| 273 | * initialised station! | ||
| 274 | */ | ||
| 275 | WARN_ON(sta_id == IWL_INVALID_STATION); | ||
| 276 | |||
| 277 | return sta_id; | ||
| 278 | } | ||
| 279 | |||
| 252 | /* | 280 | /* |
| 253 | * start REPLY_TX command process | 281 | * start REPLY_TX command process |
| 254 | */ | 282 | */ |
| @@ -260,19 +288,16 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
| 260 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 288 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
| 261 | struct iwl_device_cmd *dev_cmd = NULL; | 289 | struct iwl_device_cmd *dev_cmd = NULL; |
| 262 | struct iwl_tx_cmd *tx_cmd; | 290 | struct iwl_tx_cmd *tx_cmd; |
| 263 | |||
| 264 | __le16 fc; | 291 | __le16 fc; |
| 265 | u8 hdr_len; | 292 | u8 hdr_len; |
| 266 | u16 len, seq_number = 0; | 293 | u16 len, seq_number = 0; |
| 267 | u8 sta_id, tid = IWL_MAX_TID_COUNT; | 294 | u8 sta_id, tid = IWL_MAX_TID_COUNT; |
| 268 | unsigned long flags; | ||
| 269 | bool is_agg = false; | 295 | bool is_agg = false; |
| 270 | 296 | ||
| 271 | if (info->control.vif) | 297 | if (info->control.vif) |
| 272 | ctx = iwl_rxon_ctx_from_vif(info->control.vif); | 298 | ctx = iwl_rxon_ctx_from_vif(info->control.vif); |
| 273 | 299 | ||
| 274 | spin_lock_irqsave(&priv->shrd->lock, flags); | 300 | if (iwl_is_rfkill(priv)) { |
| 275 | if (iwl_is_rfkill(priv->shrd)) { | ||
| 276 | IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n"); | 301 | IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n"); |
| 277 | goto drop_unlock_priv; | 302 | goto drop_unlock_priv; |
| 278 | } | 303 | } |
| @@ -308,7 +333,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
| 308 | sta_id = ctx->bcast_sta_id; | 333 | sta_id = ctx->bcast_sta_id; |
| 309 | else { | 334 | else { |
| 310 | /* Find index into station table for destination station */ | 335 | /* Find index into station table for destination station */ |
| 311 | sta_id = iwl_sta_id_or_broadcast(priv, ctx, info->control.sta); | 336 | sta_id = iwl_sta_id_or_broadcast(ctx, info->control.sta); |
| 312 | if (sta_id == IWL_INVALID_STATION) { | 337 | if (sta_id == IWL_INVALID_STATION) { |
| 313 | IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", | 338 | IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", |
| 314 | hdr->addr1); | 339 | hdr->addr1); |
| @@ -342,13 +367,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
| 342 | if (info->flags & IEEE80211_TX_CTL_AMPDU) | 367 | if (info->flags & IEEE80211_TX_CTL_AMPDU) |
| 343 | is_agg = true; | 368 | is_agg = true; |
| 344 | 369 | ||
| 345 | /* irqs already disabled/saved above when locking priv->shrd->lock */ | 370 | dev_cmd = kmem_cache_alloc(iwl_tx_cmd_pool, GFP_ATOMIC); |
| 346 | spin_lock(&priv->shrd->sta_lock); | ||
| 347 | |||
| 348 | dev_cmd = kmem_cache_alloc(priv->tx_cmd_pool, GFP_ATOMIC); | ||
| 349 | 371 | ||
| 350 | if (unlikely(!dev_cmd)) | 372 | if (unlikely(!dev_cmd)) |
| 351 | goto drop_unlock_sta; | 373 | goto drop_unlock_priv; |
| 352 | 374 | ||
| 353 | memset(dev_cmd, 0, sizeof(*dev_cmd)); | 375 | memset(dev_cmd, 0, sizeof(*dev_cmd)); |
| 354 | tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload; | 376 | tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload; |
| @@ -358,7 +380,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
| 358 | tx_cmd->len = cpu_to_le16(len); | 380 | tx_cmd->len = cpu_to_le16(len); |
| 359 | 381 | ||
| 360 | if (info->control.hw_key) | 382 | if (info->control.hw_key) |
| 361 | iwlagn_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id); | 383 | iwlagn_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb); |
| 362 | 384 | ||
| 363 | /* TODO need this for burst mode later on */ | 385 | /* TODO need this for burst mode later on */ |
| 364 | iwlagn_tx_cmd_build_basic(priv, skb, tx_cmd, info, hdr, sta_id); | 386 | iwlagn_tx_cmd_build_basic(priv, skb, tx_cmd, info, hdr, sta_id); |
| @@ -373,6 +395,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
| 373 | info->driver_data[0] = ctx; | 395 | info->driver_data[0] = ctx; |
| 374 | info->driver_data[1] = dev_cmd; | 396 | info->driver_data[1] = dev_cmd; |
| 375 | 397 | ||
| 398 | spin_lock(&priv->sta_lock); | ||
| 399 | |||
| 376 | if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) { | 400 | if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) { |
| 377 | u8 *qc = NULL; | 401 | u8 *qc = NULL; |
| 378 | struct iwl_tid_data *tid_data; | 402 | struct iwl_tid_data *tid_data; |
| @@ -418,8 +442,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
| 418 | !ieee80211_has_morefrags(fc)) | 442 | !ieee80211_has_morefrags(fc)) |
| 419 | priv->tid_data[sta_id][tid].seq_number = seq_number; | 443 | priv->tid_data[sta_id][tid].seq_number = seq_number; |
| 420 | 444 | ||
| 421 | spin_unlock(&priv->shrd->sta_lock); | 445 | spin_unlock(&priv->sta_lock); |
| 422 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | ||
| 423 | 446 | ||
| 424 | /* | 447 | /* |
| 425 | * Avoid atomic ops if it isn't an associated client. | 448 | * Avoid atomic ops if it isn't an associated client. |
| @@ -435,10 +458,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
| 435 | 458 | ||
| 436 | drop_unlock_sta: | 459 | drop_unlock_sta: |
| 437 | if (dev_cmd) | 460 | if (dev_cmd) |
| 438 | kmem_cache_free(priv->tx_cmd_pool, dev_cmd); | 461 | kmem_cache_free(iwl_tx_cmd_pool, dev_cmd); |
| 439 | spin_unlock(&priv->shrd->sta_lock); | 462 | spin_unlock(&priv->sta_lock); |
| 440 | drop_unlock_priv: | 463 | drop_unlock_priv: |
| 441 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | ||
| 442 | return -1; | 464 | return -1; |
| 443 | } | 465 | } |
| 444 | 466 | ||
| @@ -446,7 +468,6 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
| 446 | struct ieee80211_sta *sta, u16 tid) | 468 | struct ieee80211_sta *sta, u16 tid) |
| 447 | { | 469 | { |
| 448 | struct iwl_tid_data *tid_data; | 470 | struct iwl_tid_data *tid_data; |
| 449 | unsigned long flags; | ||
| 450 | int sta_id; | 471 | int sta_id; |
| 451 | 472 | ||
| 452 | sta_id = iwl_sta_id(sta); | 473 | sta_id = iwl_sta_id(sta); |
| @@ -456,7 +477,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
| 456 | return -ENXIO; | 477 | return -ENXIO; |
| 457 | } | 478 | } |
| 458 | 479 | ||
| 459 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 480 | spin_lock_bh(&priv->sta_lock); |
| 460 | 481 | ||
| 461 | tid_data = &priv->tid_data[sta_id][tid]; | 482 | tid_data = &priv->tid_data[sta_id][tid]; |
| 462 | 483 | ||
| @@ -476,7 +497,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
| 476 | IWL_WARN(priv, "Stopping AGG while state not ON " | 497 | IWL_WARN(priv, "Stopping AGG while state not ON " |
| 477 | "or starting for %d on %d (%d)\n", sta_id, tid, | 498 | "or starting for %d on %d (%d)\n", sta_id, tid, |
| 478 | priv->tid_data[sta_id][tid].agg.state); | 499 | priv->tid_data[sta_id][tid].agg.state); |
| 479 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 500 | spin_unlock_bh(&priv->sta_lock); |
| 480 | return 0; | 501 | return 0; |
| 481 | } | 502 | } |
| 482 | 503 | ||
| @@ -490,7 +511,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
| 490 | tid_data->next_reclaimed); | 511 | tid_data->next_reclaimed); |
| 491 | priv->tid_data[sta_id][tid].agg.state = | 512 | priv->tid_data[sta_id][tid].agg.state = |
| 492 | IWL_EMPTYING_HW_QUEUE_DELBA; | 513 | IWL_EMPTYING_HW_QUEUE_DELBA; |
| 493 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 514 | spin_unlock_bh(&priv->sta_lock); |
| 494 | return 0; | 515 | return 0; |
| 495 | } | 516 | } |
| 496 | 517 | ||
| @@ -499,14 +520,10 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
| 499 | turn_off: | 520 | turn_off: |
| 500 | priv->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF; | 521 | priv->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF; |
| 501 | 522 | ||
| 502 | /* do not restore/save irqs */ | 523 | spin_unlock_bh(&priv->sta_lock); |
| 503 | spin_unlock(&priv->shrd->sta_lock); | ||
| 504 | spin_lock(&priv->shrd->lock); | ||
| 505 | 524 | ||
| 506 | iwl_trans_tx_agg_disable(trans(priv), sta_id, tid); | 525 | iwl_trans_tx_agg_disable(trans(priv), sta_id, tid); |
| 507 | 526 | ||
| 508 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | ||
| 509 | |||
| 510 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 527 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
| 511 | 528 | ||
| 512 | return 0; | 529 | return 0; |
| @@ -516,7 +533,6 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
| 516 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) | 533 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) |
| 517 | { | 534 | { |
| 518 | struct iwl_tid_data *tid_data; | 535 | struct iwl_tid_data *tid_data; |
| 519 | unsigned long flags; | ||
| 520 | int sta_id; | 536 | int sta_id; |
| 521 | int ret; | 537 | int ret; |
| 522 | 538 | ||
| @@ -540,7 +556,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
| 540 | if (ret) | 556 | if (ret) |
| 541 | return ret; | 557 | return ret; |
| 542 | 558 | ||
| 543 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 559 | spin_lock_bh(&priv->sta_lock); |
| 544 | 560 | ||
| 545 | tid_data = &priv->tid_data[sta_id][tid]; | 561 | tid_data = &priv->tid_data[sta_id][tid]; |
| 546 | tid_data->agg.ssn = SEQ_TO_SN(tid_data->seq_number); | 562 | tid_data->agg.ssn = SEQ_TO_SN(tid_data->seq_number); |
| @@ -549,7 +565,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
| 549 | 565 | ||
| 550 | ret = iwl_trans_tx_agg_alloc(trans(priv), sta_id, tid); | 566 | ret = iwl_trans_tx_agg_alloc(trans(priv), sta_id, tid); |
| 551 | if (ret) { | 567 | if (ret) { |
| 552 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 568 | spin_unlock_bh(&priv->sta_lock); |
| 553 | return ret; | 569 | return ret; |
| 554 | } | 570 | } |
| 555 | 571 | ||
| @@ -566,7 +582,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
| 566 | tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; | 582 | tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; |
| 567 | } | 583 | } |
| 568 | 584 | ||
| 569 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 585 | spin_unlock_bh(&priv->sta_lock); |
| 570 | 586 | ||
| 571 | return ret; | 587 | return ret; |
| 572 | } | 588 | } |
| @@ -576,14 +592,13 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
| 576 | { | 592 | { |
| 577 | struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; | 593 | struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; |
| 578 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | 594 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); |
| 579 | unsigned long flags; | ||
| 580 | u16 ssn; | 595 | u16 ssn; |
| 581 | 596 | ||
| 582 | buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF); | 597 | buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF); |
| 583 | 598 | ||
| 584 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 599 | spin_lock_bh(&priv->sta_lock); |
| 585 | ssn = priv->tid_data[sta_priv->sta_id][tid].agg.ssn; | 600 | ssn = priv->tid_data[sta_priv->sta_id][tid].agg.ssn; |
| 586 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 601 | spin_unlock_bh(&priv->sta_lock); |
| 587 | 602 | ||
| 588 | iwl_trans_tx_agg_setup(trans(priv), ctx->ctxid, sta_priv->sta_id, tid, | 603 | iwl_trans_tx_agg_setup(trans(priv), ctx->ctxid, sta_priv->sta_id, tid, |
| 589 | buf_size, ssn); | 604 | buf_size, ssn); |
| @@ -608,8 +623,7 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
| 608 | sta_priv->max_agg_bufsize = | 623 | sta_priv->max_agg_bufsize = |
| 609 | min(sta_priv->max_agg_bufsize, buf_size); | 624 | min(sta_priv->max_agg_bufsize, buf_size); |
| 610 | 625 | ||
| 611 | if (cfg(priv)->ht_params && | 626 | if (hw_params(priv).use_rts_for_aggregation) { |
| 612 | cfg(priv)->ht_params->use_rts_for_aggregation) { | ||
| 613 | /* | 627 | /* |
| 614 | * switch to RTS/CTS if it is the prefer protection | 628 | * switch to RTS/CTS if it is the prefer protection |
| 615 | * method for HT traffic | 629 | * method for HT traffic |
| @@ -639,7 +653,7 @@ static void iwlagn_check_ratid_empty(struct iwl_priv *priv, int sta_id, u8 tid) | |||
| 639 | struct ieee80211_vif *vif; | 653 | struct ieee80211_vif *vif; |
| 640 | u8 *addr; | 654 | u8 *addr; |
| 641 | 655 | ||
| 642 | lockdep_assert_held(&priv->shrd->sta_lock); | 656 | lockdep_assert_held(&priv->sta_lock); |
| 643 | 657 | ||
| 644 | addr = priv->stations[sta_id].sta.sta.addr; | 658 | addr = priv->stations[sta_id].sta.sta.addr; |
| 645 | ctx = priv->stations[sta_id].ctxid; | 659 | ctx = priv->stations[sta_id].ctxid; |
| @@ -986,19 +1000,19 @@ static void iwl_check_abort_status(struct iwl_priv *priv, | |||
| 986 | { | 1000 | { |
| 987 | if (frame_count == 1 && status == TX_STATUS_FAIL_RFKILL_FLUSH) { | 1001 | if (frame_count == 1 && status == TX_STATUS_FAIL_RFKILL_FLUSH) { |
| 988 | IWL_ERR(priv, "Tx flush command to flush out all frames\n"); | 1002 | IWL_ERR(priv, "Tx flush command to flush out all frames\n"); |
| 989 | if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 1003 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 990 | queue_work(priv->workqueue, &priv->tx_flush); | 1004 | queue_work(priv->workqueue, &priv->tx_flush); |
| 991 | } | 1005 | } |
| 992 | } | 1006 | } |
| 993 | 1007 | ||
| 994 | int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | 1008 | int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, |
| 995 | struct iwl_device_cmd *cmd) | 1009 | struct iwl_device_cmd *cmd) |
| 996 | { | 1010 | { |
| 997 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 1011 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 998 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | 1012 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); |
| 999 | int txq_id = SEQ_TO_QUEUE(sequence); | 1013 | int txq_id = SEQ_TO_QUEUE(sequence); |
| 1000 | int cmd_index __maybe_unused = SEQ_TO_INDEX(sequence); | 1014 | int cmd_index __maybe_unused = SEQ_TO_INDEX(sequence); |
| 1001 | struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; | 1015 | struct iwlagn_tx_resp *tx_resp = (void *)pkt->data; |
| 1002 | struct ieee80211_hdr *hdr; | 1016 | struct ieee80211_hdr *hdr; |
| 1003 | u32 status = le16_to_cpu(tx_resp->status.status); | 1017 | u32 status = le16_to_cpu(tx_resp->status.status); |
| 1004 | u16 ssn = iwlagn_get_scd_ssn(tx_resp); | 1018 | u16 ssn = iwlagn_get_scd_ssn(tx_resp); |
| @@ -1006,7 +1020,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
| 1006 | int sta_id; | 1020 | int sta_id; |
| 1007 | int freed; | 1021 | int freed; |
| 1008 | struct ieee80211_tx_info *info; | 1022 | struct ieee80211_tx_info *info; |
| 1009 | unsigned long flags; | ||
| 1010 | struct sk_buff_head skbs; | 1023 | struct sk_buff_head skbs; |
| 1011 | struct sk_buff *skb; | 1024 | struct sk_buff *skb; |
| 1012 | struct iwl_rxon_context *ctx; | 1025 | struct iwl_rxon_context *ctx; |
| @@ -1017,11 +1030,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
| 1017 | sta_id = (tx_resp->ra_tid & IWLAGN_TX_RES_RA_MSK) >> | 1030 | sta_id = (tx_resp->ra_tid & IWLAGN_TX_RES_RA_MSK) >> |
| 1018 | IWLAGN_TX_RES_RA_POS; | 1031 | IWLAGN_TX_RES_RA_POS; |
| 1019 | 1032 | ||
| 1020 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1033 | spin_lock(&priv->sta_lock); |
| 1021 | 1034 | ||
| 1022 | if (is_agg) | 1035 | if (is_agg) |
| 1023 | iwl_rx_reply_tx_agg(priv, tx_resp); | 1036 | iwl_rx_reply_tx_agg(priv, tx_resp); |
| 1024 | 1037 | ||
| 1038 | __skb_queue_head_init(&skbs); | ||
| 1039 | |||
| 1025 | if (tx_resp->frame_count == 1) { | 1040 | if (tx_resp->frame_count == 1) { |
| 1026 | u16 next_reclaimed = le16_to_cpu(tx_resp->seq_ctl); | 1041 | u16 next_reclaimed = le16_to_cpu(tx_resp->seq_ctl); |
| 1027 | next_reclaimed = SEQ_TO_SN(next_reclaimed + 0x10); | 1042 | next_reclaimed = SEQ_TO_SN(next_reclaimed + 0x10); |
| @@ -1041,8 +1056,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
| 1041 | next_reclaimed = ssn; | 1056 | next_reclaimed = ssn; |
| 1042 | } | 1057 | } |
| 1043 | 1058 | ||
| 1044 | __skb_queue_head_init(&skbs); | ||
| 1045 | |||
| 1046 | if (tid != IWL_TID_NON_QOS) { | 1059 | if (tid != IWL_TID_NON_QOS) { |
| 1047 | priv->tid_data[sta_id][tid].next_reclaimed = | 1060 | priv->tid_data[sta_id][tid].next_reclaimed = |
| 1048 | next_reclaimed; | 1061 | next_reclaimed; |
| @@ -1051,12 +1064,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
| 1051 | } | 1064 | } |
| 1052 | 1065 | ||
| 1053 | /*we can free until ssn % q.n_bd not inclusive */ | 1066 | /*we can free until ssn % q.n_bd not inclusive */ |
| 1054 | WARN_ON(iwl_trans_reclaim(trans(priv), sta_id, tid, txq_id, | 1067 | WARN_ON(iwl_trans_reclaim(trans(priv), sta_id, tid, |
| 1055 | ssn, status, &skbs)); | 1068 | txq_id, ssn, &skbs)); |
| 1056 | iwlagn_check_ratid_empty(priv, sta_id, tid); | 1069 | iwlagn_check_ratid_empty(priv, sta_id, tid); |
| 1057 | freed = 0; | 1070 | freed = 0; |
| 1058 | while (!skb_queue_empty(&skbs)) { | 1071 | |
| 1059 | skb = __skb_dequeue(&skbs); | 1072 | /* process frames */ |
| 1073 | skb_queue_walk(&skbs, skb) { | ||
| 1060 | hdr = (struct ieee80211_hdr *)skb->data; | 1074 | hdr = (struct ieee80211_hdr *)skb->data; |
| 1061 | 1075 | ||
| 1062 | if (!ieee80211_is_data_qos(hdr->frame_control)) | 1076 | if (!ieee80211_is_data_qos(hdr->frame_control)) |
| @@ -1064,7 +1078,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
| 1064 | 1078 | ||
| 1065 | info = IEEE80211_SKB_CB(skb); | 1079 | info = IEEE80211_SKB_CB(skb); |
| 1066 | ctx = info->driver_data[0]; | 1080 | ctx = info->driver_data[0]; |
| 1067 | kmem_cache_free(priv->tx_cmd_pool, | 1081 | kmem_cache_free(iwl_tx_cmd_pool, |
| 1068 | (info->driver_data[1])); | 1082 | (info->driver_data[1])); |
| 1069 | 1083 | ||
| 1070 | memset(&info->status, 0, sizeof(info->status)); | 1084 | memset(&info->status, 0, sizeof(info->status)); |
| @@ -1072,9 +1086,11 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
| 1072 | if (status == TX_STATUS_FAIL_PASSIVE_NO_RX && | 1086 | if (status == TX_STATUS_FAIL_PASSIVE_NO_RX && |
| 1073 | iwl_is_associated_ctx(ctx) && ctx->vif && | 1087 | iwl_is_associated_ctx(ctx) && ctx->vif && |
| 1074 | ctx->vif->type == NL80211_IFTYPE_STATION) { | 1088 | ctx->vif->type == NL80211_IFTYPE_STATION) { |
| 1075 | ctx->last_tx_rejected = true; | 1089 | /* block and stop all queues */ |
| 1076 | iwl_trans_stop_queue(trans(priv), txq_id, | 1090 | priv->passive_no_rx = true; |
| 1077 | "Tx on passive channel"); | 1091 | IWL_DEBUG_TX_QUEUES(priv, "stop all queues: " |
| 1092 | "passive channel"); | ||
| 1093 | ieee80211_stop_queues(priv->hw); | ||
| 1078 | 1094 | ||
| 1079 | IWL_DEBUG_TX_REPLY(priv, | 1095 | IWL_DEBUG_TX_REPLY(priv, |
| 1080 | "TXQ %d status %s (0x%08x) " | 1096 | "TXQ %d status %s (0x%08x) " |
| @@ -1098,8 +1114,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
| 1098 | if (!is_agg) | 1114 | if (!is_agg) |
| 1099 | iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); | 1115 | iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); |
| 1100 | 1116 | ||
| 1101 | ieee80211_tx_status_irqsafe(priv->hw, skb); | ||
| 1102 | |||
| 1103 | freed++; | 1117 | freed++; |
| 1104 | } | 1118 | } |
| 1105 | 1119 | ||
| @@ -1107,7 +1121,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
| 1107 | } | 1121 | } |
| 1108 | 1122 | ||
| 1109 | iwl_check_abort_status(priv, tx_resp->frame_count, status); | 1123 | iwl_check_abort_status(priv, tx_resp->frame_count, status); |
| 1110 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1124 | spin_unlock(&priv->sta_lock); |
| 1125 | |||
| 1126 | while (!skb_queue_empty(&skbs)) { | ||
| 1127 | skb = __skb_dequeue(&skbs); | ||
| 1128 | ieee80211_tx_status(priv->hw, skb); | ||
| 1129 | } | ||
| 1130 | |||
| 1111 | return 0; | 1131 | return 0; |
| 1112 | } | 1132 | } |
| 1113 | 1133 | ||
| @@ -1118,17 +1138,16 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
| 1118 | * of frames sent via aggregation. | 1138 | * of frames sent via aggregation. |
| 1119 | */ | 1139 | */ |
| 1120 | int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | 1140 | int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, |
| 1121 | struct iwl_rx_mem_buffer *rxb, | 1141 | struct iwl_rx_cmd_buffer *rxb, |
| 1122 | struct iwl_device_cmd *cmd) | 1142 | struct iwl_device_cmd *cmd) |
| 1123 | { | 1143 | { |
| 1124 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 1144 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 1125 | struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; | 1145 | struct iwl_compressed_ba_resp *ba_resp = (void *)pkt->data; |
| 1126 | struct iwl_ht_agg *agg; | 1146 | struct iwl_ht_agg *agg; |
| 1127 | struct sk_buff_head reclaimed_skbs; | 1147 | struct sk_buff_head reclaimed_skbs; |
| 1128 | struct ieee80211_tx_info *info; | 1148 | struct ieee80211_tx_info *info; |
| 1129 | struct ieee80211_hdr *hdr; | 1149 | struct ieee80211_hdr *hdr; |
| 1130 | struct sk_buff *skb; | 1150 | struct sk_buff *skb; |
| 1131 | unsigned long flags; | ||
| 1132 | int sta_id; | 1151 | int sta_id; |
| 1133 | int tid; | 1152 | int tid; |
| 1134 | int freed; | 1153 | int freed; |
| @@ -1140,7 +1159,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
| 1140 | * (in Tx queue's circular buffer) of first TFD/frame in window */ | 1159 | * (in Tx queue's circular buffer) of first TFD/frame in window */ |
| 1141 | u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); | 1160 | u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); |
| 1142 | 1161 | ||
| 1143 | if (scd_flow >= hw_params(priv).max_txq_num) { | 1162 | if (scd_flow >= cfg(priv)->base_params->num_of_queues) { |
| 1144 | IWL_ERR(priv, | 1163 | IWL_ERR(priv, |
| 1145 | "BUG_ON scd_flow is bigger than number of queues\n"); | 1164 | "BUG_ON scd_flow is bigger than number of queues\n"); |
| 1146 | return 0; | 1165 | return 0; |
| @@ -1150,12 +1169,12 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
| 1150 | tid = ba_resp->tid; | 1169 | tid = ba_resp->tid; |
| 1151 | agg = &priv->tid_data[sta_id][tid].agg; | 1170 | agg = &priv->tid_data[sta_id][tid].agg; |
| 1152 | 1171 | ||
| 1153 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1172 | spin_lock(&priv->sta_lock); |
| 1154 | 1173 | ||
| 1155 | if (unlikely(!agg->wait_for_ba)) { | 1174 | if (unlikely(!agg->wait_for_ba)) { |
| 1156 | if (unlikely(ba_resp->bitmap)) | 1175 | if (unlikely(ba_resp->bitmap)) |
| 1157 | IWL_ERR(priv, "Received BA when not expected\n"); | 1176 | IWL_ERR(priv, "Received BA when not expected\n"); |
| 1158 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1177 | spin_unlock(&priv->sta_lock); |
| 1159 | return 0; | 1178 | return 0; |
| 1160 | } | 1179 | } |
| 1161 | 1180 | ||
| @@ -1165,8 +1184,8 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
| 1165 | * block-ack window (we assume that they've been successfully | 1184 | * block-ack window (we assume that they've been successfully |
| 1166 | * transmitted ... if not, it's too late anyway). */ | 1185 | * transmitted ... if not, it's too late anyway). */ |
| 1167 | if (iwl_trans_reclaim(trans(priv), sta_id, tid, scd_flow, | 1186 | if (iwl_trans_reclaim(trans(priv), sta_id, tid, scd_flow, |
| 1168 | ba_resp_scd_ssn, 0, &reclaimed_skbs)) { | 1187 | ba_resp_scd_ssn, &reclaimed_skbs)) { |
| 1169 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1188 | spin_unlock(&priv->sta_lock); |
| 1170 | return 0; | 1189 | return 0; |
| 1171 | } | 1190 | } |
| 1172 | 1191 | ||
| @@ -1202,9 +1221,8 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
| 1202 | 1221 | ||
| 1203 | iwlagn_check_ratid_empty(priv, sta_id, tid); | 1222 | iwlagn_check_ratid_empty(priv, sta_id, tid); |
| 1204 | freed = 0; | 1223 | freed = 0; |
| 1205 | while (!skb_queue_empty(&reclaimed_skbs)) { | ||
| 1206 | 1224 | ||
| 1207 | skb = __skb_dequeue(&reclaimed_skbs); | 1225 | skb_queue_walk(&reclaimed_skbs, skb) { |
| 1208 | hdr = (struct ieee80211_hdr *)skb->data; | 1226 | hdr = (struct ieee80211_hdr *)skb->data; |
| 1209 | 1227 | ||
| 1210 | if (ieee80211_is_data_qos(hdr->frame_control)) | 1228 | if (ieee80211_is_data_qos(hdr->frame_control)) |
| @@ -1213,7 +1231,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
| 1213 | WARN_ON_ONCE(1); | 1231 | WARN_ON_ONCE(1); |
| 1214 | 1232 | ||
| 1215 | info = IEEE80211_SKB_CB(skb); | 1233 | info = IEEE80211_SKB_CB(skb); |
| 1216 | kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1])); | 1234 | kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1])); |
| 1217 | 1235 | ||
| 1218 | if (freed == 1) { | 1236 | if (freed == 1) { |
| 1219 | /* this is the first skb we deliver in this batch */ | 1237 | /* this is the first skb we deliver in this batch */ |
| @@ -1227,10 +1245,14 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
| 1227 | iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, | 1245 | iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, |
| 1228 | info); | 1246 | info); |
| 1229 | } | 1247 | } |
| 1248 | } | ||
| 1249 | |||
| 1250 | spin_unlock(&priv->sta_lock); | ||
| 1230 | 1251 | ||
| 1231 | ieee80211_tx_status_irqsafe(priv->hw, skb); | 1252 | while (!skb_queue_empty(&reclaimed_skbs)) { |
| 1253 | skb = __skb_dequeue(&reclaimed_skbs); | ||
| 1254 | ieee80211_tx_status(priv->hw, skb); | ||
| 1232 | } | 1255 | } |
| 1233 | 1256 | ||
| 1234 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
| 1235 | return 0; | 1257 | return 0; |
| 1236 | } | 1258 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index e0fef9f257c2..28422c03d673 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
| @@ -41,9 +41,7 @@ | |||
| 41 | 41 | ||
| 42 | #include <asm/div64.h> | 42 | #include <asm/div64.h> |
| 43 | 43 | ||
| 44 | #include "iwl-ucode.h" | ||
| 45 | #include "iwl-eeprom.h" | 44 | #include "iwl-eeprom.h" |
| 46 | #include "iwl-wifi.h" | ||
| 47 | #include "iwl-dev.h" | 45 | #include "iwl-dev.h" |
| 48 | #include "iwl-core.h" | 46 | #include "iwl-core.h" |
| 49 | #include "iwl-io.h" | 47 | #include "iwl-io.h" |
| @@ -134,7 +132,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) | |||
| 134 | * beacon contents. | 132 | * beacon contents. |
| 135 | */ | 133 | */ |
| 136 | 134 | ||
| 137 | lockdep_assert_held(&priv->shrd->mutex); | 135 | lockdep_assert_held(&priv->mutex); |
| 138 | 136 | ||
| 139 | if (!priv->beacon_ctx) { | 137 | if (!priv->beacon_ctx) { |
| 140 | IWL_ERR(priv, "trying to build beacon w/o beacon context!\n"); | 138 | IWL_ERR(priv, "trying to build beacon w/o beacon context!\n"); |
| @@ -199,7 +197,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) | |||
| 199 | cmd.data[1] = priv->beacon_skb->data; | 197 | cmd.data[1] = priv->beacon_skb->data; |
| 200 | cmd.dataflags[1] = IWL_HCMD_DFL_NOCOPY; | 198 | cmd.dataflags[1] = IWL_HCMD_DFL_NOCOPY; |
| 201 | 199 | ||
| 202 | return iwl_trans_send_cmd(trans(priv), &cmd); | 200 | return iwl_dvm_send_cmd(priv, &cmd); |
| 203 | } | 201 | } |
| 204 | 202 | ||
| 205 | static void iwl_bg_beacon_update(struct work_struct *work) | 203 | static void iwl_bg_beacon_update(struct work_struct *work) |
| @@ -208,7 +206,7 @@ static void iwl_bg_beacon_update(struct work_struct *work) | |||
| 208 | container_of(work, struct iwl_priv, beacon_update); | 206 | container_of(work, struct iwl_priv, beacon_update); |
| 209 | struct sk_buff *beacon; | 207 | struct sk_buff *beacon; |
| 210 | 208 | ||
| 211 | mutex_lock(&priv->shrd->mutex); | 209 | mutex_lock(&priv->mutex); |
| 212 | if (!priv->beacon_ctx) { | 210 | if (!priv->beacon_ctx) { |
| 213 | IWL_ERR(priv, "updating beacon w/o beacon context!\n"); | 211 | IWL_ERR(priv, "updating beacon w/o beacon context!\n"); |
| 214 | goto out; | 212 | goto out; |
| @@ -238,7 +236,7 @@ static void iwl_bg_beacon_update(struct work_struct *work) | |||
| 238 | 236 | ||
| 239 | iwlagn_send_beacon_cmd(priv); | 237 | iwlagn_send_beacon_cmd(priv); |
| 240 | out: | 238 | out: |
| 241 | mutex_unlock(&priv->shrd->mutex); | 239 | mutex_unlock(&priv->mutex); |
| 242 | } | 240 | } |
| 243 | 241 | ||
| 244 | static void iwl_bg_bt_runtime_config(struct work_struct *work) | 242 | static void iwl_bg_bt_runtime_config(struct work_struct *work) |
| @@ -246,11 +244,11 @@ static void iwl_bg_bt_runtime_config(struct work_struct *work) | |||
| 246 | struct iwl_priv *priv = | 244 | struct iwl_priv *priv = |
| 247 | container_of(work, struct iwl_priv, bt_runtime_config); | 245 | container_of(work, struct iwl_priv, bt_runtime_config); |
| 248 | 246 | ||
| 249 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 247 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 250 | return; | 248 | return; |
| 251 | 249 | ||
| 252 | /* dont send host command if rf-kill is on */ | 250 | /* dont send host command if rf-kill is on */ |
| 253 | if (!iwl_is_ready_rf(priv->shrd)) | 251 | if (!iwl_is_ready_rf(priv)) |
| 254 | return; | 252 | return; |
| 255 | iwlagn_send_advance_bt_config(priv); | 253 | iwlagn_send_advance_bt_config(priv); |
| 256 | } | 254 | } |
| @@ -261,13 +259,13 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work) | |||
| 261 | container_of(work, struct iwl_priv, bt_full_concurrency); | 259 | container_of(work, struct iwl_priv, bt_full_concurrency); |
| 262 | struct iwl_rxon_context *ctx; | 260 | struct iwl_rxon_context *ctx; |
| 263 | 261 | ||
| 264 | mutex_lock(&priv->shrd->mutex); | 262 | mutex_lock(&priv->mutex); |
| 265 | 263 | ||
| 266 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 264 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 267 | goto out; | 265 | goto out; |
| 268 | 266 | ||
| 269 | /* dont send host command if rf-kill is on */ | 267 | /* dont send host command if rf-kill is on */ |
| 270 | if (!iwl_is_ready_rf(priv->shrd)) | 268 | if (!iwl_is_ready_rf(priv)) |
| 271 | goto out; | 269 | goto out; |
| 272 | 270 | ||
| 273 | IWL_DEBUG_INFO(priv, "BT coex in %s mode\n", | 271 | IWL_DEBUG_INFO(priv, "BT coex in %s mode\n", |
| @@ -285,7 +283,7 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work) | |||
| 285 | 283 | ||
| 286 | iwlagn_send_advance_bt_config(priv); | 284 | iwlagn_send_advance_bt_config(priv); |
| 287 | out: | 285 | out: |
| 288 | mutex_unlock(&priv->shrd->mutex); | 286 | mutex_unlock(&priv->mutex); |
| 289 | } | 287 | } |
| 290 | 288 | ||
| 291 | /** | 289 | /** |
| @@ -302,11 +300,11 @@ static void iwl_bg_statistics_periodic(unsigned long data) | |||
| 302 | { | 300 | { |
| 303 | struct iwl_priv *priv = (struct iwl_priv *)data; | 301 | struct iwl_priv *priv = (struct iwl_priv *)data; |
| 304 | 302 | ||
| 305 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 303 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 306 | return; | 304 | return; |
| 307 | 305 | ||
| 308 | /* dont send host command if rf-kill is on */ | 306 | /* dont send host command if rf-kill is on */ |
| 309 | if (!iwl_is_ready_rf(priv->shrd)) | 307 | if (!iwl_is_ready_rf(priv)) |
| 310 | return; | 308 | return; |
| 311 | 309 | ||
| 312 | iwl_send_statistics_request(priv, CMD_ASYNC, false); | 310 | iwl_send_statistics_request(priv, CMD_ASYNC, false); |
| @@ -329,14 +327,13 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, | |||
| 329 | 327 | ||
| 330 | /* Make sure device is powered up for SRAM reads */ | 328 | /* Make sure device is powered up for SRAM reads */ |
| 331 | spin_lock_irqsave(&trans(priv)->reg_lock, reg_flags); | 329 | spin_lock_irqsave(&trans(priv)->reg_lock, reg_flags); |
| 332 | if (iwl_grab_nic_access(trans(priv))) { | 330 | if (unlikely(!iwl_grab_nic_access(trans(priv)))) { |
| 333 | spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags); | 331 | spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags); |
| 334 | return; | 332 | return; |
| 335 | } | 333 | } |
| 336 | 334 | ||
| 337 | /* Set starting address; reads will auto-increment */ | 335 | /* Set starting address; reads will auto-increment */ |
| 338 | iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, ptr); | 336 | iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, ptr); |
| 339 | rmb(); | ||
| 340 | 337 | ||
| 341 | /* | 338 | /* |
| 342 | * Refuse to read more than would have fit into the log from | 339 | * Refuse to read more than would have fit into the log from |
| @@ -355,11 +352,12 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, | |||
| 355 | ev = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); | 352 | ev = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
| 356 | time = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); | 353 | time = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
| 357 | if (mode == 0) { | 354 | if (mode == 0) { |
| 358 | trace_iwlwifi_dev_ucode_cont_event(priv, 0, time, ev); | 355 | trace_iwlwifi_dev_ucode_cont_event( |
| 356 | trans(priv)->dev, 0, time, ev); | ||
| 359 | } else { | 357 | } else { |
| 360 | data = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); | 358 | data = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
| 361 | trace_iwlwifi_dev_ucode_cont_event(priv, time, | 359 | trace_iwlwifi_dev_ucode_cont_event( |
| 362 | data, ev); | 360 | trans(priv)->dev, time, data, ev); |
| 363 | } | 361 | } |
| 364 | } | 362 | } |
| 365 | /* Allow device to power down */ | 363 | /* Allow device to power down */ |
| @@ -424,7 +422,7 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv) | |||
| 424 | else | 422 | else |
| 425 | priv->event_log.wraps_once_count++; | 423 | priv->event_log.wraps_once_count++; |
| 426 | 424 | ||
| 427 | trace_iwlwifi_dev_ucode_wrap_event(priv, | 425 | trace_iwlwifi_dev_ucode_wrap_event(trans(priv)->dev, |
| 428 | num_wraps - priv->event_log.num_wraps, | 426 | num_wraps - priv->event_log.num_wraps, |
| 429 | next_entry, priv->event_log.next_entry); | 427 | next_entry, priv->event_log.next_entry); |
| 430 | 428 | ||
| @@ -463,7 +461,7 @@ static void iwl_bg_ucode_trace(unsigned long data) | |||
| 463 | { | 461 | { |
| 464 | struct iwl_priv *priv = (struct iwl_priv *)data; | 462 | struct iwl_priv *priv = (struct iwl_priv *)data; |
| 465 | 463 | ||
| 466 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 464 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 467 | return; | 465 | return; |
| 468 | 466 | ||
| 469 | if (priv->event_log.ucode_trace) { | 467 | if (priv->event_log.ucode_trace) { |
| @@ -479,18 +477,18 @@ static void iwl_bg_tx_flush(struct work_struct *work) | |||
| 479 | struct iwl_priv *priv = | 477 | struct iwl_priv *priv = |
| 480 | container_of(work, struct iwl_priv, tx_flush); | 478 | container_of(work, struct iwl_priv, tx_flush); |
| 481 | 479 | ||
| 482 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 480 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 483 | return; | 481 | return; |
| 484 | 482 | ||
| 485 | /* do nothing if rf-kill is on */ | 483 | /* do nothing if rf-kill is on */ |
| 486 | if (!iwl_is_ready_rf(priv->shrd)) | 484 | if (!iwl_is_ready_rf(priv)) |
| 487 | return; | 485 | return; |
| 488 | 486 | ||
| 489 | IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n"); | 487 | IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n"); |
| 490 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); | 488 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); |
| 491 | } | 489 | } |
| 492 | 490 | ||
| 493 | void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) | 491 | static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) |
| 494 | { | 492 | { |
| 495 | int i; | 493 | int i; |
| 496 | 494 | ||
| @@ -552,13 +550,11 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) | |||
| 552 | { | 550 | { |
| 553 | struct iwl_ct_kill_config cmd; | 551 | struct iwl_ct_kill_config cmd; |
| 554 | struct iwl_ct_kill_throttling_config adv_cmd; | 552 | struct iwl_ct_kill_throttling_config adv_cmd; |
| 555 | unsigned long flags; | ||
| 556 | int ret = 0; | 553 | int ret = 0; |
| 557 | 554 | ||
| 558 | spin_lock_irqsave(&priv->shrd->lock, flags); | ||
| 559 | iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, | 555 | iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, |
| 560 | CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); | 556 | CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); |
| 561 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | 557 | |
| 562 | priv->thermal_throttle.ct_kill_toggle = false; | 558 | priv->thermal_throttle.ct_kill_toggle = false; |
| 563 | 559 | ||
| 564 | if (cfg(priv)->base_params->support_ct_kill_exit) { | 560 | if (cfg(priv)->base_params->support_ct_kill_exit) { |
| @@ -567,7 +563,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) | |||
| 567 | adv_cmd.critical_temperature_exit = | 563 | adv_cmd.critical_temperature_exit = |
| 568 | cpu_to_le32(hw_params(priv).ct_kill_exit_threshold); | 564 | cpu_to_le32(hw_params(priv).ct_kill_exit_threshold); |
| 569 | 565 | ||
| 570 | ret = iwl_trans_send_cmd_pdu(trans(priv), | 566 | ret = iwl_dvm_send_cmd_pdu(priv, |
| 571 | REPLY_CT_KILL_CONFIG_CMD, | 567 | REPLY_CT_KILL_CONFIG_CMD, |
| 572 | CMD_SYNC, sizeof(adv_cmd), &adv_cmd); | 568 | CMD_SYNC, sizeof(adv_cmd), &adv_cmd); |
| 573 | if (ret) | 569 | if (ret) |
| @@ -582,7 +578,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) | |||
| 582 | cmd.critical_temperature_R = | 578 | cmd.critical_temperature_R = |
| 583 | cpu_to_le32(hw_params(priv).ct_kill_threshold); | 579 | cpu_to_le32(hw_params(priv).ct_kill_threshold); |
| 584 | 580 | ||
| 585 | ret = iwl_trans_send_cmd_pdu(trans(priv), | 581 | ret = iwl_dvm_send_cmd_pdu(priv, |
| 586 | REPLY_CT_KILL_CONFIG_CMD, | 582 | REPLY_CT_KILL_CONFIG_CMD, |
| 587 | CMD_SYNC, sizeof(cmd), &cmd); | 583 | CMD_SYNC, sizeof(cmd), &cmd); |
| 588 | if (ret) | 584 | if (ret) |
| @@ -608,7 +604,7 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg) | |||
| 608 | calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_RT_CFG_ALL; | 604 | calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_RT_CFG_ALL; |
| 609 | calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg); | 605 | calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg); |
| 610 | 606 | ||
| 611 | return iwl_trans_send_cmd(trans(priv), &cmd); | 607 | return iwl_dvm_send_cmd(priv, &cmd); |
| 612 | } | 608 | } |
| 613 | 609 | ||
| 614 | 610 | ||
| @@ -618,9 +614,9 @@ static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant) | |||
| 618 | .valid = cpu_to_le32(valid_tx_ant), | 614 | .valid = cpu_to_le32(valid_tx_ant), |
| 619 | }; | 615 | }; |
| 620 | 616 | ||
| 621 | if (IWL_UCODE_API(nic(priv)->fw.ucode_ver) > 1) { | 617 | if (IWL_UCODE_API(priv->fw->ucode_ver) > 1) { |
| 622 | IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant); | 618 | IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant); |
| 623 | return iwl_trans_send_cmd_pdu(trans(priv), | 619 | return iwl_dvm_send_cmd_pdu(priv, |
| 624 | TX_ANT_CONFIGURATION_CMD, | 620 | TX_ANT_CONFIGURATION_CMD, |
| 625 | CMD_SYNC, | 621 | CMD_SYNC, |
| 626 | sizeof(struct iwl_tx_ant_config_cmd), | 622 | sizeof(struct iwl_tx_ant_config_cmd), |
| @@ -644,12 +640,12 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
| 644 | IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); | 640 | IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); |
| 645 | 641 | ||
| 646 | /* After the ALIVE response, we can send host commands to the uCode */ | 642 | /* After the ALIVE response, we can send host commands to the uCode */ |
| 647 | set_bit(STATUS_ALIVE, &priv->shrd->status); | 643 | set_bit(STATUS_ALIVE, &priv->status); |
| 648 | 644 | ||
| 649 | /* Enable watchdog to monitor the driver tx queues */ | 645 | /* Enable watchdog to monitor the driver tx queues */ |
| 650 | iwl_setup_watchdog(priv); | 646 | iwl_setup_watchdog(priv); |
| 651 | 647 | ||
| 652 | if (iwl_is_rfkill(priv->shrd)) | 648 | if (iwl_is_rfkill(priv)) |
| 653 | return -ERFKILL; | 649 | return -ERFKILL; |
| 654 | 650 | ||
| 655 | if (priv->event_log.ucode_trace) { | 651 | if (priv->event_log.ucode_trace) { |
| @@ -673,14 +669,14 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
| 673 | priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS; | 669 | priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS; |
| 674 | priv->cur_rssi_ctx = NULL; | 670 | priv->cur_rssi_ctx = NULL; |
| 675 | 671 | ||
| 676 | iwl_send_prio_tbl(trans(priv)); | 672 | iwl_send_prio_tbl(priv); |
| 677 | 673 | ||
| 678 | /* FIXME: w/a to force change uCode BT state machine */ | 674 | /* FIXME: w/a to force change uCode BT state machine */ |
| 679 | ret = iwl_send_bt_env(trans(priv), IWL_BT_COEX_ENV_OPEN, | 675 | ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, |
| 680 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | 676 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); |
| 681 | if (ret) | 677 | if (ret) |
| 682 | return ret; | 678 | return ret; |
| 683 | ret = iwl_send_bt_env(trans(priv), IWL_BT_COEX_ENV_CLOSE, | 679 | ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE, |
| 684 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | 680 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); |
| 685 | if (ret) | 681 | if (ret) |
| 686 | return ret; | 682 | return ret; |
| @@ -701,9 +697,9 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
| 701 | priv->active_rate = IWL_RATES_MASK; | 697 | priv->active_rate = IWL_RATES_MASK; |
| 702 | 698 | ||
| 703 | /* Configure Tx antenna selection based on H/W config */ | 699 | /* Configure Tx antenna selection based on H/W config */ |
| 704 | iwlagn_send_tx_ant_config(priv, cfg(priv)->valid_tx_ant); | 700 | iwlagn_send_tx_ant_config(priv, hw_params(priv).valid_tx_ant); |
| 705 | 701 | ||
| 706 | if (iwl_is_associated_ctx(ctx) && !priv->shrd->wowlan) { | 702 | if (iwl_is_associated_ctx(ctx) && !priv->wowlan) { |
| 707 | struct iwl_rxon_cmd *active_rxon = | 703 | struct iwl_rxon_cmd *active_rxon = |
| 708 | (struct iwl_rxon_cmd *)&ctx->active; | 704 | (struct iwl_rxon_cmd *)&ctx->active; |
| 709 | /* apply any changes in staging */ | 705 | /* apply any changes in staging */ |
| @@ -718,12 +714,12 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
| 718 | iwlagn_set_rxon_chain(priv, ctx); | 714 | iwlagn_set_rxon_chain(priv, ctx); |
| 719 | } | 715 | } |
| 720 | 716 | ||
| 721 | if (!priv->shrd->wowlan) { | 717 | if (!priv->wowlan) { |
| 722 | /* WoWLAN ucode will not reply in the same way, skip it */ | 718 | /* WoWLAN ucode will not reply in the same way, skip it */ |
| 723 | iwl_reset_run_time_calib(priv); | 719 | iwl_reset_run_time_calib(priv); |
| 724 | } | 720 | } |
| 725 | 721 | ||
| 726 | set_bit(STATUS_READY, &priv->shrd->status); | 722 | set_bit(STATUS_READY, &priv->status); |
| 727 | 723 | ||
| 728 | /* Configure the adapter for unassociated operation */ | 724 | /* Configure the adapter for unassociated operation */ |
| 729 | ret = iwlagn_commit_rxon(priv, ctx); | 725 | ret = iwlagn_commit_rxon(priv, ctx); |
| @@ -738,13 +734,47 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
| 738 | return iwl_power_update_mode(priv, true); | 734 | return iwl_power_update_mode(priv, true); |
| 739 | } | 735 | } |
| 740 | 736 | ||
| 737 | /** | ||
| 738 | * iwl_clear_driver_stations - clear knowledge of all stations from driver | ||
| 739 | * @priv: iwl priv struct | ||
| 740 | * | ||
| 741 | * This is called during iwl_down() to make sure that in the case | ||
| 742 | * we're coming there from a hardware restart mac80211 will be | ||
| 743 | * able to reconfigure stations -- if we're getting there in the | ||
| 744 | * normal down flow then the stations will already be cleared. | ||
| 745 | */ | ||
| 746 | static void iwl_clear_driver_stations(struct iwl_priv *priv) | ||
| 747 | { | ||
| 748 | struct iwl_rxon_context *ctx; | ||
| 749 | |||
| 750 | spin_lock_bh(&priv->sta_lock); | ||
| 751 | memset(priv->stations, 0, sizeof(priv->stations)); | ||
| 752 | priv->num_stations = 0; | ||
| 753 | |||
| 754 | priv->ucode_key_table = 0; | ||
| 755 | |||
| 756 | for_each_context(priv, ctx) { | ||
| 757 | /* | ||
| 758 | * Remove all key information that is not stored as part | ||
| 759 | * of station information since mac80211 may not have had | ||
| 760 | * a chance to remove all the keys. When device is | ||
| 761 | * reconfigured by mac80211 after an error all keys will | ||
| 762 | * be reconfigured. | ||
| 763 | */ | ||
| 764 | memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys)); | ||
| 765 | ctx->key_mapping_keys = 0; | ||
| 766 | } | ||
| 767 | |||
| 768 | spin_unlock_bh(&priv->sta_lock); | ||
| 769 | } | ||
| 770 | |||
| 741 | void iwl_down(struct iwl_priv *priv) | 771 | void iwl_down(struct iwl_priv *priv) |
| 742 | { | 772 | { |
| 743 | int exit_pending; | 773 | int exit_pending; |
| 744 | 774 | ||
| 745 | IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); | 775 | IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); |
| 746 | 776 | ||
| 747 | lockdep_assert_held(&priv->shrd->mutex); | 777 | lockdep_assert_held(&priv->mutex); |
| 748 | 778 | ||
| 749 | iwl_scan_cancel_timeout(priv, 200); | 779 | iwl_scan_cancel_timeout(priv, 200); |
| 750 | 780 | ||
| @@ -756,7 +786,7 @@ void iwl_down(struct iwl_priv *priv) | |||
| 756 | ieee80211_remain_on_channel_expired(priv->hw); | 786 | ieee80211_remain_on_channel_expired(priv->hw); |
| 757 | 787 | ||
| 758 | exit_pending = | 788 | exit_pending = |
| 759 | test_and_set_bit(STATUS_EXIT_PENDING, &priv->shrd->status); | 789 | test_and_set_bit(STATUS_EXIT_PENDING, &priv->status); |
| 760 | 790 | ||
| 761 | /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set | 791 | /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set |
| 762 | * to prevent rearm timer */ | 792 | * to prevent rearm timer */ |
| @@ -781,7 +811,7 @@ void iwl_down(struct iwl_priv *priv) | |||
| 781 | /* Wipe out the EXIT_PENDING status bit if we are not actually | 811 | /* Wipe out the EXIT_PENDING status bit if we are not actually |
| 782 | * exiting the module */ | 812 | * exiting the module */ |
| 783 | if (!exit_pending) | 813 | if (!exit_pending) |
| 784 | clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status); | 814 | clear_bit(STATUS_EXIT_PENDING, &priv->status); |
| 785 | 815 | ||
| 786 | if (priv->mac80211_registered) | 816 | if (priv->mac80211_registered) |
| 787 | ieee80211_stop_queues(priv->hw); | 817 | ieee80211_stop_queues(priv->hw); |
| @@ -789,15 +819,15 @@ void iwl_down(struct iwl_priv *priv) | |||
| 789 | iwl_trans_stop_device(trans(priv)); | 819 | iwl_trans_stop_device(trans(priv)); |
| 790 | 820 | ||
| 791 | /* Clear out all status bits but a few that are stable across reset */ | 821 | /* Clear out all status bits but a few that are stable across reset */ |
| 792 | priv->shrd->status &= | 822 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << |
| 793 | test_bit(STATUS_RF_KILL_HW, &priv->shrd->status) << | ||
| 794 | STATUS_RF_KILL_HW | | 823 | STATUS_RF_KILL_HW | |
| 795 | test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status) << | 824 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
| 796 | STATUS_GEO_CONFIGURED | | 825 | STATUS_GEO_CONFIGURED | |
| 797 | test_bit(STATUS_FW_ERROR, &priv->shrd->status) << | 826 | test_bit(STATUS_EXIT_PENDING, &priv->status) << |
| 798 | STATUS_FW_ERROR | | ||
| 799 | test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) << | ||
| 800 | STATUS_EXIT_PENDING; | 827 | STATUS_EXIT_PENDING; |
| 828 | priv->shrd->status &= | ||
| 829 | test_bit(STATUS_FW_ERROR, &priv->shrd->status) << | ||
| 830 | STATUS_FW_ERROR; | ||
| 801 | 831 | ||
| 802 | dev_kfree_skb(priv->beacon_skb); | 832 | dev_kfree_skb(priv->beacon_skb); |
| 803 | priv->beacon_skb = NULL; | 833 | priv->beacon_skb = NULL; |
| @@ -814,11 +844,11 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) | |||
| 814 | struct iwl_priv *priv = container_of(work, struct iwl_priv, | 844 | struct iwl_priv *priv = container_of(work, struct iwl_priv, |
| 815 | run_time_calib_work); | 845 | run_time_calib_work); |
| 816 | 846 | ||
| 817 | mutex_lock(&priv->shrd->mutex); | 847 | mutex_lock(&priv->mutex); |
| 818 | 848 | ||
| 819 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) || | 849 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || |
| 820 | test_bit(STATUS_SCANNING, &priv->shrd->status)) { | 850 | test_bit(STATUS_SCANNING, &priv->status)) { |
| 821 | mutex_unlock(&priv->shrd->mutex); | 851 | mutex_unlock(&priv->mutex); |
| 822 | return; | 852 | return; |
| 823 | } | 853 | } |
| 824 | 854 | ||
| @@ -827,7 +857,7 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) | |||
| 827 | iwl_sensitivity_calibration(priv); | 857 | iwl_sensitivity_calibration(priv); |
| 828 | } | 858 | } |
| 829 | 859 | ||
| 830 | mutex_unlock(&priv->shrd->mutex); | 860 | mutex_unlock(&priv->mutex); |
| 831 | } | 861 | } |
| 832 | 862 | ||
| 833 | void iwlagn_prepare_restart(struct iwl_priv *priv) | 863 | void iwlagn_prepare_restart(struct iwl_priv *priv) |
| @@ -839,7 +869,7 @@ void iwlagn_prepare_restart(struct iwl_priv *priv) | |||
| 839 | u8 bt_status; | 869 | u8 bt_status; |
| 840 | bool bt_is_sco; | 870 | bool bt_is_sco; |
| 841 | 871 | ||
| 842 | lockdep_assert_held(&priv->shrd->mutex); | 872 | lockdep_assert_held(&priv->mutex); |
| 843 | 873 | ||
| 844 | for_each_context(priv, ctx) | 874 | for_each_context(priv, ctx) |
| 845 | ctx->vif = NULL; | 875 | ctx->vif = NULL; |
| @@ -873,13 +903,13 @@ static void iwl_bg_restart(struct work_struct *data) | |||
| 873 | { | 903 | { |
| 874 | struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); | 904 | struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); |
| 875 | 905 | ||
| 876 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 906 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 877 | return; | 907 | return; |
| 878 | 908 | ||
| 879 | if (test_and_clear_bit(STATUS_FW_ERROR, &priv->shrd->status)) { | 909 | if (test_and_clear_bit(STATUS_FW_ERROR, &priv->shrd->status)) { |
| 880 | mutex_lock(&priv->shrd->mutex); | 910 | mutex_lock(&priv->mutex); |
| 881 | iwlagn_prepare_restart(priv); | 911 | iwlagn_prepare_restart(priv); |
| 882 | mutex_unlock(&priv->shrd->mutex); | 912 | mutex_unlock(&priv->mutex); |
| 883 | iwl_cancel_deferred_work(priv); | 913 | iwl_cancel_deferred_work(priv); |
| 884 | ieee80211_restart_hw(priv->hw); | 914 | ieee80211_restart_hw(priv->hw); |
| 885 | } else { | 915 | } else { |
| @@ -894,7 +924,7 @@ void iwlagn_disable_roc(struct iwl_priv *priv) | |||
| 894 | { | 924 | { |
| 895 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; | 925 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; |
| 896 | 926 | ||
| 897 | lockdep_assert_held(&priv->shrd->mutex); | 927 | lockdep_assert_held(&priv->mutex); |
| 898 | 928 | ||
| 899 | if (!priv->hw_roc_setup) | 929 | if (!priv->hw_roc_setup) |
| 900 | return; | 930 | return; |
| @@ -917,9 +947,9 @@ static void iwlagn_disable_roc_work(struct work_struct *work) | |||
| 917 | struct iwl_priv *priv = container_of(work, struct iwl_priv, | 947 | struct iwl_priv *priv = container_of(work, struct iwl_priv, |
| 918 | hw_roc_disable_work.work); | 948 | hw_roc_disable_work.work); |
| 919 | 949 | ||
| 920 | mutex_lock(&priv->shrd->mutex); | 950 | mutex_lock(&priv->mutex); |
| 921 | iwlagn_disable_roc(priv); | 951 | iwlagn_disable_roc(priv); |
| 922 | mutex_unlock(&priv->shrd->mutex); | 952 | mutex_unlock(&priv->mutex); |
| 923 | } | 953 | } |
| 924 | 954 | ||
| 925 | /***************************************************************************** | 955 | /***************************************************************************** |
| @@ -945,8 +975,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
| 945 | 975 | ||
| 946 | iwl_setup_scan_deferred_work(priv); | 976 | iwl_setup_scan_deferred_work(priv); |
| 947 | 977 | ||
| 948 | if (cfg(priv)->lib->bt_setup_deferred_work) | 978 | if (cfg(priv)->bt_params) |
| 949 | cfg(priv)->lib->bt_setup_deferred_work(priv); | 979 | iwlagn_bt_setup_deferred_work(priv); |
| 950 | 980 | ||
| 951 | init_timer(&priv->statistics_periodic); | 981 | init_timer(&priv->statistics_periodic); |
| 952 | priv->statistics_periodic.data = (unsigned long)priv; | 982 | priv->statistics_periodic.data = (unsigned long)priv; |
| @@ -963,8 +993,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
| 963 | 993 | ||
| 964 | void iwl_cancel_deferred_work(struct iwl_priv *priv) | 994 | void iwl_cancel_deferred_work(struct iwl_priv *priv) |
| 965 | { | 995 | { |
| 966 | if (cfg(priv)->lib->cancel_deferred_work) | 996 | if (cfg(priv)->bt_params) |
| 967 | cfg(priv)->lib->cancel_deferred_work(priv); | 997 | iwlagn_bt_cancel_deferred_work(priv); |
| 968 | 998 | ||
| 969 | cancel_work_sync(&priv->run_time_calib_work); | 999 | cancel_work_sync(&priv->run_time_calib_work); |
| 970 | cancel_work_sync(&priv->beacon_update); | 1000 | cancel_work_sync(&priv->beacon_update); |
| @@ -979,8 +1009,7 @@ void iwl_cancel_deferred_work(struct iwl_priv *priv) | |||
| 979 | del_timer_sync(&priv->ucode_trace); | 1009 | del_timer_sync(&priv->ucode_trace); |
| 980 | } | 1010 | } |
| 981 | 1011 | ||
| 982 | static void iwl_init_hw_rates(struct iwl_priv *priv, | 1012 | static void iwl_init_hw_rates(struct ieee80211_rate *rates) |
| 983 | struct ieee80211_rate *rates) | ||
| 984 | { | 1013 | { |
| 985 | int i; | 1014 | int i; |
| 986 | 1015 | ||
| @@ -1004,21 +1033,26 @@ static int iwl_init_drv(struct iwl_priv *priv) | |||
| 1004 | { | 1033 | { |
| 1005 | int ret; | 1034 | int ret; |
| 1006 | 1035 | ||
| 1007 | spin_lock_init(&priv->shrd->sta_lock); | 1036 | spin_lock_init(&priv->sta_lock); |
| 1008 | 1037 | ||
| 1009 | mutex_init(&priv->shrd->mutex); | 1038 | mutex_init(&priv->mutex); |
| 1010 | 1039 | ||
| 1011 | INIT_LIST_HEAD(&trans(priv)->calib_results); | 1040 | INIT_LIST_HEAD(&priv->calib_results); |
| 1012 | 1041 | ||
| 1013 | priv->ieee_channels = NULL; | 1042 | priv->ieee_channels = NULL; |
| 1014 | priv->ieee_rates = NULL; | 1043 | priv->ieee_rates = NULL; |
| 1015 | priv->band = IEEE80211_BAND_2GHZ; | 1044 | priv->band = IEEE80211_BAND_2GHZ; |
| 1016 | 1045 | ||
| 1046 | priv->plcp_delta_threshold = | ||
| 1047 | cfg(priv)->base_params->plcp_delta_threshold; | ||
| 1048 | |||
| 1017 | priv->iw_mode = NL80211_IFTYPE_STATION; | 1049 | priv->iw_mode = NL80211_IFTYPE_STATION; |
| 1018 | priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; | 1050 | priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; |
| 1019 | priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; | 1051 | priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; |
| 1020 | priv->agg_tids_count = 0; | 1052 | priv->agg_tids_count = 0; |
| 1021 | 1053 | ||
| 1054 | priv->ucode_owner = IWL_OWNERSHIP_DRIVER; | ||
| 1055 | |||
| 1022 | /* initialize force reset */ | 1056 | /* initialize force reset */ |
| 1023 | priv->force_reset[IWL_RF_RESET].reset_duration = | 1057 | priv->force_reset[IWL_RF_RESET].reset_duration = |
| 1024 | IWL_DELAY_NEXT_FORCE_RF_RESET; | 1058 | IWL_DELAY_NEXT_FORCE_RF_RESET; |
| @@ -1054,7 +1088,7 @@ static int iwl_init_drv(struct iwl_priv *priv) | |||
| 1054 | IWL_ERR(priv, "initializing geos failed: %d\n", ret); | 1088 | IWL_ERR(priv, "initializing geos failed: %d\n", ret); |
| 1055 | goto err_free_channel_map; | 1089 | goto err_free_channel_map; |
| 1056 | } | 1090 | } |
| 1057 | iwl_init_hw_rates(priv, priv->ieee_rates); | 1091 | iwl_init_hw_rates(priv->ieee_rates); |
| 1058 | 1092 | ||
| 1059 | return 0; | 1093 | return 0; |
| 1060 | 1094 | ||
| @@ -1068,11 +1102,10 @@ static void iwl_uninit_drv(struct iwl_priv *priv) | |||
| 1068 | { | 1102 | { |
| 1069 | iwl_free_geos(priv); | 1103 | iwl_free_geos(priv); |
| 1070 | iwl_free_channel_map(priv); | 1104 | iwl_free_channel_map(priv); |
| 1071 | if (priv->tx_cmd_pool) | ||
| 1072 | kmem_cache_destroy(priv->tx_cmd_pool); | ||
| 1073 | kfree(priv->scan_cmd); | 1105 | kfree(priv->scan_cmd); |
| 1074 | kfree(priv->beacon_cmd); | 1106 | kfree(priv->beacon_cmd); |
| 1075 | kfree(rcu_dereference_raw(priv->noa_data)); | 1107 | kfree(rcu_dereference_raw(priv->noa_data)); |
| 1108 | iwl_calib_free_results(priv); | ||
| 1076 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 1109 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
| 1077 | kfree(priv->wowlan_sram); | 1110 | kfree(priv->wowlan_sram); |
| 1078 | #endif | 1111 | #endif |
| @@ -1084,6 +1117,10 @@ static void iwl_uninit_drv(struct iwl_priv *priv) | |||
| 1084 | 1117 | ||
| 1085 | static void iwl_set_hw_params(struct iwl_priv *priv) | 1118 | static void iwl_set_hw_params(struct iwl_priv *priv) |
| 1086 | { | 1119 | { |
| 1120 | if (cfg(priv)->ht_params) | ||
| 1121 | hw_params(priv).use_rts_for_aggregation = | ||
| 1122 | cfg(priv)->ht_params->use_rts_for_aggregation; | ||
| 1123 | |||
| 1087 | if (iwlagn_mod_params.amsdu_size_8K) | 1124 | if (iwlagn_mod_params.amsdu_size_8K) |
| 1088 | hw_params(priv).rx_page_order = | 1125 | hw_params(priv).rx_page_order = |
| 1089 | get_order(IWL_RX_BUF_SIZE_8K); | 1126 | get_order(IWL_RX_BUF_SIZE_8K); |
| @@ -1092,13 +1129,10 @@ static void iwl_set_hw_params(struct iwl_priv *priv) | |||
| 1092 | get_order(IWL_RX_BUF_SIZE_4K); | 1129 | get_order(IWL_RX_BUF_SIZE_4K); |
| 1093 | 1130 | ||
| 1094 | if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_ALL) | 1131 | if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_ALL) |
| 1095 | cfg(priv)->sku &= ~EEPROM_SKU_CAP_11N_ENABLE; | 1132 | hw_params(priv).sku &= ~EEPROM_SKU_CAP_11N_ENABLE; |
| 1096 | 1133 | ||
| 1097 | hw_params(priv).num_ampdu_queues = | 1134 | hw_params(priv).num_ampdu_queues = |
| 1098 | cfg(priv)->base_params->num_of_ampdu_queues; | 1135 | cfg(priv)->base_params->num_of_ampdu_queues; |
| 1099 | hw_params(priv).shadow_reg_enable = | ||
| 1100 | cfg(priv)->base_params->shadow_reg_enable; | ||
| 1101 | hw_params(priv).sku = cfg(priv)->sku; | ||
| 1102 | hw_params(priv).wd_timeout = cfg(priv)->base_params->wd_timeout; | 1136 | hw_params(priv).wd_timeout = cfg(priv)->base_params->wd_timeout; |
| 1103 | 1137 | ||
| 1104 | /* Device-specific setup */ | 1138 | /* Device-specific setup */ |
| @@ -1142,15 +1176,16 @@ static void iwl_debug_config(struct iwl_priv *priv) | |||
| 1142 | #endif | 1176 | #endif |
| 1143 | } | 1177 | } |
| 1144 | 1178 | ||
| 1145 | static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | 1179 | static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, |
| 1180 | const struct iwl_fw *fw) | ||
| 1146 | { | 1181 | { |
| 1147 | struct iwl_fw *fw = &nic(trans)->fw; | ||
| 1148 | int err = 0; | 1182 | int err = 0; |
| 1149 | struct iwl_priv *priv; | 1183 | struct iwl_priv *priv; |
| 1150 | struct ieee80211_hw *hw; | 1184 | struct ieee80211_hw *hw; |
| 1151 | struct iwl_op_mode *op_mode; | 1185 | struct iwl_op_mode *op_mode; |
| 1152 | u16 num_mac; | 1186 | u16 num_mac; |
| 1153 | u32 ucode_flags; | 1187 | u32 ucode_flags; |
| 1188 | struct iwl_trans_config trans_cfg; | ||
| 1154 | 1189 | ||
| 1155 | /************************ | 1190 | /************************ |
| 1156 | * 1. Allocating HW data | 1191 | * 1. Allocating HW data |
| @@ -1167,9 +1202,32 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
| 1167 | op_mode->ops = &iwl_dvm_ops; | 1202 | op_mode->ops = &iwl_dvm_ops; |
| 1168 | priv = IWL_OP_MODE_GET_DVM(op_mode); | 1203 | priv = IWL_OP_MODE_GET_DVM(op_mode); |
| 1169 | priv->shrd = trans->shrd; | 1204 | priv->shrd = trans->shrd; |
| 1170 | priv->shrd->priv = priv; | 1205 | priv->fw = fw; |
| 1206 | /* TODO: remove fw from shared data later */ | ||
| 1207 | priv->shrd->fw = fw; | ||
| 1171 | 1208 | ||
| 1172 | iwl_trans_configure(trans(priv), op_mode); | 1209 | /* |
| 1210 | * Populate the state variables that the transport layer needs | ||
| 1211 | * to know about. | ||
| 1212 | */ | ||
| 1213 | trans_cfg.op_mode = op_mode; | ||
| 1214 | |||
| 1215 | ucode_flags = fw->ucode_capa.flags; | ||
| 1216 | |||
| 1217 | #ifndef CONFIG_IWLWIFI_P2P | ||
| 1218 | ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; | ||
| 1219 | #endif | ||
| 1220 | |||
| 1221 | if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) { | ||
| 1222 | priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; | ||
| 1223 | trans_cfg.cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; | ||
| 1224 | } else { | ||
| 1225 | priv->sta_key_max_num = STA_KEY_MAX_NUM; | ||
| 1226 | trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; | ||
| 1227 | } | ||
| 1228 | |||
| 1229 | /* Configure transport layer */ | ||
| 1230 | iwl_trans_configure(trans(priv), &trans_cfg); | ||
| 1173 | 1231 | ||
| 1174 | /* At this point both hw and priv are allocated. */ | 1232 | /* At this point both hw and priv are allocated. */ |
| 1175 | 1233 | ||
| @@ -1198,10 +1256,10 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
| 1198 | * we should init now | 1256 | * we should init now |
| 1199 | */ | 1257 | */ |
| 1200 | spin_lock_init(&trans(priv)->reg_lock); | 1258 | spin_lock_init(&trans(priv)->reg_lock); |
| 1201 | spin_lock_init(&priv->shrd->lock); | 1259 | spin_lock_init(&priv->statistics.lock); |
| 1202 | 1260 | ||
| 1203 | /*********************** | 1261 | /*********************** |
| 1204 | * 3. Read REV register | 1262 | * 2. Read REV register |
| 1205 | ***********************/ | 1263 | ***********************/ |
| 1206 | IWL_INFO(priv, "Detected %s, REV=0x%X\n", | 1264 | IWL_INFO(priv, "Detected %s, REV=0x%X\n", |
| 1207 | cfg(priv)->name, trans(priv)->hw_rev); | 1265 | cfg(priv)->name, trans(priv)->hw_rev); |
| @@ -1211,9 +1269,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
| 1211 | goto out_free_traffic_mem; | 1269 | goto out_free_traffic_mem; |
| 1212 | 1270 | ||
| 1213 | /***************** | 1271 | /***************** |
| 1214 | * 4. Read EEPROM | 1272 | * 3. Read EEPROM |
| 1215 | *****************/ | 1273 | *****************/ |
| 1216 | /* Read the EEPROM */ | ||
| 1217 | err = iwl_eeprom_init(trans(priv), trans(priv)->hw_rev); | 1274 | err = iwl_eeprom_init(trans(priv), trans(priv)->hw_rev); |
| 1218 | /* Reset chip to save power until we load uCode during "up". */ | 1275 | /* Reset chip to save power until we load uCode during "up". */ |
| 1219 | iwl_trans_stop_hw(trans(priv)); | 1276 | iwl_trans_stop_hw(trans(priv)); |
| @@ -1225,7 +1282,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
| 1225 | if (err) | 1282 | if (err) |
| 1226 | goto out_free_eeprom; | 1283 | goto out_free_eeprom; |
| 1227 | 1284 | ||
| 1228 | err = iwl_eeprom_check_sku(priv); | 1285 | err = iwl_eeprom_init_hw_params(priv); |
| 1229 | if (err) | 1286 | if (err) |
| 1230 | goto out_free_eeprom; | 1287 | goto out_free_eeprom; |
| 1231 | 1288 | ||
| @@ -1243,28 +1300,27 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
| 1243 | } | 1300 | } |
| 1244 | 1301 | ||
| 1245 | /************************ | 1302 | /************************ |
| 1246 | * 5. Setup HW constants | 1303 | * 4. Setup HW constants |
| 1247 | ************************/ | 1304 | ************************/ |
| 1248 | iwl_set_hw_params(priv); | 1305 | iwl_set_hw_params(priv); |
| 1249 | 1306 | ||
| 1250 | ucode_flags = fw->ucode_capa.flags; | 1307 | if (!(hw_params(priv).sku & EEPROM_SKU_CAP_IPAN_ENABLE)) { |
| 1251 | 1308 | IWL_DEBUG_INFO(priv, "Your EEPROM disabled PAN"); | |
| 1252 | #ifndef CONFIG_IWLWIFI_P2P | ||
| 1253 | ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; | ||
| 1254 | #endif | ||
| 1255 | if (!(hw_params(priv).sku & EEPROM_SKU_CAP_IPAN_ENABLE)) | ||
| 1256 | ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; | 1309 | ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; |
| 1257 | 1310 | /* | |
| 1258 | /* | 1311 | * if not PAN, then don't support P2P -- might be a uCode |
| 1259 | * if not PAN, then don't support P2P -- might be a uCode | 1312 | * packaging bug or due to the eeprom check above |
| 1260 | * packaging bug or due to the eeprom check above | 1313 | */ |
| 1261 | */ | ||
| 1262 | if (!(ucode_flags & IWL_UCODE_TLV_FLAGS_PAN)) | ||
| 1263 | ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P; | 1314 | ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P; |
| 1315 | priv->sta_key_max_num = STA_KEY_MAX_NUM; | ||
| 1316 | trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; | ||
| 1264 | 1317 | ||
| 1318 | /* Configure transport layer again*/ | ||
| 1319 | iwl_trans_configure(trans(priv), &trans_cfg); | ||
| 1320 | } | ||
| 1265 | 1321 | ||
| 1266 | /******************* | 1322 | /******************* |
| 1267 | * 6. Setup priv | 1323 | * 5. Setup priv |
| 1268 | *******************/ | 1324 | *******************/ |
| 1269 | 1325 | ||
| 1270 | err = iwl_init_drv(priv); | 1326 | err = iwl_init_drv(priv); |
| @@ -1273,7 +1329,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
| 1273 | /* At this point both hw and priv are initialized. */ | 1329 | /* At this point both hw and priv are initialized. */ |
| 1274 | 1330 | ||
| 1275 | /******************** | 1331 | /******************** |
| 1276 | * 7. Setup services | 1332 | * 6. Setup services |
| 1277 | ********************/ | 1333 | ********************/ |
| 1278 | iwl_setup_deferred_work(priv); | 1334 | iwl_setup_deferred_work(priv); |
| 1279 | iwl_setup_rx_handlers(priv); | 1335 | iwl_setup_rx_handlers(priv); |
| @@ -1289,14 +1345,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
| 1289 | priv->new_scan_threshold_behaviour = | 1345 | priv->new_scan_threshold_behaviour = |
| 1290 | !!(ucode_flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); | 1346 | !!(ucode_flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); |
| 1291 | 1347 | ||
| 1292 | if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) { | ||
| 1293 | priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; | ||
| 1294 | priv->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; | ||
| 1295 | } else { | ||
| 1296 | priv->sta_key_max_num = STA_KEY_MAX_NUM; | ||
| 1297 | priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; | ||
| 1298 | } | ||
| 1299 | |||
| 1300 | priv->phy_calib_chain_noise_reset_cmd = | 1348 | priv->phy_calib_chain_noise_reset_cmd = |
| 1301 | fw->ucode_capa.standard_phy_calibration_size; | 1349 | fw->ucode_capa.standard_phy_calibration_size; |
| 1302 | priv->phy_calib_chain_noise_gain_cmd = | 1350 | priv->phy_calib_chain_noise_gain_cmd = |
| @@ -1308,7 +1356,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
| 1308 | /************************************************** | 1356 | /************************************************** |
| 1309 | * This is still part of probe() in a sense... | 1357 | * This is still part of probe() in a sense... |
| 1310 | * | 1358 | * |
| 1311 | * 9. Setup and register with mac80211 and debugfs | 1359 | * 7. Setup and register with mac80211 and debugfs |
| 1312 | **************************************************/ | 1360 | **************************************************/ |
| 1313 | err = iwlagn_mac_setup_register(priv, &fw->ucode_capa); | 1361 | err = iwlagn_mac_setup_register(priv, &fw->ucode_capa); |
| 1314 | if (err) | 1362 | if (err) |
| @@ -1340,18 +1388,10 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) | |||
| 1340 | { | 1388 | { |
| 1341 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 1389 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
| 1342 | 1390 | ||
| 1343 | wait_for_completion(&nic(priv)->request_firmware_complete); | ||
| 1344 | |||
| 1345 | IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); | 1391 | IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); |
| 1346 | 1392 | ||
| 1347 | iwl_dbgfs_unregister(priv); | 1393 | iwl_dbgfs_unregister(priv); |
| 1348 | 1394 | ||
| 1349 | /* ieee80211_unregister_hw call wil cause iwlagn_mac_stop to | ||
| 1350 | * to be called and iwl_down since we are removing the device | ||
| 1351 | * we need to set STATUS_EXIT_PENDING bit. | ||
| 1352 | */ | ||
| 1353 | set_bit(STATUS_EXIT_PENDING, &priv->shrd->status); | ||
| 1354 | |||
| 1355 | iwl_testmode_cleanup(priv); | 1395 | iwl_testmode_cleanup(priv); |
| 1356 | iwlagn_mac_unregister(priv); | 1396 | iwlagn_mac_unregister(priv); |
| 1357 | 1397 | ||
| @@ -1360,8 +1400,6 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) | |||
| 1360 | /*This will stop the queues, move the device to low power state */ | 1400 | /*This will stop the queues, move the device to low power state */ |
| 1361 | iwl_trans_stop_device(trans(priv)); | 1401 | iwl_trans_stop_device(trans(priv)); |
| 1362 | 1402 | ||
| 1363 | iwl_dealloc_ucode(nic(priv)); | ||
| 1364 | |||
| 1365 | iwl_eeprom_free(priv->shrd); | 1403 | iwl_eeprom_free(priv->shrd); |
| 1366 | 1404 | ||
| 1367 | /*netif_stop_queue(dev); */ | 1405 | /*netif_stop_queue(dev); */ |
| @@ -1381,6 +1419,60 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) | |||
| 1381 | ieee80211_free_hw(priv->hw); | 1419 | ieee80211_free_hw(priv->hw); |
| 1382 | } | 1420 | } |
| 1383 | 1421 | ||
| 1422 | static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode) | ||
| 1423 | { | ||
| 1424 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
| 1425 | |||
| 1426 | if (!iwl_check_for_ct_kill(priv)) { | ||
| 1427 | IWL_ERR(priv, "Restarting adapter queue is full\n"); | ||
| 1428 | iwl_nic_error(op_mode); | ||
| 1429 | } | ||
| 1430 | } | ||
| 1431 | |||
| 1432 | static void iwl_nic_config(struct iwl_op_mode *op_mode) | ||
| 1433 | { | ||
| 1434 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
| 1435 | |||
| 1436 | cfg(priv)->lib->nic_config(priv); | ||
| 1437 | } | ||
| 1438 | |||
| 1439 | static void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac) | ||
| 1440 | { | ||
| 1441 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
| 1442 | |||
| 1443 | set_bit(ac, &priv->transport_queue_stop); | ||
| 1444 | ieee80211_stop_queue(priv->hw, ac); | ||
| 1445 | } | ||
| 1446 | |||
| 1447 | static void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, u8 ac) | ||
| 1448 | { | ||
| 1449 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
| 1450 | |||
| 1451 | clear_bit(ac, &priv->transport_queue_stop); | ||
| 1452 | |||
| 1453 | if (!priv->passive_no_rx) | ||
| 1454 | ieee80211_wake_queue(priv->hw, ac); | ||
| 1455 | } | ||
| 1456 | |||
| 1457 | void iwlagn_lift_passive_no_rx(struct iwl_priv *priv) | ||
| 1458 | { | ||
| 1459 | int ac; | ||
| 1460 | |||
| 1461 | if (!priv->passive_no_rx) | ||
| 1462 | return; | ||
| 1463 | |||
| 1464 | for (ac = IEEE80211_AC_VO; ac < IEEE80211_NUM_ACS; ac++) { | ||
| 1465 | if (!test_bit(ac, &priv->transport_queue_stop)) { | ||
| 1466 | IWL_DEBUG_TX_QUEUES(priv, "Wake queue %d"); | ||
| 1467 | ieee80211_wake_queue(priv->hw, ac); | ||
| 1468 | } else { | ||
| 1469 | IWL_DEBUG_TX_QUEUES(priv, "Don't wake queue %d"); | ||
| 1470 | } | ||
| 1471 | } | ||
| 1472 | |||
| 1473 | priv->passive_no_rx = false; | ||
| 1474 | } | ||
| 1475 | |||
| 1384 | const struct iwl_op_mode_ops iwl_dvm_ops = { | 1476 | const struct iwl_op_mode_ops iwl_dvm_ops = { |
| 1385 | .start = iwl_op_mode_dvm_start, | 1477 | .start = iwl_op_mode_dvm_start, |
| 1386 | .stop = iwl_op_mode_dvm_stop, | 1478 | .stop = iwl_op_mode_dvm_stop, |
| @@ -1390,6 +1482,8 @@ const struct iwl_op_mode_ops iwl_dvm_ops = { | |||
| 1390 | .hw_rf_kill = iwl_set_hw_rfkill_state, | 1482 | .hw_rf_kill = iwl_set_hw_rfkill_state, |
| 1391 | .free_skb = iwl_free_skb, | 1483 | .free_skb = iwl_free_skb, |
| 1392 | .nic_error = iwl_nic_error, | 1484 | .nic_error = iwl_nic_error, |
| 1485 | .cmd_queue_full = iwl_cmd_queue_full, | ||
| 1486 | .nic_config = iwl_nic_config, | ||
| 1393 | }; | 1487 | }; |
| 1394 | 1488 | ||
| 1395 | /***************************************************************************** | 1489 | /***************************************************************************** |
| @@ -1397,6 +1491,9 @@ const struct iwl_op_mode_ops iwl_dvm_ops = { | |||
| 1397 | * driver and module entry point | 1491 | * driver and module entry point |
| 1398 | * | 1492 | * |
| 1399 | *****************************************************************************/ | 1493 | *****************************************************************************/ |
| 1494 | |||
| 1495 | struct kmem_cache *iwl_tx_cmd_pool; | ||
| 1496 | |||
| 1400 | static int __init iwl_init(void) | 1497 | static int __init iwl_init(void) |
| 1401 | { | 1498 | { |
| 1402 | 1499 | ||
| @@ -1404,20 +1501,27 @@ static int __init iwl_init(void) | |||
| 1404 | pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); | 1501 | pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); |
| 1405 | pr_info(DRV_COPYRIGHT "\n"); | 1502 | pr_info(DRV_COPYRIGHT "\n"); |
| 1406 | 1503 | ||
| 1504 | iwl_tx_cmd_pool = kmem_cache_create("iwl_dev_cmd", | ||
| 1505 | sizeof(struct iwl_device_cmd), | ||
| 1506 | sizeof(void *), 0, NULL); | ||
| 1507 | if (!iwl_tx_cmd_pool) | ||
| 1508 | return -ENOMEM; | ||
| 1509 | |||
| 1407 | ret = iwlagn_rate_control_register(); | 1510 | ret = iwlagn_rate_control_register(); |
| 1408 | if (ret) { | 1511 | if (ret) { |
| 1409 | pr_err("Unable to register rate control algorithm: %d\n", ret); | 1512 | pr_err("Unable to register rate control algorithm: %d\n", ret); |
| 1410 | return ret; | 1513 | goto error_rc_register; |
| 1411 | } | 1514 | } |
| 1412 | 1515 | ||
| 1413 | ret = iwl_pci_register_driver(); | 1516 | ret = iwl_pci_register_driver(); |
| 1414 | |||
| 1415 | if (ret) | 1517 | if (ret) |
| 1416 | goto error_register; | 1518 | goto error_pci_register; |
| 1417 | return ret; | 1519 | return ret; |
| 1418 | 1520 | ||
| 1419 | error_register: | 1521 | error_pci_register: |
| 1420 | iwlagn_rate_control_unregister(); | 1522 | iwlagn_rate_control_unregister(); |
| 1523 | error_rc_register: | ||
| 1524 | kmem_cache_destroy(iwl_tx_cmd_pool); | ||
| 1421 | return ret; | 1525 | return ret; |
| 1422 | } | 1526 | } |
| 1423 | 1527 | ||
| @@ -1425,6 +1529,7 @@ static void __exit iwl_exit(void) | |||
| 1425 | { | 1529 | { |
| 1426 | iwl_pci_unregister_driver(); | 1530 | iwl_pci_unregister_driver(); |
| 1427 | iwlagn_rate_control_unregister(); | 1531 | iwlagn_rate_control_unregister(); |
| 1532 | kmem_cache_destroy(iwl_tx_cmd_pool); | ||
| 1428 | } | 1533 | } |
| 1429 | 1534 | ||
| 1430 | module_exit(iwl_exit); | 1535 | module_exit(iwl_exit); |
| @@ -1438,8 +1543,6 @@ MODULE_PARM_DESC(debug, "debug output mask"); | |||
| 1438 | 1543 | ||
| 1439 | module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO); | 1544 | module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO); |
| 1440 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); | 1545 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); |
| 1441 | module_param_named(queues_num, iwlagn_mod_params.num_of_queues, int, S_IRUGO); | ||
| 1442 | MODULE_PARM_DESC(queues_num, "number of hw queues."); | ||
| 1443 | module_param_named(11n_disable, iwlagn_mod_params.disable_11n, uint, S_IRUGO); | 1546 | module_param_named(11n_disable, iwlagn_mod_params.disable_11n, uint, S_IRUGO); |
| 1444 | MODULE_PARM_DESC(11n_disable, | 1547 | MODULE_PARM_DESC(11n_disable, |
| 1445 | "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX"); | 1548 | "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX"); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index cb484e273b93..3780a03f2716 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
| @@ -82,20 +82,26 @@ void iwl_cancel_deferred_work(struct iwl_priv *priv); | |||
| 82 | void iwlagn_prepare_restart(struct iwl_priv *priv); | 82 | void iwlagn_prepare_restart(struct iwl_priv *priv); |
| 83 | void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb); | 83 | void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb); |
| 84 | int __must_check iwl_rx_dispatch(struct iwl_op_mode *op_mode, | 84 | int __must_check iwl_rx_dispatch(struct iwl_op_mode *op_mode, |
| 85 | struct iwl_rx_mem_buffer *rxb, | 85 | struct iwl_rx_cmd_buffer *rxb, |
| 86 | struct iwl_device_cmd *cmd); | 86 | struct iwl_device_cmd *cmd); |
| 87 | void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac); | ||
| 88 | void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, u8 ac); | ||
| 89 | void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state); | 87 | void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state); |
| 90 | void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac); | ||
| 91 | void iwl_nic_error(struct iwl_op_mode *op_mode); | 88 | void iwl_nic_error(struct iwl_op_mode *op_mode); |
| 92 | 89 | ||
| 90 | bool iwl_check_for_ct_kill(struct iwl_priv *priv); | ||
| 91 | |||
| 92 | void iwlagn_lift_passive_no_rx(struct iwl_priv *priv); | ||
| 93 | |||
| 93 | /* MAC80211 */ | 94 | /* MAC80211 */ |
| 94 | struct ieee80211_hw *iwl_alloc_all(void); | 95 | struct ieee80211_hw *iwl_alloc_all(void); |
| 95 | int iwlagn_mac_setup_register(struct iwl_priv *priv, | 96 | int iwlagn_mac_setup_register(struct iwl_priv *priv, |
| 96 | struct iwl_ucode_capabilities *capa); | 97 | const struct iwl_ucode_capabilities *capa); |
| 97 | void iwlagn_mac_unregister(struct iwl_priv *priv); | 98 | void iwlagn_mac_unregister(struct iwl_priv *priv); |
| 98 | 99 | ||
| 100 | /* commands */ | ||
| 101 | int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); | ||
| 102 | int iwl_dvm_send_cmd_pdu(struct iwl_priv *priv, u8 id, | ||
| 103 | u32 flags, u16 len, const void *data); | ||
| 104 | |||
| 99 | /* RXON */ | 105 | /* RXON */ |
| 100 | int iwlagn_set_pan_params(struct iwl_priv *priv); | 106 | int iwlagn_set_pan_params(struct iwl_priv *priv); |
| 101 | int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | 107 | int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); |
| @@ -110,9 +116,18 @@ void iwlagn_config_ht40(struct ieee80211_conf *conf, | |||
| 110 | 116 | ||
| 111 | /* uCode */ | 117 | /* uCode */ |
| 112 | int iwlagn_rx_calib_result(struct iwl_priv *priv, | 118 | int iwlagn_rx_calib_result(struct iwl_priv *priv, |
| 113 | struct iwl_rx_mem_buffer *rxb, | 119 | struct iwl_rx_cmd_buffer *rxb, |
| 114 | struct iwl_device_cmd *cmd); | 120 | struct iwl_device_cmd *cmd); |
| 115 | void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags); | 121 | int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); |
| 122 | void iwl_send_prio_tbl(struct iwl_priv *priv); | ||
| 123 | int iwl_init_alive_start(struct iwl_priv *priv); | ||
| 124 | int iwl_run_init_ucode(struct iwl_priv *priv); | ||
| 125 | int iwl_load_ucode_wait_alive(struct iwl_priv *priv, | ||
| 126 | enum iwl_ucode_type ucode_type); | ||
| 127 | int iwl_send_calib_results(struct iwl_priv *priv); | ||
| 128 | int iwl_calib_set(struct iwl_priv *priv, | ||
| 129 | const struct iwl_calib_hdr *cmd, int len); | ||
| 130 | void iwl_calib_free_results(struct iwl_priv *priv); | ||
| 116 | 131 | ||
| 117 | /* lib */ | 132 | /* lib */ |
| 118 | int iwlagn_send_tx_power(struct iwl_priv *priv); | 133 | int iwlagn_send_tx_power(struct iwl_priv *priv); |
| @@ -124,8 +139,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv); | |||
| 124 | #ifdef CONFIG_PM_SLEEP | 139 | #ifdef CONFIG_PM_SLEEP |
| 125 | int iwlagn_send_patterns(struct iwl_priv *priv, | 140 | int iwlagn_send_patterns(struct iwl_priv *priv, |
| 126 | struct cfg80211_wowlan *wowlan); | 141 | struct cfg80211_wowlan *wowlan); |
| 127 | int iwlagn_suspend(struct iwl_priv *priv, | 142 | int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan); |
| 128 | struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan); | ||
| 129 | #endif | 143 | #endif |
| 130 | 144 | ||
| 131 | /* rx */ | 145 | /* rx */ |
| @@ -142,9 +156,9 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
| 142 | int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | 156 | int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, |
| 143 | struct ieee80211_sta *sta, u16 tid); | 157 | struct ieee80211_sta *sta, u16 tid); |
| 144 | int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | 158 | int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, |
| 145 | struct iwl_rx_mem_buffer *rxb, | 159 | struct iwl_rx_cmd_buffer *rxb, |
| 146 | struct iwl_device_cmd *cmd); | 160 | struct iwl_device_cmd *cmd); |
| 147 | int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | 161 | int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, |
| 148 | struct iwl_device_cmd *cmd); | 162 | struct iwl_device_cmd *cmd); |
| 149 | 163 | ||
| 150 | static inline u32 iwl_tx_status_to_mac80211(u32 status) | 164 | static inline u32 iwl_tx_status_to_mac80211(u32 status) |
| @@ -179,7 +193,7 @@ void iwlagn_disable_roc(struct iwl_priv *priv); | |||
| 179 | /* bt coex */ | 193 | /* bt coex */ |
| 180 | void iwlagn_send_advance_bt_config(struct iwl_priv *priv); | 194 | void iwlagn_send_advance_bt_config(struct iwl_priv *priv); |
| 181 | int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, | 195 | int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, |
| 182 | struct iwl_rx_mem_buffer *rxb, | 196 | struct iwl_rx_cmd_buffer *rxb, |
| 183 | struct iwl_device_cmd *cmd); | 197 | struct iwl_device_cmd *cmd); |
| 184 | void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv); | 198 | void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv); |
| 185 | void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv); | 199 | void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv); |
| @@ -220,6 +234,8 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
| 220 | struct ieee80211_sta *sta, u8 *sta_id_r); | 234 | struct ieee80211_sta *sta, u8 *sta_id_r); |
| 221 | int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, | 235 | int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, |
| 222 | const u8 *addr); | 236 | const u8 *addr); |
| 237 | void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id, | ||
| 238 | const u8 *addr); | ||
| 223 | u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | 239 | u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, |
| 224 | const u8 *addr, bool is_ap, struct ieee80211_sta *sta); | 240 | const u8 *addr, bool is_ap, struct ieee80211_sta *sta); |
| 225 | 241 | ||
| @@ -227,46 +243,12 @@ void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
| 227 | u8 sta_id, struct iwl_link_quality_cmd *link_cmd); | 243 | u8 sta_id, struct iwl_link_quality_cmd *link_cmd); |
| 228 | int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | 244 | int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, |
| 229 | struct iwl_link_quality_cmd *lq, u8 flags, bool init); | 245 | struct iwl_link_quality_cmd *lq, u8 flags, bool init); |
| 230 | void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | 246 | int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, |
| 231 | int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | ||
| 232 | struct iwl_device_cmd *cmd); | 247 | struct iwl_device_cmd *cmd); |
| 248 | int iwl_sta_update_ht(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | ||
| 249 | struct ieee80211_sta *sta); | ||
| 233 | 250 | ||
| 234 | 251 | ||
| 235 | /** | ||
| 236 | * iwl_clear_driver_stations - clear knowledge of all stations from driver | ||
| 237 | * @priv: iwl priv struct | ||
| 238 | * | ||
| 239 | * This is called during iwl_down() to make sure that in the case | ||
| 240 | * we're coming there from a hardware restart mac80211 will be | ||
| 241 | * able to reconfigure stations -- if we're getting there in the | ||
| 242 | * normal down flow then the stations will already be cleared. | ||
| 243 | */ | ||
| 244 | static inline void iwl_clear_driver_stations(struct iwl_priv *priv) | ||
| 245 | { | ||
| 246 | unsigned long flags; | ||
| 247 | struct iwl_rxon_context *ctx; | ||
| 248 | |||
| 249 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | ||
| 250 | memset(priv->stations, 0, sizeof(priv->stations)); | ||
| 251 | priv->num_stations = 0; | ||
| 252 | |||
| 253 | priv->ucode_key_table = 0; | ||
| 254 | |||
| 255 | for_each_context(priv, ctx) { | ||
| 256 | /* | ||
| 257 | * Remove all key information that is not stored as part | ||
| 258 | * of station information since mac80211 may not have had | ||
| 259 | * a chance to remove all the keys. When device is | ||
| 260 | * reconfigured by mac80211 after an error all keys will | ||
| 261 | * be reconfigured. | ||
| 262 | */ | ||
| 263 | memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys)); | ||
| 264 | ctx->key_mapping_keys = 0; | ||
| 265 | } | ||
| 266 | |||
| 267 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
| 268 | } | ||
| 269 | |||
| 270 | static inline int iwl_sta_id(struct ieee80211_sta *sta) | 252 | static inline int iwl_sta_id(struct ieee80211_sta *sta) |
| 271 | { | 253 | { |
| 272 | if (WARN_ON(!sta)) | 254 | if (WARN_ON(!sta)) |
| @@ -275,37 +257,6 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta) | |||
| 275 | return ((struct iwl_station_priv *)sta->drv_priv)->sta_id; | 257 | return ((struct iwl_station_priv *)sta->drv_priv)->sta_id; |
| 276 | } | 258 | } |
| 277 | 259 | ||
| 278 | /** | ||
| 279 | * iwl_sta_id_or_broadcast - return sta_id or broadcast sta | ||
| 280 | * @priv: iwl priv | ||
| 281 | * @context: the current context | ||
| 282 | * @sta: mac80211 station | ||
| 283 | * | ||
| 284 | * In certain circumstances mac80211 passes a station pointer | ||
| 285 | * that may be %NULL, for example during TX or key setup. In | ||
| 286 | * that case, we need to use the broadcast station, so this | ||
| 287 | * inline wraps that pattern. | ||
| 288 | */ | ||
| 289 | static inline int iwl_sta_id_or_broadcast(struct iwl_priv *priv, | ||
| 290 | struct iwl_rxon_context *context, | ||
| 291 | struct ieee80211_sta *sta) | ||
| 292 | { | ||
| 293 | int sta_id; | ||
| 294 | |||
| 295 | if (!sta) | ||
| 296 | return context->bcast_sta_id; | ||
| 297 | |||
| 298 | sta_id = iwl_sta_id(sta); | ||
| 299 | |||
| 300 | /* | ||
| 301 | * mac80211 should not be passing a partially | ||
| 302 | * initialised station! | ||
| 303 | */ | ||
| 304 | WARN_ON(sta_id == IWL_INVALID_STATION); | ||
| 305 | |||
| 306 | return sta_id; | ||
| 307 | } | ||
| 308 | |||
| 309 | int iwlagn_alloc_bcast_station(struct iwl_priv *priv, | 260 | int iwlagn_alloc_bcast_station(struct iwl_priv *priv, |
| 310 | struct iwl_rxon_context *ctx); | 261 | struct iwl_rxon_context *ctx); |
| 311 | int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | 262 | int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, |
| @@ -355,7 +306,6 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) | |||
| 355 | } | 306 | } |
| 356 | 307 | ||
| 357 | /* eeprom */ | 308 | /* eeprom */ |
| 358 | void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv); | ||
| 359 | void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac); | 309 | void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac); |
| 360 | 310 | ||
| 361 | extern int iwl_alive_start(struct iwl_priv *priv); | 311 | extern int iwl_alive_start(struct iwl_priv *priv); |
| @@ -402,4 +352,58 @@ static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv, | |||
| 402 | } | 352 | } |
| 403 | #endif | 353 | #endif |
| 404 | 354 | ||
| 355 | /* status checks */ | ||
| 356 | |||
| 357 | static inline int iwl_is_ready(struct iwl_priv *priv) | ||
| 358 | { | ||
| 359 | /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are | ||
| 360 | * set but EXIT_PENDING is not */ | ||
| 361 | return test_bit(STATUS_READY, &priv->status) && | ||
| 362 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) && | ||
| 363 | !test_bit(STATUS_EXIT_PENDING, &priv->status); | ||
| 364 | } | ||
| 365 | |||
| 366 | static inline int iwl_is_alive(struct iwl_priv *priv) | ||
| 367 | { | ||
| 368 | return test_bit(STATUS_ALIVE, &priv->status); | ||
| 369 | } | ||
| 370 | |||
| 371 | static inline int iwl_is_rfkill(struct iwl_priv *priv) | ||
| 372 | { | ||
| 373 | return test_bit(STATUS_RF_KILL_HW, &priv->status); | ||
| 374 | } | ||
| 375 | |||
| 376 | static inline int iwl_is_ctkill(struct iwl_priv *priv) | ||
| 377 | { | ||
| 378 | return test_bit(STATUS_CT_KILL, &priv->status); | ||
| 379 | } | ||
| 380 | |||
| 381 | static inline int iwl_is_ready_rf(struct iwl_priv *priv) | ||
| 382 | { | ||
| 383 | if (iwl_is_rfkill(priv)) | ||
| 384 | return 0; | ||
| 385 | |||
| 386 | return iwl_is_ready(priv); | ||
| 387 | } | ||
| 388 | |||
| 389 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
| 390 | #define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \ | ||
| 391 | do { \ | ||
| 392 | if (!iwl_is_rfkill((m))) \ | ||
| 393 | IWL_ERR(m, fmt, ##args); \ | ||
| 394 | else \ | ||
| 395 | __iwl_err(trans(m)->dev, true, \ | ||
| 396 | !iwl_have_debug_level(IWL_DL_RADIO), \ | ||
| 397 | fmt, ##args); \ | ||
| 398 | } while (0) | ||
| 399 | #else | ||
| 400 | #define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \ | ||
| 401 | do { \ | ||
| 402 | if (!iwl_is_rfkill((m))) \ | ||
| 403 | IWL_ERR(m, fmt, ##args); \ | ||
| 404 | else \ | ||
| 405 | __iwl_err(trans(m)->dev, true, true, fmt, ##args); \ | ||
| 406 | } while (0) | ||
| 407 | #endif /* CONFIG_IWLWIFI_DEBUG */ | ||
| 408 | |||
| 405 | #endif /* __iwl_agn_h__ */ | 409 | #endif /* __iwl_agn_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-cfg.h b/drivers/net/wireless/iwlwifi/iwl-cfg.h index 1ad14bbccc99..82152311d73b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-cfg.h +++ b/drivers/net/wireless/iwlwifi/iwl-cfg.h | |||
| @@ -68,46 +68,46 @@ | |||
| 68 | * This file declares the config structures for all devices. | 68 | * This file declares the config structures for all devices. |
| 69 | */ | 69 | */ |
| 70 | 70 | ||
| 71 | extern struct iwl_cfg iwl5300_agn_cfg; | 71 | extern const struct iwl_cfg iwl5300_agn_cfg; |
| 72 | extern struct iwl_cfg iwl5100_agn_cfg; | 72 | extern const struct iwl_cfg iwl5100_agn_cfg; |
| 73 | extern struct iwl_cfg iwl5350_agn_cfg; | 73 | extern const struct iwl_cfg iwl5350_agn_cfg; |
| 74 | extern struct iwl_cfg iwl5100_bgn_cfg; | 74 | extern const struct iwl_cfg iwl5100_bgn_cfg; |
| 75 | extern struct iwl_cfg iwl5100_abg_cfg; | 75 | extern const struct iwl_cfg iwl5100_abg_cfg; |
| 76 | extern struct iwl_cfg iwl5150_agn_cfg; | 76 | extern const struct iwl_cfg iwl5150_agn_cfg; |
| 77 | extern struct iwl_cfg iwl5150_abg_cfg; | 77 | extern const struct iwl_cfg iwl5150_abg_cfg; |
| 78 | extern struct iwl_cfg iwl6005_2agn_cfg; | 78 | extern const struct iwl_cfg iwl6005_2agn_cfg; |
| 79 | extern struct iwl_cfg iwl6005_2abg_cfg; | 79 | extern const struct iwl_cfg iwl6005_2abg_cfg; |
| 80 | extern struct iwl_cfg iwl6005_2bg_cfg; | 80 | extern const struct iwl_cfg iwl6005_2bg_cfg; |
| 81 | extern struct iwl_cfg iwl6005_2agn_sff_cfg; | 81 | extern const struct iwl_cfg iwl6005_2agn_sff_cfg; |
| 82 | extern struct iwl_cfg iwl6005_2agn_d_cfg; | 82 | extern const struct iwl_cfg iwl6005_2agn_d_cfg; |
| 83 | extern struct iwl_cfg iwl6005_2agn_mow1_cfg; | 83 | extern const struct iwl_cfg iwl6005_2agn_mow1_cfg; |
| 84 | extern struct iwl_cfg iwl6005_2agn_mow2_cfg; | 84 | extern const struct iwl_cfg iwl6005_2agn_mow2_cfg; |
| 85 | extern struct iwl_cfg iwl1030_bgn_cfg; | 85 | extern const struct iwl_cfg iwl1030_bgn_cfg; |
| 86 | extern struct iwl_cfg iwl1030_bg_cfg; | 86 | extern const struct iwl_cfg iwl1030_bg_cfg; |
| 87 | extern struct iwl_cfg iwl6030_2agn_cfg; | 87 | extern const struct iwl_cfg iwl6030_2agn_cfg; |
| 88 | extern struct iwl_cfg iwl6030_2abg_cfg; | 88 | extern const struct iwl_cfg iwl6030_2abg_cfg; |
| 89 | extern struct iwl_cfg iwl6030_2bgn_cfg; | 89 | extern const struct iwl_cfg iwl6030_2bgn_cfg; |
| 90 | extern struct iwl_cfg iwl6030_2bg_cfg; | 90 | extern const struct iwl_cfg iwl6030_2bg_cfg; |
| 91 | extern struct iwl_cfg iwl6000i_2agn_cfg; | 91 | extern const struct iwl_cfg iwl6000i_2agn_cfg; |
| 92 | extern struct iwl_cfg iwl6000i_2abg_cfg; | 92 | extern const struct iwl_cfg iwl6000i_2abg_cfg; |
| 93 | extern struct iwl_cfg iwl6000i_2bg_cfg; | 93 | extern const struct iwl_cfg iwl6000i_2bg_cfg; |
| 94 | extern struct iwl_cfg iwl6000_3agn_cfg; | 94 | extern const struct iwl_cfg iwl6000_3agn_cfg; |
| 95 | extern struct iwl_cfg iwl6050_2agn_cfg; | 95 | extern const struct iwl_cfg iwl6050_2agn_cfg; |
| 96 | extern struct iwl_cfg iwl6050_2abg_cfg; | 96 | extern const struct iwl_cfg iwl6050_2abg_cfg; |
| 97 | extern struct iwl_cfg iwl6150_bgn_cfg; | 97 | extern const struct iwl_cfg iwl6150_bgn_cfg; |
| 98 | extern struct iwl_cfg iwl6150_bg_cfg; | 98 | extern const struct iwl_cfg iwl6150_bg_cfg; |
| 99 | extern struct iwl_cfg iwl1000_bgn_cfg; | 99 | extern const struct iwl_cfg iwl1000_bgn_cfg; |
| 100 | extern struct iwl_cfg iwl1000_bg_cfg; | 100 | extern const struct iwl_cfg iwl1000_bg_cfg; |
| 101 | extern struct iwl_cfg iwl100_bgn_cfg; | 101 | extern const struct iwl_cfg iwl100_bgn_cfg; |
| 102 | extern struct iwl_cfg iwl100_bg_cfg; | 102 | extern const struct iwl_cfg iwl100_bg_cfg; |
| 103 | extern struct iwl_cfg iwl130_bgn_cfg; | 103 | extern const struct iwl_cfg iwl130_bgn_cfg; |
| 104 | extern struct iwl_cfg iwl130_bg_cfg; | 104 | extern const struct iwl_cfg iwl130_bg_cfg; |
| 105 | extern struct iwl_cfg iwl2000_2bgn_cfg; | 105 | extern const struct iwl_cfg iwl2000_2bgn_cfg; |
| 106 | extern struct iwl_cfg iwl2000_2bgn_d_cfg; | 106 | extern const struct iwl_cfg iwl2000_2bgn_d_cfg; |
| 107 | extern struct iwl_cfg iwl2030_2bgn_cfg; | 107 | extern const struct iwl_cfg iwl2030_2bgn_cfg; |
| 108 | extern struct iwl_cfg iwl6035_2agn_cfg; | 108 | extern const struct iwl_cfg iwl6035_2agn_cfg; |
| 109 | extern struct iwl_cfg iwl105_bgn_cfg; | 109 | extern const struct iwl_cfg iwl105_bgn_cfg; |
| 110 | extern struct iwl_cfg iwl105_bgn_d_cfg; | 110 | extern const struct iwl_cfg iwl105_bgn_d_cfg; |
| 111 | extern struct iwl_cfg iwl135_bgn_cfg; | 111 | extern const struct iwl_cfg iwl135_bgn_cfg; |
| 112 | 112 | ||
| 113 | #endif /* __iwl_pci_h__ */ | 113 | #endif /* __iwl_pci_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index c20618d92268..9ed73e5154be 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
| @@ -69,22 +69,9 @@ | |||
| 69 | #ifndef __iwl_commands_h__ | 69 | #ifndef __iwl_commands_h__ |
| 70 | #define __iwl_commands_h__ | 70 | #define __iwl_commands_h__ |
| 71 | 71 | ||
| 72 | #include <linux/etherdevice.h> | ||
| 73 | #include <linux/ieee80211.h> | 72 | #include <linux/ieee80211.h> |
| 73 | #include <linux/types.h> | ||
| 74 | 74 | ||
| 75 | struct iwl_priv; | ||
| 76 | |||
| 77 | /* uCode version contains 4 values: Major/Minor/API/Serial */ | ||
| 78 | #define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24) | ||
| 79 | #define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16) | ||
| 80 | #define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8) | ||
| 81 | #define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF) | ||
| 82 | |||
| 83 | |||
| 84 | /* Tx rates */ | ||
| 85 | #define IWL_CCK_RATES 4 | ||
| 86 | #define IWL_OFDM_RATES 8 | ||
| 87 | #define IWL_MAX_RATES (IWL_CCK_RATES + IWL_OFDM_RATES) | ||
| 88 | 75 | ||
| 89 | enum { | 76 | enum { |
| 90 | REPLY_ALIVE = 0x1, | 77 | REPLY_ALIVE = 0x1, |
| @@ -213,48 +200,6 @@ enum { | |||
| 213 | /* iwl_cmd_header flags value */ | 200 | /* iwl_cmd_header flags value */ |
| 214 | #define IWL_CMD_FAILED_MSK 0x40 | 201 | #define IWL_CMD_FAILED_MSK 0x40 |
| 215 | 202 | ||
| 216 | #define SEQ_TO_QUEUE(s) (((s) >> 8) & 0x1f) | ||
| 217 | #define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8) | ||
| 218 | #define SEQ_TO_INDEX(s) ((s) & 0xff) | ||
| 219 | #define INDEX_TO_SEQ(i) ((i) & 0xff) | ||
| 220 | #define SEQ_RX_FRAME cpu_to_le16(0x8000) | ||
| 221 | |||
| 222 | /** | ||
| 223 | * struct iwl_cmd_header | ||
| 224 | * | ||
| 225 | * This header format appears in the beginning of each command sent from the | ||
| 226 | * driver, and each response/notification received from uCode. | ||
| 227 | */ | ||
| 228 | struct iwl_cmd_header { | ||
| 229 | u8 cmd; /* Command ID: REPLY_RXON, etc. */ | ||
| 230 | u8 flags; /* 0:5 reserved, 6 abort, 7 internal */ | ||
| 231 | /* | ||
| 232 | * The driver sets up the sequence number to values of its choosing. | ||
| 233 | * uCode does not use this value, but passes it back to the driver | ||
| 234 | * when sending the response to each driver-originated command, so | ||
| 235 | * the driver can match the response to the command. Since the values | ||
| 236 | * don't get used by uCode, the driver may set up an arbitrary format. | ||
| 237 | * | ||
| 238 | * There is one exception: uCode sets bit 15 when it originates | ||
| 239 | * the response/notification, i.e. when the response/notification | ||
| 240 | * is not a direct response to a command sent by the driver. For | ||
| 241 | * example, uCode issues REPLY_RX when it sends a received frame | ||
| 242 | * to the driver; it is not a direct response to any driver command. | ||
| 243 | * | ||
| 244 | * The Linux driver uses the following format: | ||
| 245 | * | ||
| 246 | * 0:7 tfd index - position within TX queue | ||
| 247 | * 8:12 TX queue id | ||
| 248 | * 13:14 reserved | ||
| 249 | * 15 unsolicited RX or uCode-originated notification | ||
| 250 | */ | ||
| 251 | __le16 sequence; | ||
| 252 | |||
| 253 | /* command or response/notification data follows immediately */ | ||
| 254 | u8 data[0]; | ||
| 255 | } __packed; | ||
| 256 | |||
| 257 | |||
| 258 | /** | 203 | /** |
| 259 | * iwlagn rate_n_flags bit fields | 204 | * iwlagn rate_n_flags bit fields |
| 260 | * | 205 | * |
| @@ -3151,8 +3096,6 @@ struct iwl_enhance_sensitivity_cmd { | |||
| 3151 | */ | 3096 | */ |
| 3152 | 3097 | ||
| 3153 | /* Phy calibration command for series */ | 3098 | /* Phy calibration command for series */ |
| 3154 | /* The default calibrate table size if not specified by firmware */ | ||
| 3155 | #define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE 18 | ||
| 3156 | enum { | 3099 | enum { |
| 3157 | IWL_PHY_CALIBRATE_DC_CMD = 8, | 3100 | IWL_PHY_CALIBRATE_DC_CMD = 8, |
| 3158 | IWL_PHY_CALIBRATE_LO_CMD = 9, | 3101 | IWL_PHY_CALIBRATE_LO_CMD = 9, |
| @@ -3161,11 +3104,8 @@ enum { | |||
| 3161 | IWL_PHY_CALIBRATE_BASE_BAND_CMD = 16, | 3104 | IWL_PHY_CALIBRATE_BASE_BAND_CMD = 16, |
| 3162 | IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD = 17, | 3105 | IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD = 17, |
| 3163 | IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD = 18, | 3106 | IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD = 18, |
| 3164 | IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE = 19, | ||
| 3165 | }; | 3107 | }; |
| 3166 | 3108 | ||
| 3167 | #define IWL_MAX_PHY_CALIBRATE_TBL_SIZE (253) | ||
| 3168 | |||
| 3169 | /* This enum defines the bitmap of various calibrations to enable in both | 3109 | /* This enum defines the bitmap of various calibrations to enable in both |
| 3170 | * init ucode and runtime ucode through CALIBRATION_CFG_CMD. | 3110 | * init ucode and runtime ucode through CALIBRATION_CFG_CMD. |
| 3171 | */ | 3111 | */ |
| @@ -3905,50 +3845,6 @@ struct iwlagn_wowlan_kek_kck_material_cmd { | |||
| 3905 | __le64 replay_ctr; | 3845 | __le64 replay_ctr; |
| 3906 | } __packed; | 3846 | } __packed; |
| 3907 | 3847 | ||
| 3908 | /****************************************************************************** | ||
| 3909 | * (13) | ||
| 3910 | * Union of all expected notifications/responses: | ||
| 3911 | * | ||
| 3912 | *****************************************************************************/ | ||
| 3913 | #define FH_RSCSR_FRAME_SIZE_MSK (0x00003FFF) /* bits 0-13 */ | ||
| 3914 | |||
| 3915 | struct iwl_rx_packet { | ||
| 3916 | /* | ||
| 3917 | * The first 4 bytes of the RX frame header contain both the RX frame | ||
| 3918 | * size and some flags. | ||
| 3919 | * Bit fields: | ||
| 3920 | * 31: flag flush RB request | ||
| 3921 | * 30: flag ignore TC (terminal counter) request | ||
| 3922 | * 29: flag fast IRQ request | ||
| 3923 | * 28-14: Reserved | ||
| 3924 | * 13-00: RX frame size | ||
| 3925 | */ | ||
| 3926 | __le32 len_n_flags; | ||
| 3927 | struct iwl_cmd_header hdr; | ||
| 3928 | union { | ||
| 3929 | struct iwl_alive_resp alive_frame; | ||
| 3930 | struct iwl_spectrum_notification spectrum_notif; | ||
| 3931 | struct iwl_csa_notification csa_notif; | ||
| 3932 | struct iwl_error_resp err_resp; | ||
| 3933 | struct iwl_card_state_notif card_state_notif; | ||
| 3934 | struct iwl_add_sta_resp add_sta; | ||
| 3935 | struct iwl_rem_sta_resp rem_sta; | ||
| 3936 | struct iwl_sleep_notification sleep_notif; | ||
| 3937 | struct iwl_spectrum_resp spectrum; | ||
| 3938 | struct iwl_notif_statistics stats; | ||
| 3939 | struct iwl_bt_notif_statistics stats_bt; | ||
| 3940 | struct iwl_compressed_ba_resp compressed_ba; | ||
| 3941 | struct iwl_missed_beacon_notif missed_beacon; | ||
| 3942 | struct iwl_coex_medium_notification coex_medium_notif; | ||
| 3943 | struct iwl_coex_event_resp coex_event; | ||
| 3944 | struct iwl_bt_coex_profile_notif bt_coex_profile_notif; | ||
| 3945 | __le32 status; | ||
| 3946 | u8 raw[0]; | ||
| 3947 | } u; | ||
| 3948 | } __packed; | ||
| 3949 | |||
| 3950 | int iwl_agn_check_rxon_cmd(struct iwl_priv *priv); | ||
| 3951 | |||
| 3952 | /* | 3848 | /* |
| 3953 | * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification) | 3849 | * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification) |
| 3954 | */ | 3850 | */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 275e08966059..8b85940731f2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
| @@ -41,7 +41,6 @@ | |||
| 41 | #include "iwl-shared.h" | 41 | #include "iwl-shared.h" |
| 42 | #include "iwl-agn.h" | 42 | #include "iwl-agn.h" |
| 43 | #include "iwl-trans.h" | 43 | #include "iwl-trans.h" |
| 44 | #include "iwl-wifi.h" | ||
| 45 | 44 | ||
| 46 | const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 45 | const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
| 47 | 46 | ||
| @@ -114,7 +113,7 @@ int iwl_init_geos(struct iwl_priv *priv) | |||
| 114 | if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || | 113 | if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || |
| 115 | priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { | 114 | priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { |
| 116 | IWL_DEBUG_INFO(priv, "Geography modes already initialized.\n"); | 115 | IWL_DEBUG_INFO(priv, "Geography modes already initialized.\n"); |
| 117 | set_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status); | 116 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); |
| 118 | return 0; | 117 | return 0; |
| 119 | } | 118 | } |
| 120 | 119 | ||
| @@ -137,7 +136,7 @@ int iwl_init_geos(struct iwl_priv *priv) | |||
| 137 | sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; | 136 | sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; |
| 138 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE; | 137 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE; |
| 139 | 138 | ||
| 140 | if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE) | 139 | if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) |
| 141 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, | 140 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, |
| 142 | IEEE80211_BAND_5GHZ); | 141 | IEEE80211_BAND_5GHZ); |
| 143 | 142 | ||
| @@ -147,7 +146,7 @@ int iwl_init_geos(struct iwl_priv *priv) | |||
| 147 | sband->bitrates = rates; | 146 | sband->bitrates = rates; |
| 148 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY; | 147 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY; |
| 149 | 148 | ||
| 150 | if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE) | 149 | if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) |
| 151 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, | 150 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, |
| 152 | IEEE80211_BAND_2GHZ); | 151 | IEEE80211_BAND_2GHZ); |
| 153 | 152 | ||
| @@ -202,18 +201,18 @@ int iwl_init_geos(struct iwl_priv *priv) | |||
| 202 | priv->tx_power_next = max_tx_power; | 201 | priv->tx_power_next = max_tx_power; |
| 203 | 202 | ||
| 204 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && | 203 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && |
| 205 | cfg(priv)->sku & EEPROM_SKU_CAP_BAND_52GHZ) { | 204 | hw_params(priv).sku & EEPROM_SKU_CAP_BAND_52GHZ) { |
| 206 | IWL_INFO(priv, "Incorrectly detected BG card as ABG. " | 205 | IWL_INFO(priv, "Incorrectly detected BG card as ABG. " |
| 207 | "Please send your %s to maintainer.\n", | 206 | "Please send your %s to maintainer.\n", |
| 208 | trans(priv)->hw_id_str); | 207 | trans(priv)->hw_id_str); |
| 209 | cfg(priv)->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; | 208 | hw_params(priv).sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; |
| 210 | } | 209 | } |
| 211 | 210 | ||
| 212 | IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", | 211 | IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", |
| 213 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, | 212 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, |
| 214 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); | 213 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); |
| 215 | 214 | ||
| 216 | set_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status); | 215 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); |
| 217 | 216 | ||
| 218 | return 0; | 217 | return 0; |
| 219 | } | 218 | } |
| @@ -225,7 +224,7 @@ void iwl_free_geos(struct iwl_priv *priv) | |||
| 225 | { | 224 | { |
| 226 | kfree(priv->ieee_channels); | 225 | kfree(priv->ieee_channels); |
| 227 | kfree(priv->ieee_rates); | 226 | kfree(priv->ieee_rates); |
| 228 | clear_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status); | 227 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); |
| 229 | } | 228 | } |
| 230 | 229 | ||
| 231 | static bool iwl_is_channel_extension(struct iwl_priv *priv, | 230 | static bool iwl_is_channel_extension(struct iwl_priv *priv, |
| @@ -317,7 +316,7 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 317 | 316 | ||
| 318 | conf = &priv->hw->conf; | 317 | conf = &priv->hw->conf; |
| 319 | 318 | ||
| 320 | lockdep_assert_held(&priv->shrd->mutex); | 319 | lockdep_assert_held(&priv->mutex); |
| 321 | 320 | ||
| 322 | memset(&ctx->timing, 0, sizeof(struct iwl_rxon_time_cmd)); | 321 | memset(&ctx->timing, 0, sizeof(struct iwl_rxon_time_cmd)); |
| 323 | 322 | ||
| @@ -370,7 +369,7 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 370 | le32_to_cpu(ctx->timing.beacon_init_val), | 369 | le32_to_cpu(ctx->timing.beacon_init_val), |
| 371 | le16_to_cpu(ctx->timing.atim_window)); | 370 | le16_to_cpu(ctx->timing.atim_window)); |
| 372 | 371 | ||
| 373 | return iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_timing_cmd, | 372 | return iwl_dvm_send_cmd_pdu(priv, ctx->rxon_timing_cmd, |
| 374 | CMD_SYNC, sizeof(ctx->timing), &ctx->timing); | 373 | CMD_SYNC, sizeof(ctx->timing), &ctx->timing); |
| 375 | } | 374 | } |
| 376 | 375 | ||
| @@ -799,11 +798,10 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) | |||
| 799 | */ | 798 | */ |
| 800 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 799 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
| 801 | 800 | ||
| 802 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 801 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 803 | return; | 802 | return; |
| 804 | 803 | ||
| 805 | if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, | 804 | if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) |
| 806 | &priv->shrd->status)) | ||
| 807 | ieee80211_chswitch_done(ctx->vif, is_success); | 805 | ieee80211_chswitch_done(ctx->vif, is_success); |
| 808 | } | 806 | } |
| 809 | 807 | ||
| @@ -836,7 +834,7 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | |||
| 836 | unsigned long reload_jiffies; | 834 | unsigned long reload_jiffies; |
| 837 | 835 | ||
| 838 | #ifdef CONFIG_IWLWIFI_DEBUG | 836 | #ifdef CONFIG_IWLWIFI_DEBUG |
| 839 | if (iwl_get_debug_level(priv->shrd) & IWL_DL_FW_ERRORS) | 837 | if (iwl_have_debug_level(IWL_DL_FW_ERRORS)) |
| 840 | iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS); | 838 | iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS); |
| 841 | #endif | 839 | #endif |
| 842 | 840 | ||
| @@ -846,11 +844,11 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | |||
| 846 | /* Cancel currently queued command. */ | 844 | /* Cancel currently queued command. */ |
| 847 | clear_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status); | 845 | clear_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status); |
| 848 | 846 | ||
| 849 | iwl_abort_notification_waits(priv->shrd); | 847 | iwl_abort_notification_waits(&priv->notif_wait); |
| 850 | 848 | ||
| 851 | /* Keep the restart process from trying to send host | 849 | /* Keep the restart process from trying to send host |
| 852 | * commands by clearing the ready bit */ | 850 | * commands by clearing the ready bit */ |
| 853 | clear_bit(STATUS_READY, &priv->shrd->status); | 851 | clear_bit(STATUS_READY, &priv->status); |
| 854 | 852 | ||
| 855 | wake_up(&priv->shrd->wait_command_queue); | 853 | wake_up(&priv->shrd->wait_command_queue); |
| 856 | 854 | ||
| @@ -875,7 +873,7 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | |||
| 875 | priv->reload_count = 0; | 873 | priv->reload_count = 0; |
| 876 | } | 874 | } |
| 877 | 875 | ||
| 878 | if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { | 876 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
| 879 | if (iwlagn_mod_params.restart_fw) { | 877 | if (iwlagn_mod_params.restart_fw) { |
| 880 | IWL_DEBUG_FW_ERRORS(priv, | 878 | IWL_DEBUG_FW_ERRORS(priv, |
| 881 | "Restarting adapter due to uCode error.\n"); | 879 | "Restarting adapter due to uCode error.\n"); |
| @@ -893,7 +891,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | |||
| 893 | bool defer; | 891 | bool defer; |
| 894 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 892 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
| 895 | 893 | ||
| 896 | lockdep_assert_held(&priv->shrd->mutex); | 894 | lockdep_assert_held(&priv->mutex); |
| 897 | 895 | ||
| 898 | if (priv->tx_power_user_lmt == tx_power && !force) | 896 | if (priv->tx_power_user_lmt == tx_power && !force) |
| 899 | return 0; | 897 | return 0; |
| @@ -913,7 +911,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | |||
| 913 | return -EINVAL; | 911 | return -EINVAL; |
| 914 | } | 912 | } |
| 915 | 913 | ||
| 916 | if (!iwl_is_ready_rf(priv->shrd)) | 914 | if (!iwl_is_ready_rf(priv)) |
| 917 | return -EIO; | 915 | return -EIO; |
| 918 | 916 | ||
| 919 | /* scan complete and commit_rxon use tx_power_next value, | 917 | /* scan complete and commit_rxon use tx_power_next value, |
| @@ -921,7 +919,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | |||
| 921 | priv->tx_power_next = tx_power; | 919 | priv->tx_power_next = tx_power; |
| 922 | 920 | ||
| 923 | /* do not set tx power when scanning or channel changing */ | 921 | /* do not set tx power when scanning or channel changing */ |
| 924 | defer = test_bit(STATUS_SCANNING, &priv->shrd->status) || | 922 | defer = test_bit(STATUS_SCANNING, &priv->status) || |
| 925 | memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)); | 923 | memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)); |
| 926 | if (defer && !force) { | 924 | if (defer && !force) { |
| 927 | IWL_DEBUG_INFO(priv, "Deferring tx power set\n"); | 925 | IWL_DEBUG_INFO(priv, "Deferring tx power set\n"); |
| @@ -959,7 +957,7 @@ void iwl_send_bt_config(struct iwl_priv *priv) | |||
| 959 | IWL_DEBUG_INFO(priv, "BT coex %s\n", | 957 | IWL_DEBUG_INFO(priv, "BT coex %s\n", |
| 960 | (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active"); | 958 | (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active"); |
| 961 | 959 | ||
| 962 | if (iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG, | 960 | if (iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, |
| 963 | CMD_SYNC, sizeof(struct iwl_bt_cmd), &bt_cmd)) | 961 | CMD_SYNC, sizeof(struct iwl_bt_cmd), &bt_cmd)) |
| 964 | IWL_ERR(priv, "failed to send BT Coex Config\n"); | 962 | IWL_ERR(priv, "failed to send BT Coex Config\n"); |
| 965 | } | 963 | } |
| @@ -972,12 +970,12 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) | |||
| 972 | }; | 970 | }; |
| 973 | 971 | ||
| 974 | if (flags & CMD_ASYNC) | 972 | if (flags & CMD_ASYNC) |
| 975 | return iwl_trans_send_cmd_pdu(trans(priv), REPLY_STATISTICS_CMD, | 973 | return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD, |
| 976 | CMD_ASYNC, | 974 | CMD_ASYNC, |
| 977 | sizeof(struct iwl_statistics_cmd), | 975 | sizeof(struct iwl_statistics_cmd), |
| 978 | &statistics_cmd); | 976 | &statistics_cmd); |
| 979 | else | 977 | else |
| 980 | return iwl_trans_send_cmd_pdu(trans(priv), REPLY_STATISTICS_CMD, | 978 | return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD, |
| 981 | CMD_SYNC, | 979 | CMD_SYNC, |
| 982 | sizeof(struct iwl_statistics_cmd), | 980 | sizeof(struct iwl_statistics_cmd), |
| 983 | &statistics_cmd); | 981 | &statistics_cmd); |
| @@ -1004,7 +1002,7 @@ int iwl_alloc_traffic_mem(struct iwl_priv *priv) | |||
| 1004 | { | 1002 | { |
| 1005 | u32 traffic_size = IWL_TRAFFIC_DUMP_SIZE; | 1003 | u32 traffic_size = IWL_TRAFFIC_DUMP_SIZE; |
| 1006 | 1004 | ||
| 1007 | if (iwl_get_debug_level(priv->shrd) & IWL_DL_TX) { | 1005 | if (iwl_have_debug_level(IWL_DL_TX)) { |
| 1008 | if (!priv->tx_traffic) { | 1006 | if (!priv->tx_traffic) { |
| 1009 | priv->tx_traffic = | 1007 | priv->tx_traffic = |
| 1010 | kzalloc(traffic_size, GFP_KERNEL); | 1008 | kzalloc(traffic_size, GFP_KERNEL); |
| @@ -1012,7 +1010,7 @@ int iwl_alloc_traffic_mem(struct iwl_priv *priv) | |||
| 1012 | return -ENOMEM; | 1010 | return -ENOMEM; |
| 1013 | } | 1011 | } |
| 1014 | } | 1012 | } |
| 1015 | if (iwl_get_debug_level(priv->shrd) & IWL_DL_RX) { | 1013 | if (iwl_have_debug_level(IWL_DL_RX)) { |
| 1016 | if (!priv->rx_traffic) { | 1014 | if (!priv->rx_traffic) { |
| 1017 | priv->rx_traffic = | 1015 | priv->rx_traffic = |
| 1018 | kzalloc(traffic_size, GFP_KERNEL); | 1016 | kzalloc(traffic_size, GFP_KERNEL); |
| @@ -1039,7 +1037,7 @@ void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv, | |||
| 1039 | __le16 fc; | 1037 | __le16 fc; |
| 1040 | u16 len; | 1038 | u16 len; |
| 1041 | 1039 | ||
| 1042 | if (likely(!(iwl_get_debug_level(priv->shrd) & IWL_DL_TX))) | 1040 | if (likely(!iwl_have_debug_level(IWL_DL_TX))) |
| 1043 | return; | 1041 | return; |
| 1044 | 1042 | ||
| 1045 | if (!priv->tx_traffic) | 1043 | if (!priv->tx_traffic) |
| @@ -1063,7 +1061,7 @@ void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv, | |||
| 1063 | __le16 fc; | 1061 | __le16 fc; |
| 1064 | u16 len; | 1062 | u16 len; |
| 1065 | 1063 | ||
| 1066 | if (likely(!(iwl_get_debug_level(priv->shrd) & IWL_DL_RX))) | 1064 | if (likely(!iwl_have_debug_level(IWL_DL_RX))) |
| 1067 | return; | 1065 | return; |
| 1068 | 1066 | ||
| 1069 | if (!priv->rx_traffic) | 1067 | if (!priv->rx_traffic) |
| @@ -1220,7 +1218,7 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) | |||
| 1220 | 1218 | ||
| 1221 | static void iwl_force_rf_reset(struct iwl_priv *priv) | 1219 | static void iwl_force_rf_reset(struct iwl_priv *priv) |
| 1222 | { | 1220 | { |
| 1223 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 1221 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 1224 | return; | 1222 | return; |
| 1225 | 1223 | ||
| 1226 | if (!iwl_is_any_associated(priv)) { | 1224 | if (!iwl_is_any_associated(priv)) { |
| @@ -1245,7 +1243,7 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external) | |||
| 1245 | { | 1243 | { |
| 1246 | struct iwl_force_reset *force_reset; | 1244 | struct iwl_force_reset *force_reset; |
| 1247 | 1245 | ||
| 1248 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 1246 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 1249 | return -EINVAL; | 1247 | return -EINVAL; |
| 1250 | 1248 | ||
| 1251 | if (mode >= IWL_MAX_FORCE_RESET) { | 1249 | if (mode >= IWL_MAX_FORCE_RESET) { |
| @@ -1301,7 +1299,7 @@ int iwl_cmd_echo_test(struct iwl_priv *priv) | |||
| 1301 | .flags = CMD_SYNC, | 1299 | .flags = CMD_SYNC, |
| 1302 | }; | 1300 | }; |
| 1303 | 1301 | ||
| 1304 | ret = iwl_trans_send_cmd(trans(priv), &cmd); | 1302 | ret = iwl_dvm_send_cmd(priv, &cmd); |
| 1305 | if (ret) | 1303 | if (ret) |
| 1306 | IWL_ERR(priv, "echo testing fail: 0X%x\n", ret); | 1304 | IWL_ERR(priv, "echo testing fail: 0X%x\n", ret); |
| 1307 | else | 1305 | else |
| @@ -1335,30 +1333,20 @@ void iwl_bg_watchdog(unsigned long data) | |||
| 1335 | int cnt; | 1333 | int cnt; |
| 1336 | unsigned long timeout; | 1334 | unsigned long timeout; |
| 1337 | 1335 | ||
| 1338 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 1336 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 1339 | return; | 1337 | return; |
| 1340 | 1338 | ||
| 1341 | if (iwl_is_rfkill(priv->shrd)) | 1339 | if (iwl_is_rfkill(priv)) |
| 1342 | return; | 1340 | return; |
| 1343 | 1341 | ||
| 1344 | timeout = cfg(priv)->base_params->wd_timeout; | 1342 | timeout = hw_params(priv).wd_timeout; |
| 1345 | if (timeout == 0) | 1343 | if (timeout == 0) |
| 1346 | return; | 1344 | return; |
| 1347 | 1345 | ||
| 1348 | /* monitor and check for stuck cmd queue */ | 1346 | /* monitor and check for stuck queues */ |
| 1349 | if (iwl_check_stuck_queue(priv, priv->shrd->cmd_queue)) | 1347 | for (cnt = 0; cnt < cfg(priv)->base_params->num_of_queues; cnt++) |
| 1350 | return; | 1348 | if (iwl_check_stuck_queue(priv, cnt)) |
| 1351 | 1349 | return; | |
| 1352 | /* monitor and check for other stuck queues */ | ||
| 1353 | if (iwl_is_any_associated(priv)) { | ||
| 1354 | for (cnt = 0; cnt < hw_params(priv).max_txq_num; cnt++) { | ||
| 1355 | /* skip as we already checked the command queue */ | ||
| 1356 | if (cnt == priv->shrd->cmd_queue) | ||
| 1357 | continue; | ||
| 1358 | if (iwl_check_stuck_queue(priv, cnt)) | ||
| 1359 | return; | ||
| 1360 | } | ||
| 1361 | } | ||
| 1362 | 1350 | ||
| 1363 | mod_timer(&priv->watchdog, jiffies + | 1351 | mod_timer(&priv->watchdog, jiffies + |
| 1364 | msecs_to_jiffies(IWL_WD_TICK(timeout))); | 1352 | msecs_to_jiffies(IWL_WD_TICK(timeout))); |
| @@ -1366,7 +1354,7 @@ void iwl_bg_watchdog(unsigned long data) | |||
| 1366 | 1354 | ||
| 1367 | void iwl_setup_watchdog(struct iwl_priv *priv) | 1355 | void iwl_setup_watchdog(struct iwl_priv *priv) |
| 1368 | { | 1356 | { |
| 1369 | unsigned int timeout = cfg(priv)->base_params->wd_timeout; | 1357 | unsigned int timeout = hw_params(priv).wd_timeout; |
| 1370 | 1358 | ||
| 1371 | if (!iwlagn_mod_params.wd_disable) { | 1359 | if (!iwlagn_mod_params.wd_disable) { |
| 1372 | /* use system default */ | 1360 | /* use system default */ |
| @@ -1471,34 +1459,19 @@ void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) | |||
| 1471 | { | 1459 | { |
| 1472 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 1460 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
| 1473 | 1461 | ||
| 1474 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); | 1462 | if (state) |
| 1475 | } | 1463 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
| 1464 | else | ||
| 1465 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | ||
| 1476 | 1466 | ||
| 1477 | void iwl_nic_config(struct iwl_priv *priv) | 1467 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); |
| 1478 | { | ||
| 1479 | cfg(priv)->lib->nic_config(priv); | ||
| 1480 | } | 1468 | } |
| 1481 | 1469 | ||
| 1482 | void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) | 1470 | void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) |
| 1483 | { | 1471 | { |
| 1484 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
| 1485 | struct ieee80211_tx_info *info; | 1472 | struct ieee80211_tx_info *info; |
| 1486 | 1473 | ||
| 1487 | info = IEEE80211_SKB_CB(skb); | 1474 | info = IEEE80211_SKB_CB(skb); |
| 1488 | kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1])); | 1475 | kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1])); |
| 1489 | dev_kfree_skb_any(skb); | 1476 | dev_kfree_skb_any(skb); |
| 1490 | } | 1477 | } |
| 1491 | |||
| 1492 | void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac) | ||
| 1493 | { | ||
| 1494 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
| 1495 | |||
| 1496 | ieee80211_stop_queue(priv->hw, ac); | ||
| 1497 | } | ||
| 1498 | |||
| 1499 | void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, u8 ac) | ||
| 1500 | { | ||
| 1501 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
| 1502 | |||
| 1503 | ieee80211_wake_queue(priv->hw, ac); | ||
| 1504 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 42630f5e8de7..635eb685edeb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
| @@ -77,12 +77,6 @@ struct iwl_cmd; | |||
| 77 | struct iwl_lib_ops { | 77 | struct iwl_lib_ops { |
| 78 | /* set hw dependent parameters */ | 78 | /* set hw dependent parameters */ |
| 79 | void (*set_hw_params)(struct iwl_priv *priv); | 79 | void (*set_hw_params)(struct iwl_priv *priv); |
| 80 | /* setup BT Rx handler */ | ||
| 81 | void (*bt_rx_handler_setup)(struct iwl_priv *priv); | ||
| 82 | /* setup BT related deferred work */ | ||
| 83 | void (*bt_setup_deferred_work)(struct iwl_priv *priv); | ||
| 84 | /* cancel deferred work */ | ||
| 85 | void (*cancel_deferred_work)(struct iwl_priv *priv); | ||
| 86 | int (*set_channel_switch)(struct iwl_priv *priv, | 80 | int (*set_channel_switch)(struct iwl_priv *priv, |
| 87 | struct ieee80211_channel_switch *ch_switch); | 81 | struct ieee80211_channel_switch *ch_switch); |
| 88 | /* device specific configuration */ | 82 | /* device specific configuration */ |
| @@ -95,72 +89,6 @@ struct iwl_lib_ops { | |||
| 95 | void (*temperature)(struct iwl_priv *priv); | 89 | void (*temperature)(struct iwl_priv *priv); |
| 96 | }; | 90 | }; |
| 97 | 91 | ||
| 98 | /* | ||
| 99 | * @max_ll_items: max number of OTP blocks | ||
| 100 | * @shadow_ram_support: shadow support for OTP memory | ||
| 101 | * @led_compensation: compensate on the led on/off time per HW according | ||
| 102 | * to the deviation to achieve the desired led frequency. | ||
| 103 | * The detail algorithm is described in iwl-led.c | ||
| 104 | * @chain_noise_num_beacons: number of beacons used to compute chain noise | ||
| 105 | * @adv_thermal_throttle: support advance thermal throttle | ||
| 106 | * @support_ct_kill_exit: support ct kill exit condition | ||
| 107 | * @support_wimax_coexist: support wimax/wifi co-exist | ||
| 108 | * @plcp_delta_threshold: plcp error rate threshold used to trigger | ||
| 109 | * radio tuning when there is a high receiving plcp error rate | ||
| 110 | * @chain_noise_scale: default chain noise scale used for gain computation | ||
| 111 | * @wd_timeout: TX queues watchdog timeout | ||
| 112 | * @max_event_log_size: size of event log buffer size for ucode event logging | ||
| 113 | * @shadow_reg_enable: HW shadhow register bit | ||
| 114 | * @no_idle_support: do not support idle mode | ||
| 115 | * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up | ||
| 116 | * wd_disable: disable watchdog timer | ||
| 117 | */ | ||
| 118 | struct iwl_base_params { | ||
| 119 | int eeprom_size; | ||
| 120 | int num_of_queues; /* def: HW dependent */ | ||
| 121 | int num_of_ampdu_queues;/* def: HW dependent */ | ||
| 122 | /* for iwl_apm_init() */ | ||
| 123 | u32 pll_cfg_val; | ||
| 124 | |||
| 125 | const u16 max_ll_items; | ||
| 126 | const bool shadow_ram_support; | ||
| 127 | u16 led_compensation; | ||
| 128 | bool adv_thermal_throttle; | ||
| 129 | bool support_ct_kill_exit; | ||
| 130 | const bool support_wimax_coexist; | ||
| 131 | u8 plcp_delta_threshold; | ||
| 132 | s32 chain_noise_scale; | ||
| 133 | unsigned int wd_timeout; | ||
| 134 | u32 max_event_log_size; | ||
| 135 | const bool shadow_reg_enable; | ||
| 136 | const bool no_idle_support; | ||
| 137 | const bool hd_v2; | ||
| 138 | const bool wd_disable; | ||
| 139 | }; | ||
| 140 | /* | ||
| 141 | * @advanced_bt_coexist: support advanced bt coexist | ||
| 142 | * @bt_init_traffic_load: specify initial bt traffic load | ||
| 143 | * @bt_prio_boost: default bt priority boost value | ||
| 144 | * @agg_time_limit: maximum number of uSec in aggregation | ||
| 145 | * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode | ||
| 146 | */ | ||
| 147 | struct iwl_bt_params { | ||
| 148 | bool advanced_bt_coexist; | ||
| 149 | u8 bt_init_traffic_load; | ||
| 150 | u8 bt_prio_boost; | ||
| 151 | u16 agg_time_limit; | ||
| 152 | bool bt_sco_disable; | ||
| 153 | bool bt_session_2; | ||
| 154 | }; | ||
| 155 | /* | ||
| 156 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic | ||
| 157 | */ | ||
| 158 | struct iwl_ht_params { | ||
| 159 | const bool ht_greenfield_support; /* if used set to true */ | ||
| 160 | bool use_rts_for_aggregation; | ||
| 161 | enum ieee80211_smps_mode smps_mode; | ||
| 162 | }; | ||
| 163 | |||
| 164 | /*************************** | 92 | /*************************** |
| 165 | * L i b * | 93 | * L i b * |
| 166 | ***************************/ | 94 | ***************************/ |
| @@ -244,8 +172,6 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); | |||
| 244 | void iwl_force_scan_end(struct iwl_priv *priv); | 172 | void iwl_force_scan_end(struct iwl_priv *priv); |
| 245 | void iwl_internal_short_hw_scan(struct iwl_priv *priv); | 173 | void iwl_internal_short_hw_scan(struct iwl_priv *priv); |
| 246 | int iwl_force_reset(struct iwl_priv *priv, int mode, bool external); | 174 | int iwl_force_reset(struct iwl_priv *priv, int mode, bool external); |
| 247 | u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, | ||
| 248 | const u8 *ta, const u8 *ie, int ie_len, int left); | ||
| 249 | void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); | 175 | void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); |
| 250 | void iwl_setup_scan_deferred_work(struct iwl_priv *priv); | 176 | void iwl_setup_scan_deferred_work(struct iwl_priv *priv); |
| 251 | void iwl_cancel_scan_deferred_work(struct iwl_priv *priv); | 177 | void iwl_cancel_scan_deferred_work(struct iwl_priv *priv); |
| @@ -265,6 +191,10 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, | |||
| 265 | 191 | ||
| 266 | #define IWL_SCAN_CHECK_WATCHDOG (HZ * 7) | 192 | #define IWL_SCAN_CHECK_WATCHDOG (HZ * 7) |
| 267 | 193 | ||
| 194 | /* traffic log definitions */ | ||
| 195 | #define IWL_TRAFFIC_ENTRIES (256) | ||
| 196 | #define IWL_TRAFFIC_ENTRY_SIZE (64) | ||
| 197 | |||
| 268 | /***************************************************** | 198 | /***************************************************** |
| 269 | * S e n d i n g H o s t C o m m a n d s * | 199 | * S e n d i n g H o s t C o m m a n d s * |
| 270 | *****************************************************/ | 200 | *****************************************************/ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.c b/drivers/net/wireless/iwlwifi/iwl-debug.c index 4bc2e70051d6..059efabda184 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.c +++ b/drivers/net/wireless/iwlwifi/iwl-debug.c | |||
| @@ -104,7 +104,7 @@ void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only, | |||
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) | 106 | #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) |
| 107 | void __iwl_dbg(struct iwl_shared *shared, struct device *dev, | 107 | void __iwl_dbg(struct device *dev, |
| 108 | u32 level, bool limit, const char *function, | 108 | u32 level, bool limit, const char *function, |
| 109 | const char *fmt, ...) | 109 | const char *fmt, ...) |
| 110 | { | 110 | { |
| @@ -116,7 +116,7 @@ void __iwl_dbg(struct iwl_shared *shared, struct device *dev, | |||
| 116 | va_start(args, fmt); | 116 | va_start(args, fmt); |
| 117 | vaf.va = &args; | 117 | vaf.va = &args; |
| 118 | #ifdef CONFIG_IWLWIFI_DEBUG | 118 | #ifdef CONFIG_IWLWIFI_DEBUG |
| 119 | if (iwl_get_debug_level(shared) & level && | 119 | if (iwl_have_debug_level(level) && |
| 120 | (!limit || net_ratelimit())) | 120 | (!limit || net_ratelimit())) |
| 121 | dev_err(dev, "%c %s %pV", in_interrupt() ? 'I' : 'U', | 121 | dev_err(dev, "%c %s %pV", in_interrupt() ? 'I' : 'U', |
| 122 | function, &vaf); | 122 | function, &vaf); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 01b23303d736..a6b32a11e103 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
| @@ -47,12 +47,12 @@ void __iwl_crit(struct device *dev, const char *fmt, ...); | |||
| 47 | #define IWL_CRIT(m, f, a...) __iwl_crit(trans(m)->dev, f, ## a) | 47 | #define IWL_CRIT(m, f, a...) __iwl_crit(trans(m)->dev, f, ## a) |
| 48 | 48 | ||
| 49 | #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) | 49 | #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) |
| 50 | void __iwl_dbg(struct iwl_shared *shared, struct device *dev, | 50 | void __iwl_dbg(struct device *dev, |
| 51 | u32 level, bool limit, const char *function, | 51 | u32 level, bool limit, const char *function, |
| 52 | const char *fmt, ...); | 52 | const char *fmt, ...); |
| 53 | #else | 53 | #else |
| 54 | static inline void | 54 | static inline void |
| 55 | __iwl_dbg(struct iwl_shared *shared, struct device *dev, | 55 | __iwl_dbg(struct device *dev, |
| 56 | u32 level, bool limit, const char *function, | 56 | u32 level, bool limit, const char *function, |
| 57 | const char *fmt, ...) | 57 | const char *fmt, ...) |
| 58 | {} | 58 | {} |
| @@ -65,35 +65,19 @@ do { \ | |||
| 65 | } while (0) | 65 | } while (0) |
| 66 | 66 | ||
| 67 | #define IWL_DEBUG(m, level, fmt, args...) \ | 67 | #define IWL_DEBUG(m, level, fmt, args...) \ |
| 68 | __iwl_dbg((m)->shrd, trans(m)->dev, level, false, __func__, fmt, ##args) | 68 | __iwl_dbg(trans(m)->dev, level, false, __func__, fmt, ##args) |
| 69 | #define IWL_DEBUG_LIMIT(m, level, fmt, args...) \ | 69 | #define IWL_DEBUG_LIMIT(m, level, fmt, args...) \ |
| 70 | __iwl_dbg((m)->shrd, trans(m)->dev, level, true, __func__, fmt, ##args) | 70 | __iwl_dbg(trans(m)->dev, level, true, __func__, fmt, ##args) |
| 71 | 71 | ||
| 72 | #ifdef CONFIG_IWLWIFI_DEBUG | 72 | #ifdef CONFIG_IWLWIFI_DEBUG |
| 73 | #define iwl_print_hex_dump(m, level, p, len) \ | 73 | #define iwl_print_hex_dump(m, level, p, len) \ |
| 74 | do { \ | 74 | do { \ |
| 75 | if (iwl_get_debug_level((m)->shrd) & level) \ | 75 | if (iwl_have_debug_level(level)) \ |
| 76 | print_hex_dump(KERN_DEBUG, "iwl data: ", \ | 76 | print_hex_dump(KERN_DEBUG, "iwl data: ", \ |
| 77 | DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \ | 77 | DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \ |
| 78 | } while (0) | 78 | } while (0) |
| 79 | #define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \ | ||
| 80 | do { \ | ||
| 81 | if (!iwl_is_rfkill((m)->shrd)) \ | ||
| 82 | IWL_ERR(m, fmt, ##args); \ | ||
| 83 | else \ | ||
| 84 | __iwl_err(trans(m)->dev, true, \ | ||
| 85 | !(iwl_get_debug_level((m)->shrd) & IWL_DL_RADIO),\ | ||
| 86 | fmt, ##args); \ | ||
| 87 | } while (0) | ||
| 88 | #else | 79 | #else |
| 89 | #define iwl_print_hex_dump(m, level, p, len) | 80 | #define iwl_print_hex_dump(m, level, p, len) |
| 90 | #define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \ | ||
| 91 | do { \ | ||
| 92 | if (!iwl_is_rfkill((m)->shrd)) \ | ||
| 93 | IWL_ERR(m, fmt, ##args); \ | ||
| 94 | else \ | ||
| 95 | __iwl_err(trans(m)->dev, true, true, fmt, ##args); \ | ||
| 96 | } while (0) | ||
| 97 | #endif /* CONFIG_IWLWIFI_DEBUG */ | 81 | #endif /* CONFIG_IWLWIFI_DEBUG */ |
| 98 | 82 | ||
| 99 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 83 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index ad74138e1c70..9b71c87847c2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
| @@ -40,7 +40,6 @@ | |||
| 40 | #include "iwl-core.h" | 40 | #include "iwl-core.h" |
| 41 | #include "iwl-io.h" | 41 | #include "iwl-io.h" |
| 42 | #include "iwl-agn.h" | 42 | #include "iwl-agn.h" |
| 43 | #include "iwl-wifi.h" | ||
| 44 | 43 | ||
| 45 | /* create and remove of files */ | 44 | /* create and remove of files */ |
| 46 | #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ | 45 | #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ |
| @@ -235,12 +234,11 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
| 235 | 234 | ||
| 236 | /* default is to dump the entire data segment */ | 235 | /* default is to dump the entire data segment */ |
| 237 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { | 236 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { |
| 238 | struct iwl_nic *nic = nic(priv); | ||
| 239 | priv->dbgfs_sram_offset = 0x800000; | 237 | priv->dbgfs_sram_offset = 0x800000; |
| 240 | if (nic->shrd->ucode_type == IWL_UCODE_INIT) | 238 | if (priv->shrd->ucode_type == IWL_UCODE_INIT) |
| 241 | priv->dbgfs_sram_len = nic->fw.ucode_init.data.len; | 239 | priv->dbgfs_sram_len = priv->fw->ucode_init.data.len; |
| 242 | else | 240 | else |
| 243 | priv->dbgfs_sram_len = nic->fw.ucode_rt.data.len; | 241 | priv->dbgfs_sram_len = priv->fw->ucode_rt.data.len; |
| 244 | } | 242 | } |
| 245 | len = priv->dbgfs_sram_len; | 243 | len = priv->dbgfs_sram_len; |
| 246 | 244 | ||
| @@ -343,7 +341,7 @@ static ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file, | |||
| 343 | 341 | ||
| 344 | return simple_read_from_buffer(user_buf, count, ppos, | 342 | return simple_read_from_buffer(user_buf, count, ppos, |
| 345 | priv->wowlan_sram, | 343 | priv->wowlan_sram, |
| 346 | nic(priv)->fw.ucode_wowlan.data.len); | 344 | priv->fw->ucode_wowlan.data.len); |
| 347 | } | 345 | } |
| 348 | static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, | 346 | static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, |
| 349 | size_t count, loff_t *ppos) | 347 | size_t count, loff_t *ppos) |
| @@ -456,7 +454,7 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, | |||
| 456 | char *buf; | 454 | char *buf; |
| 457 | ssize_t ret; | 455 | ssize_t ret; |
| 458 | 456 | ||
| 459 | if (!test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status)) | 457 | if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status)) |
| 460 | return -EAGAIN; | 458 | return -EAGAIN; |
| 461 | 459 | ||
| 462 | buf = kzalloc(bufsz, GFP_KERNEL); | 460 | buf = kzalloc(bufsz, GFP_KERNEL); |
| @@ -527,32 +525,26 @@ static ssize_t iwl_dbgfs_status_read(struct file *file, | |||
| 527 | 525 | ||
| 528 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n", | 526 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n", |
| 529 | test_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status)); | 527 | test_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status)); |
| 530 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n", | ||
| 531 | test_bit(STATUS_INT_ENABLED, &priv->shrd->status)); | ||
| 532 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", | 528 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", |
| 533 | test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)); | 529 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
| 534 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n", | 530 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n", |
| 535 | test_bit(STATUS_CT_KILL, &priv->shrd->status)); | 531 | test_bit(STATUS_CT_KILL, &priv->status)); |
| 536 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n", | ||
| 537 | test_bit(STATUS_INIT, &priv->shrd->status)); | ||
| 538 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", | 532 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", |
| 539 | test_bit(STATUS_ALIVE, &priv->shrd->status)); | 533 | test_bit(STATUS_ALIVE, &priv->status)); |
| 540 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", | 534 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", |
| 541 | test_bit(STATUS_READY, &priv->shrd->status)); | 535 | test_bit(STATUS_READY, &priv->status)); |
| 542 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n", | ||
| 543 | test_bit(STATUS_TEMPERATURE, &priv->shrd->status)); | ||
| 544 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n", | 536 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n", |
| 545 | test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status)); | 537 | test_bit(STATUS_GEO_CONFIGURED, &priv->status)); |
| 546 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", | 538 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", |
| 547 | test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)); | 539 | test_bit(STATUS_EXIT_PENDING, &priv->status)); |
| 548 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", | 540 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", |
| 549 | test_bit(STATUS_STATISTICS, &priv->shrd->status)); | 541 | test_bit(STATUS_STATISTICS, &priv->status)); |
| 550 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n", | 542 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n", |
| 551 | test_bit(STATUS_SCANNING, &priv->shrd->status)); | 543 | test_bit(STATUS_SCANNING, &priv->status)); |
| 552 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n", | 544 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n", |
| 553 | test_bit(STATUS_SCAN_ABORTING, &priv->shrd->status)); | 545 | test_bit(STATUS_SCAN_ABORTING, &priv->status)); |
| 554 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n", | 546 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n", |
| 555 | test_bit(STATUS_SCAN_HW, &priv->shrd->status)); | 547 | test_bit(STATUS_SCAN_HW, &priv->status)); |
| 556 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n", | 548 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n", |
| 557 | test_bit(STATUS_POWER_PMI, &priv->shrd->status)); | 549 | test_bit(STATUS_POWER_PMI, &priv->shrd->status)); |
| 558 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n", | 550 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n", |
| @@ -758,14 +750,14 @@ static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file, | |||
| 758 | if (value != -1 && (value < 0 || value >= IWL_POWER_NUM)) | 750 | if (value != -1 && (value < 0 || value >= IWL_POWER_NUM)) |
| 759 | return -EINVAL; | 751 | return -EINVAL; |
| 760 | 752 | ||
| 761 | if (!iwl_is_ready_rf(priv->shrd)) | 753 | if (!iwl_is_ready_rf(priv)) |
| 762 | return -EAGAIN; | 754 | return -EAGAIN; |
| 763 | 755 | ||
| 764 | priv->power_data.debug_sleep_level_override = value; | 756 | priv->power_data.debug_sleep_level_override = value; |
| 765 | 757 | ||
| 766 | mutex_lock(&priv->shrd->mutex); | 758 | mutex_lock(&priv->mutex); |
| 767 | iwl_power_update_mode(priv, true); | 759 | iwl_power_update_mode(priv, true); |
| 768 | mutex_unlock(&priv->shrd->mutex); | 760 | mutex_unlock(&priv->mutex); |
| 769 | 761 | ||
| 770 | return count; | 762 | return count; |
| 771 | } | 763 | } |
| @@ -836,7 +828,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, | |||
| 836 | 828 | ||
| 837 | char *buf; | 829 | char *buf; |
| 838 | int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + | 830 | int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + |
| 839 | (hw_params(priv).max_txq_num * 32 * 8) + 400; | 831 | (cfg(priv)->base_params->num_of_queues * 32 * 8) + 400; |
| 840 | const u8 *ptr; | 832 | const u8 *ptr; |
| 841 | ssize_t ret; | 833 | ssize_t ret; |
| 842 | 834 | ||
| @@ -845,8 +837,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, | |||
| 845 | IWL_ERR(priv, "Can not allocate buffer\n"); | 837 | IWL_ERR(priv, "Can not allocate buffer\n"); |
| 846 | return -ENOMEM; | 838 | return -ENOMEM; |
| 847 | } | 839 | } |
| 848 | if (priv->tx_traffic && | 840 | if (priv->tx_traffic && iwl_have_debug_level(IWL_DL_TX)) { |
| 849 | (iwl_get_debug_level(priv->shrd) & IWL_DL_TX)) { | ||
| 850 | ptr = priv->tx_traffic; | 841 | ptr = priv->tx_traffic; |
| 851 | pos += scnprintf(buf + pos, bufsz - pos, | 842 | pos += scnprintf(buf + pos, bufsz - pos, |
| 852 | "Tx Traffic idx: %u\n", priv->tx_traffic_idx); | 843 | "Tx Traffic idx: %u\n", priv->tx_traffic_idx); |
| @@ -864,8 +855,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, | |||
| 864 | } | 855 | } |
| 865 | } | 856 | } |
| 866 | 857 | ||
| 867 | if (priv->rx_traffic && | 858 | if (priv->rx_traffic && iwl_have_debug_level(IWL_DL_RX)) { |
| 868 | (iwl_get_debug_level(priv->shrd) & IWL_DL_RX)) { | ||
| 869 | ptr = priv->rx_traffic; | 859 | ptr = priv->rx_traffic; |
| 870 | pos += scnprintf(buf + pos, bufsz - pos, | 860 | pos += scnprintf(buf + pos, bufsz - pos, |
| 871 | "Rx Traffic idx: %u\n", priv->rx_traffic_idx); | 861 | "Rx Traffic idx: %u\n", priv->rx_traffic_idx); |
| @@ -920,6 +910,8 @@ static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) | |||
| 920 | int p = 0; | 910 | int p = 0; |
| 921 | u32 flag; | 911 | u32 flag; |
| 922 | 912 | ||
| 913 | lockdep_assert_held(&priv->statistics.lock); | ||
| 914 | |||
| 923 | flag = le32_to_cpu(priv->statistics.flag); | 915 | flag = le32_to_cpu(priv->statistics.flag); |
| 924 | 916 | ||
| 925 | p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag); | 917 | p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag); |
| @@ -953,7 +945,7 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, | |||
| 953 | struct statistics_rx_non_phy *delta_general, *max_general; | 945 | struct statistics_rx_non_phy *delta_general, *max_general; |
| 954 | struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht; | 946 | struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht; |
| 955 | 947 | ||
| 956 | if (!iwl_is_alive(priv->shrd)) | 948 | if (!iwl_is_alive(priv)) |
| 957 | return -EAGAIN; | 949 | return -EAGAIN; |
| 958 | 950 | ||
| 959 | buf = kzalloc(bufsz, GFP_KERNEL); | 951 | buf = kzalloc(bufsz, GFP_KERNEL); |
| @@ -967,6 +959,7 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, | |||
| 967 | * the last statistics notification from uCode | 959 | * the last statistics notification from uCode |
| 968 | * might not reflect the current uCode activity | 960 | * might not reflect the current uCode activity |
| 969 | */ | 961 | */ |
| 962 | spin_lock_bh(&priv->statistics.lock); | ||
| 970 | ofdm = &priv->statistics.rx_ofdm; | 963 | ofdm = &priv->statistics.rx_ofdm; |
| 971 | cck = &priv->statistics.rx_cck; | 964 | cck = &priv->statistics.rx_cck; |
| 972 | general = &priv->statistics.rx_non_phy; | 965 | general = &priv->statistics.rx_non_phy; |
| @@ -1363,6 +1356,8 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, | |||
| 1363 | accum_ht->unsupport_mcs, | 1356 | accum_ht->unsupport_mcs, |
| 1364 | delta_ht->unsupport_mcs, max_ht->unsupport_mcs); | 1357 | delta_ht->unsupport_mcs, max_ht->unsupport_mcs); |
| 1365 | 1358 | ||
| 1359 | spin_unlock_bh(&priv->statistics.lock); | ||
| 1360 | |||
| 1366 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 1361 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
| 1367 | kfree(buf); | 1362 | kfree(buf); |
| 1368 | return ret; | 1363 | return ret; |
| @@ -1379,7 +1374,7 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, | |||
| 1379 | ssize_t ret; | 1374 | ssize_t ret; |
| 1380 | struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx; | 1375 | struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx; |
| 1381 | 1376 | ||
| 1382 | if (!iwl_is_alive(priv->shrd)) | 1377 | if (!iwl_is_alive(priv)) |
| 1383 | return -EAGAIN; | 1378 | return -EAGAIN; |
| 1384 | 1379 | ||
| 1385 | buf = kzalloc(bufsz, GFP_KERNEL); | 1380 | buf = kzalloc(bufsz, GFP_KERNEL); |
| @@ -1392,6 +1387,8 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, | |||
| 1392 | * the last statistics notification from uCode | 1387 | * the last statistics notification from uCode |
| 1393 | * might not reflect the current uCode activity | 1388 | * might not reflect the current uCode activity |
| 1394 | */ | 1389 | */ |
| 1390 | spin_lock_bh(&priv->statistics.lock); | ||
| 1391 | |||
| 1395 | tx = &priv->statistics.tx; | 1392 | tx = &priv->statistics.tx; |
| 1396 | accum_tx = &priv->accum_stats.tx; | 1393 | accum_tx = &priv->accum_stats.tx; |
| 1397 | delta_tx = &priv->delta_stats.tx; | 1394 | delta_tx = &priv->delta_stats.tx; |
| @@ -1541,19 +1538,25 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, | |||
| 1541 | if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) { | 1538 | if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) { |
| 1542 | pos += scnprintf(buf + pos, bufsz - pos, | 1539 | pos += scnprintf(buf + pos, bufsz - pos, |
| 1543 | "tx power: (1/2 dB step)\n"); | 1540 | "tx power: (1/2 dB step)\n"); |
| 1544 | if ((cfg(priv)->valid_tx_ant & ANT_A) && tx->tx_power.ant_a) | 1541 | if ((hw_params(priv).valid_tx_ant & ANT_A) && |
| 1542 | tx->tx_power.ant_a) | ||
| 1545 | pos += scnprintf(buf + pos, bufsz - pos, | 1543 | pos += scnprintf(buf + pos, bufsz - pos, |
| 1546 | fmt_hex, "antenna A:", | 1544 | fmt_hex, "antenna A:", |
| 1547 | tx->tx_power.ant_a); | 1545 | tx->tx_power.ant_a); |
| 1548 | if ((cfg(priv)->valid_tx_ant & ANT_B) && tx->tx_power.ant_b) | 1546 | if ((hw_params(priv).valid_tx_ant & ANT_B) && |
| 1547 | tx->tx_power.ant_b) | ||
| 1549 | pos += scnprintf(buf + pos, bufsz - pos, | 1548 | pos += scnprintf(buf + pos, bufsz - pos, |
| 1550 | fmt_hex, "antenna B:", | 1549 | fmt_hex, "antenna B:", |
| 1551 | tx->tx_power.ant_b); | 1550 | tx->tx_power.ant_b); |
| 1552 | if ((cfg(priv)->valid_tx_ant & ANT_C) && tx->tx_power.ant_c) | 1551 | if ((hw_params(priv).valid_tx_ant & ANT_C) && |
| 1552 | tx->tx_power.ant_c) | ||
| 1553 | pos += scnprintf(buf + pos, bufsz - pos, | 1553 | pos += scnprintf(buf + pos, bufsz - pos, |
| 1554 | fmt_hex, "antenna C:", | 1554 | fmt_hex, "antenna C:", |
| 1555 | tx->tx_power.ant_c); | 1555 | tx->tx_power.ant_c); |
| 1556 | } | 1556 | } |
| 1557 | |||
| 1558 | spin_unlock_bh(&priv->statistics.lock); | ||
| 1559 | |||
| 1557 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 1560 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
| 1558 | kfree(buf); | 1561 | kfree(buf); |
| 1559 | return ret; | 1562 | return ret; |
| @@ -1573,7 +1576,7 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, | |||
| 1573 | struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; | 1576 | struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; |
| 1574 | struct statistics_div *div, *accum_div, *delta_div, *max_div; | 1577 | struct statistics_div *div, *accum_div, *delta_div, *max_div; |
| 1575 | 1578 | ||
| 1576 | if (!iwl_is_alive(priv->shrd)) | 1579 | if (!iwl_is_alive(priv)) |
| 1577 | return -EAGAIN; | 1580 | return -EAGAIN; |
| 1578 | 1581 | ||
| 1579 | buf = kzalloc(bufsz, GFP_KERNEL); | 1582 | buf = kzalloc(bufsz, GFP_KERNEL); |
| @@ -1586,6 +1589,9 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, | |||
| 1586 | * the last statistics notification from uCode | 1589 | * the last statistics notification from uCode |
| 1587 | * might not reflect the current uCode activity | 1590 | * might not reflect the current uCode activity |
| 1588 | */ | 1591 | */ |
| 1592 | |||
| 1593 | spin_lock_bh(&priv->statistics.lock); | ||
| 1594 | |||
| 1589 | general = &priv->statistics.common; | 1595 | general = &priv->statistics.common; |
| 1590 | dbg = &priv->statistics.common.dbg; | 1596 | dbg = &priv->statistics.common.dbg; |
| 1591 | div = &priv->statistics.common.div; | 1597 | div = &priv->statistics.common.div; |
| @@ -1670,6 +1676,9 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, | |||
| 1670 | accum_general->num_of_sos_states, | 1676 | accum_general->num_of_sos_states, |
| 1671 | delta_general->num_of_sos_states, | 1677 | delta_general->num_of_sos_states, |
| 1672 | max_general->num_of_sos_states); | 1678 | max_general->num_of_sos_states); |
| 1679 | |||
| 1680 | spin_unlock_bh(&priv->statistics.lock); | ||
| 1681 | |||
| 1673 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 1682 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
| 1674 | kfree(buf); | 1683 | kfree(buf); |
| 1675 | return ret; | 1684 | return ret; |
| @@ -1686,16 +1695,16 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, | |||
| 1686 | ssize_t ret; | 1695 | ssize_t ret; |
| 1687 | struct statistics_bt_activity *bt, *accum_bt; | 1696 | struct statistics_bt_activity *bt, *accum_bt; |
| 1688 | 1697 | ||
| 1689 | if (!iwl_is_alive(priv->shrd)) | 1698 | if (!iwl_is_alive(priv)) |
| 1690 | return -EAGAIN; | 1699 | return -EAGAIN; |
| 1691 | 1700 | ||
| 1692 | if (!priv->bt_enable_flag) | 1701 | if (!priv->bt_enable_flag) |
| 1693 | return -EINVAL; | 1702 | return -EINVAL; |
| 1694 | 1703 | ||
| 1695 | /* make request to uCode to retrieve statistics information */ | 1704 | /* make request to uCode to retrieve statistics information */ |
| 1696 | mutex_lock(&priv->shrd->mutex); | 1705 | mutex_lock(&priv->mutex); |
| 1697 | ret = iwl_send_statistics_request(priv, CMD_SYNC, false); | 1706 | ret = iwl_send_statistics_request(priv, CMD_SYNC, false); |
| 1698 | mutex_unlock(&priv->shrd->mutex); | 1707 | mutex_unlock(&priv->mutex); |
| 1699 | 1708 | ||
| 1700 | if (ret) { | 1709 | if (ret) { |
| 1701 | IWL_ERR(priv, | 1710 | IWL_ERR(priv, |
| @@ -1713,6 +1722,9 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, | |||
| 1713 | * the last statistics notification from uCode | 1722 | * the last statistics notification from uCode |
| 1714 | * might not reflect the current uCode activity | 1723 | * might not reflect the current uCode activity |
| 1715 | */ | 1724 | */ |
| 1725 | |||
| 1726 | spin_lock_bh(&priv->statistics.lock); | ||
| 1727 | |||
| 1716 | bt = &priv->statistics.bt_activity; | 1728 | bt = &priv->statistics.bt_activity; |
| 1717 | accum_bt = &priv->accum_stats.bt_activity; | 1729 | accum_bt = &priv->accum_stats.bt_activity; |
| 1718 | 1730 | ||
| @@ -1758,6 +1770,8 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, | |||
| 1758 | le32_to_cpu(priv->statistics.num_bt_kills), | 1770 | le32_to_cpu(priv->statistics.num_bt_kills), |
| 1759 | priv->statistics.accum_num_bt_kills); | 1771 | priv->statistics.accum_num_bt_kills); |
| 1760 | 1772 | ||
| 1773 | spin_unlock_bh(&priv->statistics.lock); | ||
| 1774 | |||
| 1761 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 1775 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
| 1762 | kfree(buf); | 1776 | kfree(buf); |
| 1763 | return ret; | 1777 | return ret; |
| @@ -1774,7 +1788,7 @@ static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file, | |||
| 1774 | (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200; | 1788 | (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200; |
| 1775 | ssize_t ret; | 1789 | ssize_t ret; |
| 1776 | 1790 | ||
| 1777 | if (!iwl_is_alive(priv->shrd)) | 1791 | if (!iwl_is_alive(priv)) |
| 1778 | return -EAGAIN; | 1792 | return -EAGAIN; |
| 1779 | 1793 | ||
| 1780 | buf = kzalloc(bufsz, GFP_KERNEL); | 1794 | buf = kzalloc(bufsz, GFP_KERNEL); |
| @@ -2086,9 +2100,9 @@ static ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file, | |||
| 2086 | return -EFAULT; | 2100 | return -EFAULT; |
| 2087 | 2101 | ||
| 2088 | /* make request to uCode to retrieve statistics information */ | 2102 | /* make request to uCode to retrieve statistics information */ |
| 2089 | mutex_lock(&priv->shrd->mutex); | 2103 | mutex_lock(&priv->mutex); |
| 2090 | iwl_send_statistics_request(priv, CMD_SYNC, true); | 2104 | iwl_send_statistics_request(priv, CMD_SYNC, true); |
| 2091 | mutex_unlock(&priv->shrd->mutex); | 2105 | mutex_unlock(&priv->mutex); |
| 2092 | 2106 | ||
| 2093 | return count; | 2107 | return count; |
| 2094 | } | 2108 | } |
| @@ -2132,7 +2146,7 @@ static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file, | |||
| 2132 | 2146 | ||
| 2133 | if (trace) { | 2147 | if (trace) { |
| 2134 | priv->event_log.ucode_trace = true; | 2148 | priv->event_log.ucode_trace = true; |
| 2135 | if (iwl_is_alive(priv->shrd)) { | 2149 | if (iwl_is_alive(priv)) { |
| 2136 | /* start collecting data now */ | 2150 | /* start collecting data now */ |
| 2137 | mod_timer(&priv->ucode_trace, jiffies); | 2151 | mod_timer(&priv->ucode_trace, jiffies); |
| 2138 | } | 2152 | } |
| @@ -2221,7 +2235,7 @@ static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file, | |||
| 2221 | const size_t bufsz = sizeof(buf); | 2235 | const size_t bufsz = sizeof(buf); |
| 2222 | 2236 | ||
| 2223 | pos += scnprintf(buf + pos, bufsz - pos, "%u\n", | 2237 | pos += scnprintf(buf + pos, bufsz - pos, "%u\n", |
| 2224 | cfg(priv)->base_params->plcp_delta_threshold); | 2238 | priv->plcp_delta_threshold); |
| 2225 | 2239 | ||
| 2226 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 2240 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
| 2227 | } | 2241 | } |
| @@ -2243,10 +2257,10 @@ static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file, | |||
| 2243 | return -EINVAL; | 2257 | return -EINVAL; |
| 2244 | if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || | 2258 | if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || |
| 2245 | (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) | 2259 | (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) |
| 2246 | cfg(priv)->base_params->plcp_delta_threshold = | 2260 | priv->plcp_delta_threshold = |
| 2247 | IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; | 2261 | IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; |
| 2248 | else | 2262 | else |
| 2249 | cfg(priv)->base_params->plcp_delta_threshold = plcp; | 2263 | priv->plcp_delta_threshold = plcp; |
| 2250 | return count; | 2264 | return count; |
| 2251 | } | 2265 | } |
| 2252 | 2266 | ||
| @@ -2322,7 +2336,7 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file, | |||
| 2322 | if (sscanf(buf, "%d", &flush) != 1) | 2336 | if (sscanf(buf, "%d", &flush) != 1) |
| 2323 | return -EINVAL; | 2337 | return -EINVAL; |
| 2324 | 2338 | ||
| 2325 | if (iwl_is_rfkill(priv->shrd)) | 2339 | if (iwl_is_rfkill(priv)) |
| 2326 | return -EFAULT; | 2340 | return -EFAULT; |
| 2327 | 2341 | ||
| 2328 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); | 2342 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); |
| @@ -2348,7 +2362,7 @@ static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file, | |||
| 2348 | if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT) | 2362 | if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT) |
| 2349 | timeout = IWL_DEF_WD_TIMEOUT; | 2363 | timeout = IWL_DEF_WD_TIMEOUT; |
| 2350 | 2364 | ||
| 2351 | cfg(priv)->base_params->wd_timeout = timeout; | 2365 | hw_params(priv).wd_timeout = timeout; |
| 2352 | iwl_setup_watchdog(priv); | 2366 | iwl_setup_watchdog(priv); |
| 2353 | return count; | 2367 | return count; |
| 2354 | } | 2368 | } |
| @@ -2411,7 +2425,7 @@ static ssize_t iwl_dbgfs_protection_mode_read(struct file *file, | |||
| 2411 | if (cfg(priv)->ht_params) | 2425 | if (cfg(priv)->ht_params) |
| 2412 | pos += scnprintf(buf + pos, bufsz - pos, | 2426 | pos += scnprintf(buf + pos, bufsz - pos, |
| 2413 | "use %s for aggregation\n", | 2427 | "use %s for aggregation\n", |
| 2414 | (cfg(priv)->ht_params->use_rts_for_aggregation) ? | 2428 | (hw_params(priv).use_rts_for_aggregation) ? |
| 2415 | "rts/cts" : "cts-to-self"); | 2429 | "rts/cts" : "cts-to-self"); |
| 2416 | else | 2430 | else |
| 2417 | pos += scnprintf(buf + pos, bufsz - pos, "N/A"); | 2431 | pos += scnprintf(buf + pos, bufsz - pos, "N/A"); |
| @@ -2438,9 +2452,9 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file, | |||
| 2438 | if (sscanf(buf, "%d", &rts) != 1) | 2452 | if (sscanf(buf, "%d", &rts) != 1) |
| 2439 | return -EINVAL; | 2453 | return -EINVAL; |
| 2440 | if (rts) | 2454 | if (rts) |
| 2441 | cfg(priv)->ht_params->use_rts_for_aggregation = true; | 2455 | hw_params(priv).use_rts_for_aggregation = true; |
| 2442 | else | 2456 | else |
| 2443 | cfg(priv)->ht_params->use_rts_for_aggregation = false; | 2457 | hw_params(priv).use_rts_for_aggregation = false; |
| 2444 | return count; | 2458 | return count; |
| 2445 | } | 2459 | } |
| 2446 | 2460 | ||
| @@ -2486,52 +2500,6 @@ DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); | |||
| 2486 | DEBUGFS_READ_FILE_OPS(reply_tx_error); | 2500 | DEBUGFS_READ_FILE_OPS(reply_tx_error); |
| 2487 | DEBUGFS_WRITE_FILE_OPS(echo_test); | 2501 | DEBUGFS_WRITE_FILE_OPS(echo_test); |
| 2488 | 2502 | ||
| 2489 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
| 2490 | static ssize_t iwl_dbgfs_debug_level_read(struct file *file, | ||
| 2491 | char __user *user_buf, | ||
| 2492 | size_t count, loff_t *ppos) | ||
| 2493 | { | ||
| 2494 | struct iwl_priv *priv = file->private_data; | ||
| 2495 | struct iwl_shared *shrd = priv->shrd; | ||
| 2496 | char buf[11]; | ||
| 2497 | int len; | ||
| 2498 | |||
| 2499 | len = scnprintf(buf, sizeof(buf), "0x%.8x", | ||
| 2500 | iwl_get_debug_level(shrd)); | ||
| 2501 | |||
| 2502 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
| 2503 | } | ||
| 2504 | |||
| 2505 | static ssize_t iwl_dbgfs_debug_level_write(struct file *file, | ||
| 2506 | const char __user *user_buf, | ||
| 2507 | size_t count, loff_t *ppos) | ||
| 2508 | { | ||
| 2509 | struct iwl_priv *priv = file->private_data; | ||
| 2510 | struct iwl_shared *shrd = priv->shrd; | ||
| 2511 | char buf[11]; | ||
| 2512 | unsigned long val; | ||
| 2513 | int ret; | ||
| 2514 | |||
| 2515 | if (count > sizeof(buf)) | ||
| 2516 | return -EINVAL; | ||
| 2517 | |||
| 2518 | memset(buf, 0, sizeof(buf)); | ||
| 2519 | if (copy_from_user(buf, user_buf, count)) | ||
| 2520 | return -EFAULT; | ||
| 2521 | |||
| 2522 | ret = strict_strtoul(buf, 0, &val); | ||
| 2523 | if (ret) | ||
| 2524 | return ret; | ||
| 2525 | |||
| 2526 | shrd->dbg_level_dev = val; | ||
| 2527 | if (iwl_alloc_traffic_mem(priv)) | ||
| 2528 | IWL_ERR(priv, "Not enough memory to generate traffic log\n"); | ||
| 2529 | |||
| 2530 | return count; | ||
| 2531 | } | ||
| 2532 | DEBUGFS_READ_WRITE_FILE_OPS(debug_level); | ||
| 2533 | #endif /* CONFIG_IWLWIFI_DEBUG */ | ||
| 2534 | |||
| 2535 | /* | 2503 | /* |
| 2536 | * Create the debugfs files and directories | 2504 | * Create the debugfs files and directories |
| 2537 | * | 2505 | * |
| @@ -2596,9 +2564,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
| 2596 | DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); | 2564 | DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); |
| 2597 | if (iwl_advanced_bt_coexist(priv)) | 2565 | if (iwl_advanced_bt_coexist(priv)) |
| 2598 | DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); | 2566 | DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); |
| 2599 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
| 2600 | DEBUGFS_ADD_FILE(debug_level, dir_debug, S_IRUSR | S_IWUSR); | ||
| 2601 | #endif | ||
| 2602 | 2567 | ||
| 2603 | DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, | 2568 | DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, |
| 2604 | &priv->disable_sens_cal); | 2569 | &priv->disable_sens_cal); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 6e5bf0a14609..aa4b3b122da4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
| @@ -36,11 +36,10 @@ | |||
| 36 | #include <linux/wait.h> | 36 | #include <linux/wait.h> |
| 37 | #include <linux/leds.h> | 37 | #include <linux/leds.h> |
| 38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
| 39 | #include <net/ieee80211_radiotap.h> | 39 | #include <linux/mutex.h> |
| 40 | 40 | ||
| 41 | #include "iwl-eeprom.h" | 41 | #include "iwl-eeprom.h" |
| 42 | #include "iwl-csr.h" | 42 | #include "iwl-csr.h" |
| 43 | #include "iwl-prph.h" | ||
| 44 | #include "iwl-debug.h" | 43 | #include "iwl-debug.h" |
| 45 | #include "iwl-agn-hw.h" | 44 | #include "iwl-agn-hw.h" |
| 46 | #include "iwl-led.h" | 45 | #include "iwl-led.h" |
| @@ -50,6 +49,7 @@ | |||
| 50 | #include "iwl-trans.h" | 49 | #include "iwl-trans.h" |
| 51 | #include "iwl-shared.h" | 50 | #include "iwl-shared.h" |
| 52 | #include "iwl-op-mode.h" | 51 | #include "iwl-op-mode.h" |
| 52 | #include "iwl-notif-wait.h" | ||
| 53 | 53 | ||
| 54 | struct iwl_tx_queue; | 54 | struct iwl_tx_queue; |
| 55 | 55 | ||
| @@ -294,7 +294,6 @@ struct iwl_vif_priv { | |||
| 294 | 294 | ||
| 295 | struct iwl_sensitivity_ranges { | 295 | struct iwl_sensitivity_ranges { |
| 296 | u16 min_nrg_cck; | 296 | u16 min_nrg_cck; |
| 297 | u16 max_nrg_cck; | ||
| 298 | 297 | ||
| 299 | u16 nrg_th_cck; | 298 | u16 nrg_th_cck; |
| 300 | u16 nrg_th_ofdm; | 299 | u16 nrg_th_ofdm; |
| @@ -670,11 +669,6 @@ struct iwl_rxon_context { | |||
| 670 | bool enabled, is_40mhz; | 669 | bool enabled, is_40mhz; |
| 671 | u8 extension_chan_offset; | 670 | u8 extension_chan_offset; |
| 672 | } ht; | 671 | } ht; |
| 673 | |||
| 674 | u8 bssid[ETH_ALEN]; | ||
| 675 | bool preauth_bssid; | ||
| 676 | |||
| 677 | bool last_tx_rejected; | ||
| 678 | }; | 672 | }; |
| 679 | 673 | ||
| 680 | enum iwl_scan_type { | 674 | enum iwl_scan_type { |
| @@ -718,29 +712,44 @@ struct iwl_priv { | |||
| 718 | 712 | ||
| 719 | /*data shared among all the driver's layers */ | 713 | /*data shared among all the driver's layers */ |
| 720 | struct iwl_shared *shrd; | 714 | struct iwl_shared *shrd; |
| 715 | const struct iwl_fw *fw; | ||
| 716 | unsigned long status; | ||
| 717 | |||
| 718 | spinlock_t sta_lock; | ||
| 719 | struct mutex mutex; | ||
| 720 | |||
| 721 | unsigned long transport_queue_stop; | ||
| 722 | bool passive_no_rx; | ||
| 721 | 723 | ||
| 722 | /* ieee device used by generic ieee processing code */ | 724 | /* ieee device used by generic ieee processing code */ |
| 723 | struct ieee80211_hw *hw; | 725 | struct ieee80211_hw *hw; |
| 724 | struct ieee80211_channel *ieee_channels; | 726 | struct ieee80211_channel *ieee_channels; |
| 725 | struct ieee80211_rate *ieee_rates; | 727 | struct ieee80211_rate *ieee_rates; |
| 726 | struct kmem_cache *tx_cmd_pool; | 728 | |
| 729 | struct list_head calib_results; | ||
| 727 | 730 | ||
| 728 | struct workqueue_struct *workqueue; | 731 | struct workqueue_struct *workqueue; |
| 729 | 732 | ||
| 730 | enum ieee80211_band band; | 733 | enum ieee80211_band band; |
| 731 | 734 | ||
| 732 | void (*pre_rx_handler)(struct iwl_priv *priv, | 735 | void (*pre_rx_handler)(struct iwl_priv *priv, |
| 733 | struct iwl_rx_mem_buffer *rxb); | 736 | struct iwl_rx_cmd_buffer *rxb); |
| 734 | int (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, | 737 | int (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, |
| 735 | struct iwl_rx_mem_buffer *rxb, | 738 | struct iwl_rx_cmd_buffer *rxb, |
| 736 | struct iwl_device_cmd *cmd); | 739 | struct iwl_device_cmd *cmd); |
| 737 | 740 | ||
| 741 | struct iwl_notif_wait_data notif_wait; | ||
| 742 | |||
| 738 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; | 743 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; |
| 739 | 744 | ||
| 740 | /* spectrum measurement report caching */ | 745 | /* spectrum measurement report caching */ |
| 741 | struct iwl_spectrum_notification measure_report; | 746 | struct iwl_spectrum_notification measure_report; |
| 742 | u8 measurement_status; | 747 | u8 measurement_status; |
| 743 | 748 | ||
| 749 | #define IWL_OWNERSHIP_DRIVER 0 | ||
| 750 | #define IWL_OWNERSHIP_TM 1 | ||
| 751 | u8 ucode_owner; | ||
| 752 | |||
| 744 | /* ucode beacon time */ | 753 | /* ucode beacon time */ |
| 745 | u32 ucode_beacon_time; | 754 | u32 ucode_beacon_time; |
| 746 | int missed_beacon_threshold; | 755 | int missed_beacon_threshold; |
| @@ -766,6 +775,8 @@ struct iwl_priv { | |||
| 766 | struct iwl_channel_info *channel_info; /* channel info array */ | 775 | struct iwl_channel_info *channel_info; /* channel info array */ |
| 767 | u8 channel_count; /* # of channels */ | 776 | u8 channel_count; /* # of channels */ |
| 768 | 777 | ||
| 778 | u8 plcp_delta_threshold; | ||
| 779 | |||
| 769 | /* thermal calibration */ | 780 | /* thermal calibration */ |
| 770 | s32 temperature; /* Celsius */ | 781 | s32 temperature; /* Celsius */ |
| 771 | s32 last_temperature; | 782 | s32 last_temperature; |
| @@ -788,6 +799,8 @@ struct iwl_priv { | |||
| 788 | 799 | ||
| 789 | bool new_scan_threshold_behaviour; | 800 | bool new_scan_threshold_behaviour; |
| 790 | 801 | ||
| 802 | bool wowlan; | ||
| 803 | |||
| 791 | /* EEPROM MAC addresses */ | 804 | /* EEPROM MAC addresses */ |
| 792 | struct mac_address addresses[2]; | 805 | struct mac_address addresses[2]; |
| 793 | 806 | ||
| @@ -845,6 +858,7 @@ struct iwl_priv { | |||
| 845 | struct statistics_bt_activity bt_activity; | 858 | struct statistics_bt_activity bt_activity; |
| 846 | __le32 num_bt_kills, accum_num_bt_kills; | 859 | __le32 num_bt_kills, accum_num_bt_kills; |
| 847 | #endif | 860 | #endif |
| 861 | spinlock_t lock; | ||
| 848 | } statistics; | 862 | } statistics; |
| 849 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 863 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
| 850 | struct { | 864 | struct { |
| @@ -968,6 +982,7 @@ struct iwl_priv { | |||
| 968 | bool have_rekey_data; | 982 | bool have_rekey_data; |
| 969 | }; /*iwl_priv */ | 983 | }; /*iwl_priv */ |
| 970 | 984 | ||
| 985 | extern struct kmem_cache *iwl_tx_cmd_pool; | ||
| 971 | extern struct iwl_mod_params iwlagn_mod_params; | 986 | extern struct iwl_mod_params iwlagn_mod_params; |
| 972 | 987 | ||
| 973 | static inline struct iwl_rxon_context * | 988 | static inline struct iwl_rxon_context * |
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 96e62338cec0..06203d6a1d86 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h | |||
| @@ -41,130 +41,134 @@ static inline void trace_ ## name(proto) {} | |||
| 41 | static inline void trace_ ## name(proto) {} | 41 | static inline void trace_ ## name(proto) {} |
| 42 | #endif | 42 | #endif |
| 43 | 43 | ||
| 44 | #define PRIV_ENTRY __field(void *, priv) | 44 | #define DEV_ENTRY __string(dev, dev_name(dev)) |
| 45 | #define PRIV_ASSIGN __entry->priv = priv | 45 | #define DEV_ASSIGN __assign_str(dev, dev_name(dev)) |
| 46 | 46 | ||
| 47 | #undef TRACE_SYSTEM | 47 | #undef TRACE_SYSTEM |
| 48 | #define TRACE_SYSTEM iwlwifi_io | 48 | #define TRACE_SYSTEM iwlwifi_io |
| 49 | 49 | ||
| 50 | TRACE_EVENT(iwlwifi_dev_ioread32, | 50 | TRACE_EVENT(iwlwifi_dev_ioread32, |
| 51 | TP_PROTO(void *priv, u32 offs, u32 val), | 51 | TP_PROTO(const struct device *dev, u32 offs, u32 val), |
| 52 | TP_ARGS(priv, offs, val), | 52 | TP_ARGS(dev, offs, val), |
| 53 | TP_STRUCT__entry( | 53 | TP_STRUCT__entry( |
| 54 | PRIV_ENTRY | 54 | DEV_ENTRY |
| 55 | __field(u32, offs) | 55 | __field(u32, offs) |
| 56 | __field(u32, val) | 56 | __field(u32, val) |
| 57 | ), | 57 | ), |
| 58 | TP_fast_assign( | 58 | TP_fast_assign( |
| 59 | PRIV_ASSIGN; | 59 | DEV_ASSIGN; |
| 60 | __entry->offs = offs; | 60 | __entry->offs = offs; |
| 61 | __entry->val = val; | 61 | __entry->val = val; |
| 62 | ), | 62 | ), |
| 63 | TP_printk("[%p] read io[%#x] = %#x", __entry->priv, __entry->offs, __entry->val) | 63 | TP_printk("[%s] read io[%#x] = %#x", |
| 64 | __get_str(dev), __entry->offs, __entry->val) | ||
| 64 | ); | 65 | ); |
| 65 | 66 | ||
| 66 | TRACE_EVENT(iwlwifi_dev_iowrite8, | 67 | TRACE_EVENT(iwlwifi_dev_iowrite8, |
| 67 | TP_PROTO(void *priv, u32 offs, u8 val), | 68 | TP_PROTO(const struct device *dev, u32 offs, u8 val), |
| 68 | TP_ARGS(priv, offs, val), | 69 | TP_ARGS(dev, offs, val), |
| 69 | TP_STRUCT__entry( | 70 | TP_STRUCT__entry( |
| 70 | PRIV_ENTRY | 71 | DEV_ENTRY |
| 71 | __field(u32, offs) | 72 | __field(u32, offs) |
| 72 | __field(u8, val) | 73 | __field(u8, val) |
| 73 | ), | 74 | ), |
| 74 | TP_fast_assign( | 75 | TP_fast_assign( |
| 75 | PRIV_ASSIGN; | 76 | DEV_ASSIGN; |
| 76 | __entry->offs = offs; | 77 | __entry->offs = offs; |
| 77 | __entry->val = val; | 78 | __entry->val = val; |
| 78 | ), | 79 | ), |
| 79 | TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, __entry->offs, __entry->val) | 80 | TP_printk("[%s] write io[%#x] = %#x)", |
| 81 | __get_str(dev), __entry->offs, __entry->val) | ||
| 80 | ); | 82 | ); |
| 81 | 83 | ||
| 82 | TRACE_EVENT(iwlwifi_dev_iowrite32, | 84 | TRACE_EVENT(iwlwifi_dev_iowrite32, |
| 83 | TP_PROTO(void *priv, u32 offs, u32 val), | 85 | TP_PROTO(const struct device *dev, u32 offs, u32 val), |
| 84 | TP_ARGS(priv, offs, val), | 86 | TP_ARGS(dev, offs, val), |
| 85 | TP_STRUCT__entry( | 87 | TP_STRUCT__entry( |
| 86 | PRIV_ENTRY | 88 | DEV_ENTRY |
| 87 | __field(u32, offs) | 89 | __field(u32, offs) |
| 88 | __field(u32, val) | 90 | __field(u32, val) |
| 89 | ), | 91 | ), |
| 90 | TP_fast_assign( | 92 | TP_fast_assign( |
| 91 | PRIV_ASSIGN; | 93 | DEV_ASSIGN; |
| 92 | __entry->offs = offs; | 94 | __entry->offs = offs; |
| 93 | __entry->val = val; | 95 | __entry->val = val; |
| 94 | ), | 96 | ), |
| 95 | TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, __entry->offs, __entry->val) | 97 | TP_printk("[%s] write io[%#x] = %#x)", |
| 98 | __get_str(dev), __entry->offs, __entry->val) | ||
| 96 | ); | 99 | ); |
| 97 | 100 | ||
| 98 | TRACE_EVENT(iwlwifi_dev_irq, | 101 | TRACE_EVENT(iwlwifi_dev_irq, |
| 99 | TP_PROTO(void *priv), | 102 | TP_PROTO(const struct device *dev), |
| 100 | TP_ARGS(priv), | 103 | TP_ARGS(dev), |
| 101 | TP_STRUCT__entry( | 104 | TP_STRUCT__entry( |
| 102 | PRIV_ENTRY | 105 | DEV_ENTRY |
| 103 | ), | 106 | ), |
| 104 | TP_fast_assign( | 107 | TP_fast_assign( |
| 105 | PRIV_ASSIGN; | 108 | DEV_ASSIGN; |
| 106 | ), | 109 | ), |
| 107 | /* TP_printk("") doesn't compile */ | 110 | /* TP_printk("") doesn't compile */ |
| 108 | TP_printk("%d", 0) | 111 | TP_printk("%d", 0) |
| 109 | ); | 112 | ); |
| 110 | 113 | ||
| 111 | TRACE_EVENT(iwlwifi_dev_ict_read, | 114 | TRACE_EVENT(iwlwifi_dev_ict_read, |
| 112 | TP_PROTO(void *priv, u32 index, u32 value), | 115 | TP_PROTO(const struct device *dev, u32 index, u32 value), |
| 113 | TP_ARGS(priv, index, value), | 116 | TP_ARGS(dev, index, value), |
| 114 | TP_STRUCT__entry( | 117 | TP_STRUCT__entry( |
| 115 | PRIV_ENTRY | 118 | DEV_ENTRY |
| 116 | __field(u32, index) | 119 | __field(u32, index) |
| 117 | __field(u32, value) | 120 | __field(u32, value) |
| 118 | ), | 121 | ), |
| 119 | TP_fast_assign( | 122 | TP_fast_assign( |
| 120 | PRIV_ASSIGN; | 123 | DEV_ASSIGN; |
| 121 | __entry->index = index; | 124 | __entry->index = index; |
| 122 | __entry->value = value; | 125 | __entry->value = value; |
| 123 | ), | 126 | ), |
| 124 | TP_printk("read ict[%d] = %#.8x", __entry->index, __entry->value) | 127 | TP_printk("[%s] read ict[%d] = %#.8x", |
| 128 | __get_str(dev), __entry->index, __entry->value) | ||
| 125 | ); | 129 | ); |
| 126 | 130 | ||
| 127 | #undef TRACE_SYSTEM | 131 | #undef TRACE_SYSTEM |
| 128 | #define TRACE_SYSTEM iwlwifi_ucode | 132 | #define TRACE_SYSTEM iwlwifi_ucode |
| 129 | 133 | ||
| 130 | TRACE_EVENT(iwlwifi_dev_ucode_cont_event, | 134 | TRACE_EVENT(iwlwifi_dev_ucode_cont_event, |
| 131 | TP_PROTO(void *priv, u32 time, u32 data, u32 ev), | 135 | TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev), |
| 132 | TP_ARGS(priv, time, data, ev), | 136 | TP_ARGS(dev, time, data, ev), |
| 133 | TP_STRUCT__entry( | 137 | TP_STRUCT__entry( |
| 134 | PRIV_ENTRY | 138 | DEV_ENTRY |
| 135 | 139 | ||
| 136 | __field(u32, time) | 140 | __field(u32, time) |
| 137 | __field(u32, data) | 141 | __field(u32, data) |
| 138 | __field(u32, ev) | 142 | __field(u32, ev) |
| 139 | ), | 143 | ), |
| 140 | TP_fast_assign( | 144 | TP_fast_assign( |
| 141 | PRIV_ASSIGN; | 145 | DEV_ASSIGN; |
| 142 | __entry->time = time; | 146 | __entry->time = time; |
| 143 | __entry->data = data; | 147 | __entry->data = data; |
| 144 | __entry->ev = ev; | 148 | __entry->ev = ev; |
| 145 | ), | 149 | ), |
| 146 | TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u", | 150 | TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u", |
| 147 | __entry->priv, __entry->time, __entry->data, __entry->ev) | 151 | __get_str(dev), __entry->time, __entry->data, __entry->ev) |
| 148 | ); | 152 | ); |
| 149 | 153 | ||
| 150 | TRACE_EVENT(iwlwifi_dev_ucode_wrap_event, | 154 | TRACE_EVENT(iwlwifi_dev_ucode_wrap_event, |
| 151 | TP_PROTO(void *priv, u32 wraps, u32 n_entry, u32 p_entry), | 155 | TP_PROTO(const struct device *dev, u32 wraps, u32 n_entry, u32 p_entry), |
| 152 | TP_ARGS(priv, wraps, n_entry, p_entry), | 156 | TP_ARGS(dev, wraps, n_entry, p_entry), |
| 153 | TP_STRUCT__entry( | 157 | TP_STRUCT__entry( |
| 154 | PRIV_ENTRY | 158 | DEV_ENTRY |
| 155 | 159 | ||
| 156 | __field(u32, wraps) | 160 | __field(u32, wraps) |
| 157 | __field(u32, n_entry) | 161 | __field(u32, n_entry) |
| 158 | __field(u32, p_entry) | 162 | __field(u32, p_entry) |
| 159 | ), | 163 | ), |
| 160 | TP_fast_assign( | 164 | TP_fast_assign( |
| 161 | PRIV_ASSIGN; | 165 | DEV_ASSIGN; |
| 162 | __entry->wraps = wraps; | 166 | __entry->wraps = wraps; |
| 163 | __entry->n_entry = n_entry; | 167 | __entry->n_entry = n_entry; |
| 164 | __entry->p_entry = p_entry; | 168 | __entry->p_entry = p_entry; |
| 165 | ), | 169 | ), |
| 166 | TP_printk("[%p] wraps=#%02d n=0x%X p=0x%X", | 170 | TP_printk("[%s] wraps=#%02d n=0x%X p=0x%X", |
| 167 | __entry->priv, __entry->wraps, __entry->n_entry, | 171 | __get_str(dev), __entry->wraps, __entry->n_entry, |
| 168 | __entry->p_entry) | 172 | __entry->p_entry) |
| 169 | ); | 173 | ); |
| 170 | 174 | ||
| @@ -232,52 +236,52 @@ TRACE_EVENT(iwlwifi_dbg, | |||
| 232 | #define TRACE_SYSTEM iwlwifi | 236 | #define TRACE_SYSTEM iwlwifi |
| 233 | 237 | ||
| 234 | TRACE_EVENT(iwlwifi_dev_hcmd, | 238 | TRACE_EVENT(iwlwifi_dev_hcmd, |
| 235 | TP_PROTO(void *priv, u32 flags, | 239 | TP_PROTO(const struct device *dev, u32 flags, |
| 236 | const void *hcmd0, size_t len0, | 240 | const void *hcmd0, size_t len0, |
| 237 | const void *hcmd1, size_t len1, | 241 | const void *hcmd1, size_t len1, |
| 238 | const void *hcmd2, size_t len2), | 242 | const void *hcmd2, size_t len2), |
| 239 | TP_ARGS(priv, flags, hcmd0, len0, hcmd1, len1, hcmd2, len2), | 243 | TP_ARGS(dev, flags, hcmd0, len0, hcmd1, len1, hcmd2, len2), |
| 240 | TP_STRUCT__entry( | 244 | TP_STRUCT__entry( |
| 241 | PRIV_ENTRY | 245 | DEV_ENTRY |
| 242 | __dynamic_array(u8, hcmd0, len0) | 246 | __dynamic_array(u8, hcmd0, len0) |
| 243 | __dynamic_array(u8, hcmd1, len1) | 247 | __dynamic_array(u8, hcmd1, len1) |
| 244 | __dynamic_array(u8, hcmd2, len2) | 248 | __dynamic_array(u8, hcmd2, len2) |
| 245 | __field(u32, flags) | 249 | __field(u32, flags) |
| 246 | ), | 250 | ), |
| 247 | TP_fast_assign( | 251 | TP_fast_assign( |
| 248 | PRIV_ASSIGN; | 252 | DEV_ASSIGN; |
| 249 | memcpy(__get_dynamic_array(hcmd0), hcmd0, len0); | 253 | memcpy(__get_dynamic_array(hcmd0), hcmd0, len0); |
| 250 | memcpy(__get_dynamic_array(hcmd1), hcmd1, len1); | 254 | memcpy(__get_dynamic_array(hcmd1), hcmd1, len1); |
| 251 | memcpy(__get_dynamic_array(hcmd2), hcmd2, len2); | 255 | memcpy(__get_dynamic_array(hcmd2), hcmd2, len2); |
| 252 | __entry->flags = flags; | 256 | __entry->flags = flags; |
| 253 | ), | 257 | ), |
| 254 | TP_printk("[%p] hcmd %#.2x (%ssync)", | 258 | TP_printk("[%s] hcmd %#.2x (%ssync)", |
| 255 | __entry->priv, ((u8 *)__get_dynamic_array(hcmd0))[0], | 259 | __get_str(dev), ((u8 *)__get_dynamic_array(hcmd0))[0], |
| 256 | __entry->flags & CMD_ASYNC ? "a" : "") | 260 | __entry->flags & CMD_ASYNC ? "a" : "") |
| 257 | ); | 261 | ); |
| 258 | 262 | ||
| 259 | TRACE_EVENT(iwlwifi_dev_rx, | 263 | TRACE_EVENT(iwlwifi_dev_rx, |
| 260 | TP_PROTO(void *priv, void *rxbuf, size_t len), | 264 | TP_PROTO(const struct device *dev, void *rxbuf, size_t len), |
| 261 | TP_ARGS(priv, rxbuf, len), | 265 | TP_ARGS(dev, rxbuf, len), |
| 262 | TP_STRUCT__entry( | 266 | TP_STRUCT__entry( |
| 263 | PRIV_ENTRY | 267 | DEV_ENTRY |
| 264 | __dynamic_array(u8, rxbuf, len) | 268 | __dynamic_array(u8, rxbuf, len) |
| 265 | ), | 269 | ), |
| 266 | TP_fast_assign( | 270 | TP_fast_assign( |
| 267 | PRIV_ASSIGN; | 271 | DEV_ASSIGN; |
| 268 | memcpy(__get_dynamic_array(rxbuf), rxbuf, len); | 272 | memcpy(__get_dynamic_array(rxbuf), rxbuf, len); |
| 269 | ), | 273 | ), |
| 270 | TP_printk("[%p] RX cmd %#.2x", | 274 | TP_printk("[%s] RX cmd %#.2x", |
| 271 | __entry->priv, ((u8 *)__get_dynamic_array(rxbuf))[4]) | 275 | __get_str(dev), ((u8 *)__get_dynamic_array(rxbuf))[4]) |
| 272 | ); | 276 | ); |
| 273 | 277 | ||
| 274 | TRACE_EVENT(iwlwifi_dev_tx, | 278 | TRACE_EVENT(iwlwifi_dev_tx, |
| 275 | TP_PROTO(void *priv, void *tfd, size_t tfdlen, | 279 | TP_PROTO(const struct device *dev, void *tfd, size_t tfdlen, |
| 276 | void *buf0, size_t buf0_len, | 280 | void *buf0, size_t buf0_len, |
| 277 | void *buf1, size_t buf1_len), | 281 | void *buf1, size_t buf1_len), |
| 278 | TP_ARGS(priv, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), | 282 | TP_ARGS(dev, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), |
| 279 | TP_STRUCT__entry( | 283 | TP_STRUCT__entry( |
| 280 | PRIV_ENTRY | 284 | DEV_ENTRY |
| 281 | 285 | ||
| 282 | __field(size_t, framelen) | 286 | __field(size_t, framelen) |
| 283 | __dynamic_array(u8, tfd, tfdlen) | 287 | __dynamic_array(u8, tfd, tfdlen) |
| @@ -291,29 +295,28 @@ TRACE_EVENT(iwlwifi_dev_tx, | |||
| 291 | __dynamic_array(u8, buf1, buf1_len) | 295 | __dynamic_array(u8, buf1, buf1_len) |
| 292 | ), | 296 | ), |
| 293 | TP_fast_assign( | 297 | TP_fast_assign( |
| 294 | PRIV_ASSIGN; | 298 | DEV_ASSIGN; |
| 295 | __entry->framelen = buf0_len + buf1_len; | 299 | __entry->framelen = buf0_len + buf1_len; |
| 296 | memcpy(__get_dynamic_array(tfd), tfd, tfdlen); | 300 | memcpy(__get_dynamic_array(tfd), tfd, tfdlen); |
| 297 | memcpy(__get_dynamic_array(buf0), buf0, buf0_len); | 301 | memcpy(__get_dynamic_array(buf0), buf0, buf0_len); |
| 298 | memcpy(__get_dynamic_array(buf1), buf1, buf1_len); | 302 | memcpy(__get_dynamic_array(buf1), buf1, buf1_len); |
| 299 | ), | 303 | ), |
| 300 | TP_printk("[%p] TX %.2x (%zu bytes)", | 304 | TP_printk("[%s] TX %.2x (%zu bytes)", |
| 301 | __entry->priv, | 305 | __get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0], |
| 302 | ((u8 *)__get_dynamic_array(buf0))[0], | ||
| 303 | __entry->framelen) | 306 | __entry->framelen) |
| 304 | ); | 307 | ); |
| 305 | 308 | ||
| 306 | TRACE_EVENT(iwlwifi_dev_ucode_error, | 309 | TRACE_EVENT(iwlwifi_dev_ucode_error, |
| 307 | TP_PROTO(void *priv, u32 desc, u32 tsf_low, | 310 | TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low, |
| 308 | u32 data1, u32 data2, u32 line, u32 blink1, | 311 | u32 data1, u32 data2, u32 line, u32 blink1, |
| 309 | u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time, | 312 | u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time, |
| 310 | u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver, | 313 | u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver, |
| 311 | u32 brd_ver), | 314 | u32 brd_ver), |
| 312 | TP_ARGS(priv, desc, tsf_low, data1, data2, line, | 315 | TP_ARGS(dev, desc, tsf_low, data1, data2, line, |
| 313 | blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2, | 316 | blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2, |
| 314 | gp3, ucode_ver, hw_ver, brd_ver), | 317 | gp3, ucode_ver, hw_ver, brd_ver), |
| 315 | TP_STRUCT__entry( | 318 | TP_STRUCT__entry( |
| 316 | PRIV_ENTRY | 319 | DEV_ENTRY |
| 317 | __field(u32, desc) | 320 | __field(u32, desc) |
| 318 | __field(u32, tsf_low) | 321 | __field(u32, tsf_low) |
| 319 | __field(u32, data1) | 322 | __field(u32, data1) |
| @@ -332,7 +335,7 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, | |||
| 332 | __field(u32, brd_ver) | 335 | __field(u32, brd_ver) |
| 333 | ), | 336 | ), |
| 334 | TP_fast_assign( | 337 | TP_fast_assign( |
| 335 | PRIV_ASSIGN; | 338 | DEV_ASSIGN; |
| 336 | __entry->desc = desc; | 339 | __entry->desc = desc; |
| 337 | __entry->tsf_low = tsf_low; | 340 | __entry->tsf_low = tsf_low; |
| 338 | __entry->data1 = data1; | 341 | __entry->data1 = data1; |
| @@ -350,11 +353,11 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, | |||
| 350 | __entry->hw_ver = hw_ver; | 353 | __entry->hw_ver = hw_ver; |
| 351 | __entry->brd_ver = brd_ver; | 354 | __entry->brd_ver = brd_ver; |
| 352 | ), | 355 | ), |
| 353 | TP_printk("[%p] #%02d %010u data 0x%08X 0x%08X line %u, " | 356 | TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, " |
| 354 | "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X " | 357 | "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X " |
| 355 | "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X " | 358 | "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X " |
| 356 | "hw 0x%08X brd 0x%08X", | 359 | "hw 0x%08X brd 0x%08X", |
| 357 | __entry->priv, __entry->desc, __entry->tsf_low, | 360 | __get_str(dev), __entry->desc, __entry->tsf_low, |
| 358 | __entry->data1, | 361 | __entry->data1, |
| 359 | __entry->data2, __entry->line, __entry->blink1, | 362 | __entry->data2, __entry->line, __entry->blink1, |
| 360 | __entry->blink2, __entry->ilink1, __entry->ilink2, | 363 | __entry->blink2, __entry->ilink1, __entry->ilink2, |
| @@ -364,23 +367,23 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, | |||
| 364 | ); | 367 | ); |
| 365 | 368 | ||
| 366 | TRACE_EVENT(iwlwifi_dev_ucode_event, | 369 | TRACE_EVENT(iwlwifi_dev_ucode_event, |
| 367 | TP_PROTO(void *priv, u32 time, u32 data, u32 ev), | 370 | TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev), |
| 368 | TP_ARGS(priv, time, data, ev), | 371 | TP_ARGS(dev, time, data, ev), |
| 369 | TP_STRUCT__entry( | 372 | TP_STRUCT__entry( |
| 370 | PRIV_ENTRY | 373 | DEV_ENTRY |
| 371 | 374 | ||
| 372 | __field(u32, time) | 375 | __field(u32, time) |
| 373 | __field(u32, data) | 376 | __field(u32, data) |
| 374 | __field(u32, ev) | 377 | __field(u32, ev) |
| 375 | ), | 378 | ), |
| 376 | TP_fast_assign( | 379 | TP_fast_assign( |
| 377 | PRIV_ASSIGN; | 380 | DEV_ASSIGN; |
| 378 | __entry->time = time; | 381 | __entry->time = time; |
| 379 | __entry->data = data; | 382 | __entry->data = data; |
| 380 | __entry->ev = ev; | 383 | __entry->ev = ev; |
| 381 | ), | 384 | ), |
| 382 | TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u", | 385 | TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u", |
| 383 | __entry->priv, __entry->time, __entry->data, __entry->ev) | 386 | __get_str(dev), __entry->time, __entry->data, __entry->ev) |
| 384 | ); | 387 | ); |
| 385 | #endif /* __IWLWIFI_DEVICE_TRACE */ | 388 | #endif /* __IWLWIFI_DEVICE_TRACE */ |
| 386 | 389 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 8ff52568cf6e..29a3ae48df6d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
| @@ -61,33 +61,686 @@ | |||
| 61 | * | 61 | * |
| 62 | *****************************************************************************/ | 62 | *****************************************************************************/ |
| 63 | #include <linux/completion.h> | 63 | #include <linux/completion.h> |
| 64 | #include <linux/dma-mapping.h> | ||
| 65 | #include <linux/firmware.h> | ||
| 66 | #include <linux/module.h> | ||
| 64 | 67 | ||
| 65 | #include "iwl-drv.h" | 68 | #include "iwl-drv.h" |
| 66 | #include "iwl-trans.h" | 69 | #include "iwl-trans.h" |
| 67 | #include "iwl-wifi.h" | 70 | #include "iwl-shared.h" |
| 68 | #include "iwl-op-mode.h" | 71 | #include "iwl-op-mode.h" |
| 69 | 72 | ||
| 73 | /* private includes */ | ||
| 74 | #include "iwl-fw-file.h" | ||
| 75 | |||
| 76 | /** | ||
| 77 | * struct iwl_drv - drv common data | ||
| 78 | * @fw: the iwl_fw structure | ||
| 79 | * @shrd: pointer to common shared structure | ||
| 80 | * @op_mode: the running op_mode | ||
| 81 | * @fw_index: firmware revision to try loading | ||
| 82 | * @firmware_name: composite filename of ucode file to load | ||
| 83 | * @request_firmware_complete: the firmware has been obtained from user space | ||
| 84 | */ | ||
| 85 | struct iwl_drv { | ||
| 86 | struct iwl_fw fw; | ||
| 87 | |||
| 88 | struct iwl_shared *shrd; | ||
| 89 | struct iwl_op_mode *op_mode; | ||
| 90 | |||
| 91 | int fw_index; /* firmware we're trying to load */ | ||
| 92 | char firmware_name[25]; /* name of firmware file to load */ | ||
| 93 | |||
| 94 | struct completion request_firmware_complete; | ||
| 95 | }; | ||
| 96 | |||
| 97 | |||
| 98 | |||
| 99 | static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc) | ||
| 100 | { | ||
| 101 | if (desc->v_addr) | ||
| 102 | dma_free_coherent(trans(drv)->dev, desc->len, | ||
| 103 | desc->v_addr, desc->p_addr); | ||
| 104 | desc->v_addr = NULL; | ||
| 105 | desc->len = 0; | ||
| 106 | } | ||
| 107 | |||
| 108 | static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img) | ||
| 109 | { | ||
| 110 | iwl_free_fw_desc(drv, &img->code); | ||
| 111 | iwl_free_fw_desc(drv, &img->data); | ||
| 112 | } | ||
| 113 | |||
| 114 | static void iwl_dealloc_ucode(struct iwl_drv *drv) | ||
| 115 | { | ||
| 116 | iwl_free_fw_img(drv, &drv->fw.ucode_rt); | ||
| 117 | iwl_free_fw_img(drv, &drv->fw.ucode_init); | ||
| 118 | iwl_free_fw_img(drv, &drv->fw.ucode_wowlan); | ||
| 119 | } | ||
| 120 | |||
| 121 | static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc, | ||
| 122 | const void *data, size_t len) | ||
| 123 | { | ||
| 124 | if (!len) { | ||
| 125 | desc->v_addr = NULL; | ||
| 126 | return -EINVAL; | ||
| 127 | } | ||
| 128 | |||
| 129 | desc->v_addr = dma_alloc_coherent(trans(drv)->dev, len, | ||
| 130 | &desc->p_addr, GFP_KERNEL); | ||
| 131 | if (!desc->v_addr) | ||
| 132 | return -ENOMEM; | ||
| 133 | |||
| 134 | desc->len = len; | ||
| 135 | memcpy(desc->v_addr, data, len); | ||
| 136 | return 0; | ||
| 137 | } | ||
| 138 | |||
| 139 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); | ||
| 140 | |||
| 141 | #define UCODE_EXPERIMENTAL_INDEX 100 | ||
| 142 | #define UCODE_EXPERIMENTAL_TAG "exp" | ||
| 143 | |||
| 144 | static int iwl_request_firmware(struct iwl_drv *drv, bool first) | ||
| 145 | { | ||
| 146 | const struct iwl_cfg *cfg = cfg(drv); | ||
| 147 | const char *name_pre = cfg->fw_name_pre; | ||
| 148 | char tag[8]; | ||
| 149 | |||
| 150 | if (first) { | ||
| 151 | #ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE | ||
| 152 | drv->fw_index = UCODE_EXPERIMENTAL_INDEX; | ||
| 153 | strcpy(tag, UCODE_EXPERIMENTAL_TAG); | ||
| 154 | } else if (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) { | ||
| 155 | #endif | ||
| 156 | drv->fw_index = cfg->ucode_api_max; | ||
| 157 | sprintf(tag, "%d", drv->fw_index); | ||
| 158 | } else { | ||
| 159 | drv->fw_index--; | ||
| 160 | sprintf(tag, "%d", drv->fw_index); | ||
| 161 | } | ||
| 162 | |||
| 163 | if (drv->fw_index < cfg->ucode_api_min) { | ||
| 164 | IWL_ERR(drv, "no suitable firmware found!\n"); | ||
| 165 | return -ENOENT; | ||
| 166 | } | ||
| 167 | |||
| 168 | sprintf(drv->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); | ||
| 169 | |||
| 170 | IWL_DEBUG_INFO(drv, "attempting to load firmware %s'%s'\n", | ||
| 171 | (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) | ||
| 172 | ? "EXPERIMENTAL " : "", | ||
| 173 | drv->firmware_name); | ||
| 174 | |||
| 175 | return request_firmware_nowait(THIS_MODULE, 1, drv->firmware_name, | ||
| 176 | trans(drv)->dev, | ||
| 177 | GFP_KERNEL, drv, iwl_ucode_callback); | ||
| 178 | } | ||
| 179 | |||
| 180 | struct iwlagn_firmware_pieces { | ||
| 181 | const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data; | ||
| 182 | size_t inst_size, data_size, init_size, init_data_size, | ||
| 183 | wowlan_inst_size, wowlan_data_size; | ||
| 184 | |||
| 185 | u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; | ||
| 186 | u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; | ||
| 187 | }; | ||
| 188 | |||
| 189 | static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, | ||
| 190 | const struct firmware *ucode_raw, | ||
| 191 | struct iwlagn_firmware_pieces *pieces) | ||
| 192 | { | ||
| 193 | struct iwl_ucode_header *ucode = (void *)ucode_raw->data; | ||
| 194 | u32 api_ver, hdr_size, build; | ||
| 195 | char buildstr[25]; | ||
| 196 | const u8 *src; | ||
| 197 | |||
| 198 | drv->fw.ucode_ver = le32_to_cpu(ucode->ver); | ||
| 199 | api_ver = IWL_UCODE_API(drv->fw.ucode_ver); | ||
| 200 | |||
| 201 | switch (api_ver) { | ||
| 202 | default: | ||
| 203 | hdr_size = 28; | ||
| 204 | if (ucode_raw->size < hdr_size) { | ||
| 205 | IWL_ERR(drv, "File size too small!\n"); | ||
| 206 | return -EINVAL; | ||
| 207 | } | ||
| 208 | build = le32_to_cpu(ucode->u.v2.build); | ||
| 209 | pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); | ||
| 210 | pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); | ||
| 211 | pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); | ||
| 212 | pieces->init_data_size = | ||
| 213 | le32_to_cpu(ucode->u.v2.init_data_size); | ||
| 214 | src = ucode->u.v2.data; | ||
| 215 | break; | ||
| 216 | case 0: | ||
| 217 | case 1: | ||
| 218 | case 2: | ||
| 219 | hdr_size = 24; | ||
| 220 | if (ucode_raw->size < hdr_size) { | ||
| 221 | IWL_ERR(drv, "File size too small!\n"); | ||
| 222 | return -EINVAL; | ||
| 223 | } | ||
| 224 | build = 0; | ||
| 225 | pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size); | ||
| 226 | pieces->data_size = le32_to_cpu(ucode->u.v1.data_size); | ||
| 227 | pieces->init_size = le32_to_cpu(ucode->u.v1.init_size); | ||
| 228 | pieces->init_data_size = | ||
| 229 | le32_to_cpu(ucode->u.v1.init_data_size); | ||
| 230 | src = ucode->u.v1.data; | ||
| 231 | break; | ||
| 232 | } | ||
| 233 | |||
| 234 | if (build) | ||
| 235 | sprintf(buildstr, " build %u%s", build, | ||
| 236 | (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) | ||
| 237 | ? " (EXP)" : ""); | ||
| 238 | else | ||
| 239 | buildstr[0] = '\0'; | ||
| 240 | |||
| 241 | snprintf(drv->fw.fw_version, | ||
| 242 | sizeof(drv->fw.fw_version), | ||
| 243 | "%u.%u.%u.%u%s", | ||
| 244 | IWL_UCODE_MAJOR(drv->fw.ucode_ver), | ||
| 245 | IWL_UCODE_MINOR(drv->fw.ucode_ver), | ||
| 246 | IWL_UCODE_API(drv->fw.ucode_ver), | ||
| 247 | IWL_UCODE_SERIAL(drv->fw.ucode_ver), | ||
| 248 | buildstr); | ||
| 249 | |||
| 250 | /* Verify size of file vs. image size info in file's header */ | ||
| 251 | if (ucode_raw->size != hdr_size + pieces->inst_size + | ||
| 252 | pieces->data_size + pieces->init_size + | ||
| 253 | pieces->init_data_size) { | ||
| 254 | |||
| 255 | IWL_ERR(drv, | ||
| 256 | "uCode file size %d does not match expected size\n", | ||
| 257 | (int)ucode_raw->size); | ||
| 258 | return -EINVAL; | ||
| 259 | } | ||
| 260 | |||
| 261 | pieces->inst = src; | ||
| 262 | src += pieces->inst_size; | ||
| 263 | pieces->data = src; | ||
| 264 | src += pieces->data_size; | ||
| 265 | pieces->init = src; | ||
| 266 | src += pieces->init_size; | ||
| 267 | pieces->init_data = src; | ||
| 268 | src += pieces->init_data_size; | ||
| 269 | |||
| 270 | return 0; | ||
| 271 | } | ||
| 272 | |||
| 273 | static int iwl_parse_tlv_firmware(struct iwl_drv *drv, | ||
| 274 | const struct firmware *ucode_raw, | ||
| 275 | struct iwlagn_firmware_pieces *pieces, | ||
| 276 | struct iwl_ucode_capabilities *capa) | ||
| 277 | { | ||
| 278 | struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data; | ||
| 279 | struct iwl_ucode_tlv *tlv; | ||
| 280 | size_t len = ucode_raw->size; | ||
| 281 | const u8 *data; | ||
| 282 | int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative; | ||
| 283 | int tmp; | ||
| 284 | u64 alternatives; | ||
| 285 | u32 tlv_len; | ||
| 286 | enum iwl_ucode_tlv_type tlv_type; | ||
| 287 | const u8 *tlv_data; | ||
| 288 | char buildstr[25]; | ||
| 289 | u32 build; | ||
| 290 | |||
| 291 | if (len < sizeof(*ucode)) { | ||
| 292 | IWL_ERR(drv, "uCode has invalid length: %zd\n", len); | ||
| 293 | return -EINVAL; | ||
| 294 | } | ||
| 295 | |||
| 296 | if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { | ||
| 297 | IWL_ERR(drv, "invalid uCode magic: 0X%x\n", | ||
| 298 | le32_to_cpu(ucode->magic)); | ||
| 299 | return -EINVAL; | ||
| 300 | } | ||
| 301 | |||
| 302 | /* | ||
| 303 | * Check which alternatives are present, and "downgrade" | ||
| 304 | * when the chosen alternative is not present, warning | ||
| 305 | * the user when that happens. Some files may not have | ||
| 306 | * any alternatives, so don't warn in that case. | ||
| 307 | */ | ||
| 308 | alternatives = le64_to_cpu(ucode->alternatives); | ||
| 309 | tmp = wanted_alternative; | ||
| 310 | if (wanted_alternative > 63) | ||
| 311 | wanted_alternative = 63; | ||
| 312 | while (wanted_alternative && !(alternatives & BIT(wanted_alternative))) | ||
| 313 | wanted_alternative--; | ||
| 314 | if (wanted_alternative && wanted_alternative != tmp) | ||
| 315 | IWL_WARN(drv, | ||
| 316 | "uCode alternative %d not available, choosing %d\n", | ||
| 317 | tmp, wanted_alternative); | ||
| 318 | |||
| 319 | drv->fw.ucode_ver = le32_to_cpu(ucode->ver); | ||
| 320 | build = le32_to_cpu(ucode->build); | ||
| 321 | |||
| 322 | if (build) | ||
| 323 | sprintf(buildstr, " build %u%s", build, | ||
| 324 | (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) | ||
| 325 | ? " (EXP)" : ""); | ||
| 326 | else | ||
| 327 | buildstr[0] = '\0'; | ||
| 328 | |||
| 329 | snprintf(drv->fw.fw_version, | ||
| 330 | sizeof(drv->fw.fw_version), | ||
| 331 | "%u.%u.%u.%u%s", | ||
| 332 | IWL_UCODE_MAJOR(drv->fw.ucode_ver), | ||
| 333 | IWL_UCODE_MINOR(drv->fw.ucode_ver), | ||
| 334 | IWL_UCODE_API(drv->fw.ucode_ver), | ||
| 335 | IWL_UCODE_SERIAL(drv->fw.ucode_ver), | ||
| 336 | buildstr); | ||
| 337 | |||
| 338 | data = ucode->data; | ||
| 339 | |||
| 340 | len -= sizeof(*ucode); | ||
| 341 | |||
| 342 | while (len >= sizeof(*tlv)) { | ||
| 343 | u16 tlv_alt; | ||
| 344 | |||
| 345 | len -= sizeof(*tlv); | ||
| 346 | tlv = (void *)data; | ||
| 347 | |||
| 348 | tlv_len = le32_to_cpu(tlv->length); | ||
| 349 | tlv_type = le16_to_cpu(tlv->type); | ||
| 350 | tlv_alt = le16_to_cpu(tlv->alternative); | ||
| 351 | tlv_data = tlv->data; | ||
| 352 | |||
| 353 | if (len < tlv_len) { | ||
| 354 | IWL_ERR(drv, "invalid TLV len: %zd/%u\n", | ||
| 355 | len, tlv_len); | ||
| 356 | return -EINVAL; | ||
| 357 | } | ||
| 358 | len -= ALIGN(tlv_len, 4); | ||
| 359 | data += sizeof(*tlv) + ALIGN(tlv_len, 4); | ||
| 360 | |||
| 361 | /* | ||
| 362 | * Alternative 0 is always valid. | ||
| 363 | * | ||
| 364 | * Skip alternative TLVs that are not selected. | ||
| 365 | */ | ||
| 366 | if (tlv_alt != 0 && tlv_alt != wanted_alternative) | ||
| 367 | continue; | ||
| 368 | |||
| 369 | switch (tlv_type) { | ||
| 370 | case IWL_UCODE_TLV_INST: | ||
| 371 | pieces->inst = tlv_data; | ||
| 372 | pieces->inst_size = tlv_len; | ||
| 373 | break; | ||
| 374 | case IWL_UCODE_TLV_DATA: | ||
| 375 | pieces->data = tlv_data; | ||
| 376 | pieces->data_size = tlv_len; | ||
| 377 | break; | ||
| 378 | case IWL_UCODE_TLV_INIT: | ||
| 379 | pieces->init = tlv_data; | ||
| 380 | pieces->init_size = tlv_len; | ||
| 381 | break; | ||
| 382 | case IWL_UCODE_TLV_INIT_DATA: | ||
| 383 | pieces->init_data = tlv_data; | ||
| 384 | pieces->init_data_size = tlv_len; | ||
| 385 | break; | ||
| 386 | case IWL_UCODE_TLV_BOOT: | ||
| 387 | IWL_ERR(drv, "Found unexpected BOOT ucode\n"); | ||
| 388 | break; | ||
| 389 | case IWL_UCODE_TLV_PROBE_MAX_LEN: | ||
| 390 | if (tlv_len != sizeof(u32)) | ||
| 391 | goto invalid_tlv_len; | ||
| 392 | capa->max_probe_length = | ||
| 393 | le32_to_cpup((__le32 *)tlv_data); | ||
| 394 | break; | ||
| 395 | case IWL_UCODE_TLV_PAN: | ||
| 396 | if (tlv_len) | ||
| 397 | goto invalid_tlv_len; | ||
| 398 | capa->flags |= IWL_UCODE_TLV_FLAGS_PAN; | ||
| 399 | break; | ||
| 400 | case IWL_UCODE_TLV_FLAGS: | ||
| 401 | /* must be at least one u32 */ | ||
| 402 | if (tlv_len < sizeof(u32)) | ||
| 403 | goto invalid_tlv_len; | ||
| 404 | /* and a proper number of u32s */ | ||
| 405 | if (tlv_len % sizeof(u32)) | ||
| 406 | goto invalid_tlv_len; | ||
| 407 | /* | ||
| 408 | * This driver only reads the first u32 as | ||
| 409 | * right now no more features are defined, | ||
| 410 | * if that changes then either the driver | ||
| 411 | * will not work with the new firmware, or | ||
| 412 | * it'll not take advantage of new features. | ||
| 413 | */ | ||
| 414 | capa->flags = le32_to_cpup((__le32 *)tlv_data); | ||
| 415 | break; | ||
| 416 | case IWL_UCODE_TLV_INIT_EVTLOG_PTR: | ||
| 417 | if (tlv_len != sizeof(u32)) | ||
| 418 | goto invalid_tlv_len; | ||
| 419 | pieces->init_evtlog_ptr = | ||
| 420 | le32_to_cpup((__le32 *)tlv_data); | ||
| 421 | break; | ||
| 422 | case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: | ||
| 423 | if (tlv_len != sizeof(u32)) | ||
| 424 | goto invalid_tlv_len; | ||
| 425 | pieces->init_evtlog_size = | ||
| 426 | le32_to_cpup((__le32 *)tlv_data); | ||
| 427 | break; | ||
| 428 | case IWL_UCODE_TLV_INIT_ERRLOG_PTR: | ||
| 429 | if (tlv_len != sizeof(u32)) | ||
| 430 | goto invalid_tlv_len; | ||
| 431 | pieces->init_errlog_ptr = | ||
| 432 | le32_to_cpup((__le32 *)tlv_data); | ||
| 433 | break; | ||
| 434 | case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: | ||
| 435 | if (tlv_len != sizeof(u32)) | ||
| 436 | goto invalid_tlv_len; | ||
| 437 | pieces->inst_evtlog_ptr = | ||
| 438 | le32_to_cpup((__le32 *)tlv_data); | ||
| 439 | break; | ||
| 440 | case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: | ||
| 441 | if (tlv_len != sizeof(u32)) | ||
| 442 | goto invalid_tlv_len; | ||
| 443 | pieces->inst_evtlog_size = | ||
| 444 | le32_to_cpup((__le32 *)tlv_data); | ||
| 445 | break; | ||
| 446 | case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: | ||
| 447 | if (tlv_len != sizeof(u32)) | ||
| 448 | goto invalid_tlv_len; | ||
| 449 | pieces->inst_errlog_ptr = | ||
| 450 | le32_to_cpup((__le32 *)tlv_data); | ||
| 451 | break; | ||
| 452 | case IWL_UCODE_TLV_ENHANCE_SENS_TBL: | ||
| 453 | if (tlv_len) | ||
| 454 | goto invalid_tlv_len; | ||
| 455 | drv->fw.enhance_sensitivity_table = true; | ||
| 456 | break; | ||
| 457 | case IWL_UCODE_TLV_WOWLAN_INST: | ||
| 458 | pieces->wowlan_inst = tlv_data; | ||
| 459 | pieces->wowlan_inst_size = tlv_len; | ||
| 460 | break; | ||
| 461 | case IWL_UCODE_TLV_WOWLAN_DATA: | ||
| 462 | pieces->wowlan_data = tlv_data; | ||
| 463 | pieces->wowlan_data_size = tlv_len; | ||
| 464 | break; | ||
| 465 | case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: | ||
| 466 | if (tlv_len != sizeof(u32)) | ||
| 467 | goto invalid_tlv_len; | ||
| 468 | capa->standard_phy_calibration_size = | ||
| 469 | le32_to_cpup((__le32 *)tlv_data); | ||
| 470 | break; | ||
| 471 | default: | ||
| 472 | IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); | ||
| 473 | break; | ||
| 474 | } | ||
| 475 | } | ||
| 476 | |||
| 477 | if (len) { | ||
| 478 | IWL_ERR(drv, "invalid TLV after parsing: %zd\n", len); | ||
| 479 | iwl_print_hex_dump(drv, IWL_DL_FW, (u8 *)data, len); | ||
| 480 | return -EINVAL; | ||
| 481 | } | ||
| 482 | |||
| 483 | return 0; | ||
| 484 | |||
| 485 | invalid_tlv_len: | ||
| 486 | IWL_ERR(drv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); | ||
| 487 | iwl_print_hex_dump(drv, IWL_DL_FW, tlv_data, tlv_len); | ||
| 488 | |||
| 489 | return -EINVAL; | ||
| 490 | } | ||
| 491 | |||
| 492 | /** | ||
| 493 | * iwl_ucode_callback - callback when firmware was loaded | ||
| 494 | * | ||
| 495 | * If loaded successfully, copies the firmware into buffers | ||
| 496 | * for the card to fetch (via DMA). | ||
| 497 | */ | ||
| 498 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | ||
| 499 | { | ||
| 500 | struct iwl_drv *drv = context; | ||
| 501 | const struct iwl_cfg *cfg = cfg(drv); | ||
| 502 | struct iwl_fw *fw = &drv->fw; | ||
| 503 | struct iwl_ucode_header *ucode; | ||
| 504 | int err; | ||
| 505 | struct iwlagn_firmware_pieces pieces; | ||
| 506 | const unsigned int api_max = cfg->ucode_api_max; | ||
| 507 | unsigned int api_ok = cfg->ucode_api_ok; | ||
| 508 | const unsigned int api_min = cfg->ucode_api_min; | ||
| 509 | u32 api_ver; | ||
| 510 | |||
| 511 | fw->ucode_capa.max_probe_length = 200; | ||
| 512 | fw->ucode_capa.standard_phy_calibration_size = | ||
| 513 | IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE; | ||
| 514 | |||
| 515 | if (!api_ok) | ||
| 516 | api_ok = api_max; | ||
| 517 | |||
| 518 | memset(&pieces, 0, sizeof(pieces)); | ||
| 519 | |||
| 520 | if (!ucode_raw) { | ||
| 521 | if (drv->fw_index <= api_ok) | ||
| 522 | IWL_ERR(drv, | ||
| 523 | "request for firmware file '%s' failed.\n", | ||
| 524 | drv->firmware_name); | ||
| 525 | goto try_again; | ||
| 526 | } | ||
| 527 | |||
| 528 | IWL_DEBUG_INFO(drv, "Loaded firmware file '%s' (%zd bytes).\n", | ||
| 529 | drv->firmware_name, ucode_raw->size); | ||
| 530 | |||
| 531 | /* Make sure that we got at least the API version number */ | ||
| 532 | if (ucode_raw->size < 4) { | ||
| 533 | IWL_ERR(drv, "File size way too small!\n"); | ||
| 534 | goto try_again; | ||
| 535 | } | ||
| 536 | |||
| 537 | /* Data from ucode file: header followed by uCode images */ | ||
| 538 | ucode = (struct iwl_ucode_header *)ucode_raw->data; | ||
| 539 | |||
| 540 | if (ucode->ver) | ||
| 541 | err = iwl_parse_v1_v2_firmware(drv, ucode_raw, &pieces); | ||
| 542 | else | ||
| 543 | err = iwl_parse_tlv_firmware(drv, ucode_raw, &pieces, | ||
| 544 | &fw->ucode_capa); | ||
| 545 | |||
| 546 | if (err) | ||
| 547 | goto try_again; | ||
| 548 | |||
| 549 | api_ver = IWL_UCODE_API(drv->fw.ucode_ver); | ||
| 550 | |||
| 551 | /* | ||
| 552 | * api_ver should match the api version forming part of the | ||
| 553 | * firmware filename ... but we don't check for that and only rely | ||
| 554 | * on the API version read from firmware header from here on forward | ||
| 555 | */ | ||
| 556 | /* no api version check required for experimental uCode */ | ||
| 557 | if (drv->fw_index != UCODE_EXPERIMENTAL_INDEX) { | ||
| 558 | if (api_ver < api_min || api_ver > api_max) { | ||
| 559 | IWL_ERR(drv, | ||
| 560 | "Driver unable to support your firmware API. " | ||
| 561 | "Driver supports v%u, firmware is v%u.\n", | ||
| 562 | api_max, api_ver); | ||
| 563 | goto try_again; | ||
| 564 | } | ||
| 565 | |||
| 566 | if (api_ver < api_ok) { | ||
| 567 | if (api_ok != api_max) | ||
| 568 | IWL_ERR(drv, "Firmware has old API version, " | ||
| 569 | "expected v%u through v%u, got v%u.\n", | ||
| 570 | api_ok, api_max, api_ver); | ||
| 571 | else | ||
| 572 | IWL_ERR(drv, "Firmware has old API version, " | ||
| 573 | "expected v%u, got v%u.\n", | ||
| 574 | api_max, api_ver); | ||
| 575 | IWL_ERR(drv, "New firmware can be obtained from " | ||
| 576 | "http://www.intellinuxwireless.org/.\n"); | ||
| 577 | } | ||
| 578 | } | ||
| 579 | |||
| 580 | IWL_INFO(drv, "loaded firmware version %s", drv->fw.fw_version); | ||
| 581 | |||
| 582 | /* | ||
| 583 | * For any of the failures below (before allocating pci memory) | ||
| 584 | * we will try to load a version with a smaller API -- maybe the | ||
| 585 | * user just got a corrupted version of the latest API. | ||
| 586 | */ | ||
| 587 | |||
| 588 | IWL_DEBUG_INFO(drv, "f/w package hdr ucode version raw = 0x%x\n", | ||
| 589 | drv->fw.ucode_ver); | ||
| 590 | IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n", | ||
| 591 | pieces.inst_size); | ||
| 592 | IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n", | ||
| 593 | pieces.data_size); | ||
| 594 | IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n", | ||
| 595 | pieces.init_size); | ||
| 596 | IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n", | ||
| 597 | pieces.init_data_size); | ||
| 598 | |||
| 599 | /* Verify that uCode images will fit in card's SRAM */ | ||
| 600 | if (pieces.inst_size > cfg->max_inst_size) { | ||
| 601 | IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n", | ||
| 602 | pieces.inst_size); | ||
| 603 | goto try_again; | ||
| 604 | } | ||
| 605 | |||
| 606 | if (pieces.data_size > cfg->max_data_size) { | ||
| 607 | IWL_ERR(drv, "uCode data len %Zd too large to fit in\n", | ||
| 608 | pieces.data_size); | ||
| 609 | goto try_again; | ||
| 610 | } | ||
| 611 | |||
| 612 | if (pieces.init_size > cfg->max_inst_size) { | ||
| 613 | IWL_ERR(drv, "uCode init instr len %Zd too large to fit in\n", | ||
| 614 | pieces.init_size); | ||
| 615 | goto try_again; | ||
| 616 | } | ||
| 617 | |||
| 618 | if (pieces.init_data_size > cfg->max_data_size) { | ||
| 619 | IWL_ERR(drv, "uCode init data len %Zd too large to fit in\n", | ||
| 620 | pieces.init_data_size); | ||
| 621 | goto try_again; | ||
| 622 | } | ||
| 623 | |||
| 624 | /* Allocate ucode buffers for card's bus-master loading ... */ | ||
| 625 | |||
| 626 | /* Runtime instructions and 2 copies of data: | ||
| 627 | * 1) unmodified from disk | ||
| 628 | * 2) backup cache for save/restore during power-downs */ | ||
| 629 | if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_rt.code, | ||
| 630 | pieces.inst, pieces.inst_size)) | ||
| 631 | goto err_pci_alloc; | ||
| 632 | if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_rt.data, | ||
| 633 | pieces.data, pieces.data_size)) | ||
| 634 | goto err_pci_alloc; | ||
| 635 | |||
| 636 | /* Initialization instructions and data */ | ||
| 637 | if (pieces.init_size && pieces.init_data_size) { | ||
| 638 | if (iwl_alloc_fw_desc(drv, | ||
| 639 | &drv->fw.ucode_init.code, | ||
| 640 | pieces.init, pieces.init_size)) | ||
| 641 | goto err_pci_alloc; | ||
| 642 | if (iwl_alloc_fw_desc(drv, | ||
| 643 | &drv->fw.ucode_init.data, | ||
| 644 | pieces.init_data, pieces.init_data_size)) | ||
| 645 | goto err_pci_alloc; | ||
| 646 | } | ||
| 647 | |||
| 648 | /* WoWLAN instructions and data */ | ||
| 649 | if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { | ||
| 650 | if (iwl_alloc_fw_desc(drv, | ||
| 651 | &drv->fw.ucode_wowlan.code, | ||
| 652 | pieces.wowlan_inst, | ||
| 653 | pieces.wowlan_inst_size)) | ||
| 654 | goto err_pci_alloc; | ||
| 655 | if (iwl_alloc_fw_desc(drv, | ||
| 656 | &drv->fw.ucode_wowlan.data, | ||
| 657 | pieces.wowlan_data, | ||
| 658 | pieces.wowlan_data_size)) | ||
| 659 | goto err_pci_alloc; | ||
| 660 | } | ||
| 661 | |||
| 662 | /* Now that we can no longer fail, copy information */ | ||
| 663 | |||
| 664 | /* | ||
| 665 | * The (size - 16) / 12 formula is based on the information recorded | ||
| 666 | * for each event, which is of mode 1 (including timestamp) for all | ||
| 667 | * new microcodes that include this information. | ||
| 668 | */ | ||
| 669 | fw->init_evtlog_ptr = pieces.init_evtlog_ptr; | ||
| 670 | if (pieces.init_evtlog_size) | ||
| 671 | fw->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; | ||
| 672 | else | ||
| 673 | fw->init_evtlog_size = | ||
| 674 | cfg->base_params->max_event_log_size; | ||
| 675 | fw->init_errlog_ptr = pieces.init_errlog_ptr; | ||
| 676 | fw->inst_evtlog_ptr = pieces.inst_evtlog_ptr; | ||
| 677 | if (pieces.inst_evtlog_size) | ||
| 678 | fw->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; | ||
| 679 | else | ||
| 680 | fw->inst_evtlog_size = | ||
| 681 | cfg->base_params->max_event_log_size; | ||
| 682 | fw->inst_errlog_ptr = pieces.inst_errlog_ptr; | ||
| 683 | |||
| 684 | /* | ||
| 685 | * figure out the offset of chain noise reset and gain commands | ||
| 686 | * base on the size of standard phy calibration commands table size | ||
| 687 | */ | ||
| 688 | if (fw->ucode_capa.standard_phy_calibration_size > | ||
| 689 | IWL_MAX_PHY_CALIBRATE_TBL_SIZE) | ||
| 690 | fw->ucode_capa.standard_phy_calibration_size = | ||
| 691 | IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; | ||
| 692 | |||
| 693 | /* We have our copies now, allow OS release its copies */ | ||
| 694 | release_firmware(ucode_raw); | ||
| 695 | complete(&drv->request_firmware_complete); | ||
| 696 | |||
| 697 | drv->op_mode = iwl_dvm_ops.start(drv->shrd->trans, &drv->fw); | ||
| 698 | |||
| 699 | if (!drv->op_mode) | ||
| 700 | goto out_unbind; | ||
| 701 | |||
| 702 | return; | ||
| 703 | |||
| 704 | try_again: | ||
| 705 | /* try next, if any */ | ||
| 706 | release_firmware(ucode_raw); | ||
| 707 | if (iwl_request_firmware(drv, false)) | ||
| 708 | goto out_unbind; | ||
| 709 | return; | ||
| 710 | |||
| 711 | err_pci_alloc: | ||
| 712 | IWL_ERR(drv, "failed to allocate pci memory\n"); | ||
| 713 | iwl_dealloc_ucode(drv); | ||
| 714 | release_firmware(ucode_raw); | ||
| 715 | out_unbind: | ||
| 716 | complete(&drv->request_firmware_complete); | ||
| 717 | device_release_driver(trans(drv)->dev); | ||
| 718 | } | ||
| 719 | |||
| 70 | int iwl_drv_start(struct iwl_shared *shrd, | 720 | int iwl_drv_start(struct iwl_shared *shrd, |
| 71 | struct iwl_trans *trans, struct iwl_cfg *cfg) | 721 | struct iwl_trans *trans, const struct iwl_cfg *cfg) |
| 72 | { | 722 | { |
| 723 | struct iwl_drv *drv; | ||
| 73 | int ret; | 724 | int ret; |
| 74 | 725 | ||
| 75 | shrd->cfg = cfg; | 726 | shrd->cfg = cfg; |
| 76 | 727 | ||
| 77 | shrd->nic = kzalloc(sizeof(*shrd->nic), GFP_KERNEL); | 728 | drv = kzalloc(sizeof(*drv), GFP_KERNEL); |
| 78 | if (!shrd->nic) { | 729 | if (!drv) { |
| 79 | dev_printk(KERN_ERR, trans->dev, "Couldn't allocate iwl_nic"); | 730 | dev_printk(KERN_ERR, trans->dev, "Couldn't allocate iwl_drv"); |
| 80 | return -ENOMEM; | 731 | return -ENOMEM; |
| 81 | } | 732 | } |
| 82 | shrd->nic->shrd = shrd; | 733 | drv->shrd = shrd; |
| 734 | shrd->drv = drv; | ||
| 83 | 735 | ||
| 84 | init_completion(&shrd->nic->request_firmware_complete); | 736 | init_completion(&drv->request_firmware_complete); |
| 85 | 737 | ||
| 86 | ret = iwl_request_firmware(shrd->nic, true); | 738 | ret = iwl_request_firmware(drv, true); |
| 87 | 739 | ||
| 88 | if (ret) { | 740 | if (ret) { |
| 89 | dev_printk(KERN_ERR, trans->dev, "Couldn't request the fw"); | 741 | dev_printk(KERN_ERR, trans->dev, "Couldn't request the fw"); |
| 90 | kfree(shrd->nic); | 742 | kfree(drv); |
| 743 | shrd->drv = NULL; | ||
| 91 | } | 744 | } |
| 92 | 745 | ||
| 93 | return ret; | 746 | return ret; |
| @@ -95,9 +748,16 @@ int iwl_drv_start(struct iwl_shared *shrd, | |||
| 95 | 748 | ||
| 96 | void iwl_drv_stop(struct iwl_shared *shrd) | 749 | void iwl_drv_stop(struct iwl_shared *shrd) |
| 97 | { | 750 | { |
| 751 | struct iwl_drv *drv = shrd->drv; | ||
| 752 | |||
| 753 | wait_for_completion(&drv->request_firmware_complete); | ||
| 754 | |||
| 98 | /* op_mode can be NULL if its start failed */ | 755 | /* op_mode can be NULL if its start failed */ |
| 99 | if (shrd->nic->op_mode) | 756 | if (drv->op_mode) |
| 100 | iwl_op_mode_stop(shrd->nic->op_mode); | 757 | iwl_op_mode_stop(drv->op_mode); |
| 758 | |||
| 759 | iwl_dealloc_ucode(drv); | ||
| 101 | 760 | ||
| 102 | kfree(shrd->nic); | 761 | kfree(drv); |
| 762 | shrd->drv = NULL; | ||
| 103 | } | 763 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h index 90534a23ddc8..3b771c1d9096 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.h +++ b/drivers/net/wireless/iwlwifi/iwl-drv.h | |||
| @@ -105,7 +105,7 @@ | |||
| 105 | * function. | 105 | * function. |
| 106 | */ | 106 | */ |
| 107 | int iwl_drv_start(struct iwl_shared *shrd, | 107 | int iwl_drv_start(struct iwl_shared *shrd, |
| 108 | struct iwl_trans *trans, struct iwl_cfg *cfg); | 108 | struct iwl_trans *trans, const struct iwl_cfg *cfg); |
| 109 | 109 | ||
| 110 | /** | 110 | /** |
| 111 | * iwl_drv_stop - stop the drv | 111 | * iwl_drv_stop - stop the drv |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 07e93787bce8..23cea42b9495 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c | |||
| @@ -75,6 +75,7 @@ | |||
| 75 | #include "iwl-agn.h" | 75 | #include "iwl-agn.h" |
| 76 | #include "iwl-eeprom.h" | 76 | #include "iwl-eeprom.h" |
| 77 | #include "iwl-io.h" | 77 | #include "iwl-io.h" |
| 78 | #include "iwl-prph.h" | ||
| 78 | 79 | ||
| 79 | /************************** EEPROM BANDS **************************** | 80 | /************************** EEPROM BANDS **************************** |
| 80 | * | 81 | * |
| @@ -252,46 +253,46 @@ err: | |||
| 252 | 253 | ||
| 253 | } | 254 | } |
| 254 | 255 | ||
| 255 | int iwl_eeprom_check_sku(struct iwl_priv *priv) | 256 | int iwl_eeprom_init_hw_params(struct iwl_priv *priv) |
| 256 | { | 257 | { |
| 257 | struct iwl_shared *shrd = priv->shrd; | 258 | struct iwl_shared *shrd = priv->shrd; |
| 258 | u16 radio_cfg; | 259 | u16 radio_cfg; |
| 259 | 260 | ||
| 260 | if (!cfg(priv)->sku) { | 261 | hw_params(priv).sku = iwl_eeprom_query16(shrd, EEPROM_SKU_CAP); |
| 261 | /* not using sku overwrite */ | 262 | if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE && |
| 262 | cfg(priv)->sku = iwl_eeprom_query16(shrd, EEPROM_SKU_CAP); | 263 | !cfg(priv)->ht_params) { |
| 263 | if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE && | 264 | IWL_ERR(priv, "Invalid 11n configuration\n"); |
| 264 | !cfg(priv)->ht_params) { | 265 | return -EINVAL; |
| 265 | IWL_ERR(priv, "Invalid 11n configuration\n"); | ||
| 266 | return -EINVAL; | ||
| 267 | } | ||
| 268 | } | 266 | } |
| 269 | if (!cfg(priv)->sku) { | 267 | |
| 268 | if (!hw_params(priv).sku) { | ||
| 270 | IWL_ERR(priv, "Invalid device sku\n"); | 269 | IWL_ERR(priv, "Invalid device sku\n"); |
| 271 | return -EINVAL; | 270 | return -EINVAL; |
| 272 | } | 271 | } |
| 273 | 272 | ||
| 274 | IWL_INFO(priv, "Device SKU: 0x%X\n", cfg(priv)->sku); | 273 | IWL_INFO(priv, "Device SKU: 0x%X\n", hw_params(priv).sku); |
| 275 | 274 | ||
| 276 | if (!cfg(priv)->valid_tx_ant && !cfg(priv)->valid_rx_ant) { | 275 | radio_cfg = iwl_eeprom_query16(shrd, EEPROM_RADIO_CONFIG); |
| 277 | /* not using .cfg overwrite */ | 276 | |
| 278 | radio_cfg = iwl_eeprom_query16(shrd, EEPROM_RADIO_CONFIG); | 277 | hw_params(priv).valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); |
| 279 | cfg(priv)->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); | 278 | hw_params(priv).valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg); |
| 280 | cfg(priv)->valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg); | 279 | |
| 281 | if (!cfg(priv)->valid_tx_ant || !cfg(priv)->valid_rx_ant) { | 280 | /* check overrides (some devices have wrong EEPROM) */ |
| 282 | IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n", | 281 | if (cfg(priv)->valid_tx_ant) |
| 283 | cfg(priv)->valid_tx_ant, | 282 | hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; |
| 284 | cfg(priv)->valid_rx_ant); | 283 | if (cfg(priv)->valid_rx_ant) |
| 285 | return -EINVAL; | 284 | hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; |
| 286 | } | 285 | |
| 287 | IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", | 286 | if (!hw_params(priv).valid_tx_ant || !hw_params(priv).valid_rx_ant) { |
| 288 | cfg(priv)->valid_tx_ant, cfg(priv)->valid_rx_ant); | 287 | IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n", |
| 288 | hw_params(priv).valid_tx_ant, | ||
| 289 | hw_params(priv).valid_rx_ant); | ||
| 290 | return -EINVAL; | ||
| 289 | } | 291 | } |
| 290 | /* | 292 | |
| 291 | * for some special cases, | 293 | IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", |
| 292 | * EEPROM did not reflect the correct antenna setting | 294 | hw_params(priv).valid_tx_ant, hw_params(priv).valid_rx_ant); |
| 293 | * so overwrite the valid tx/rx antenna from .cfg | 295 | |
| 294 | */ | ||
| 295 | return 0; | 296 | return 0; |
| 296 | } | 297 | } |
| 297 | 298 | ||
| @@ -512,7 +513,7 @@ static int iwl_find_otp_image(struct iwl_trans *trans, | |||
| 512 | * iwl_get_max_txpower_avg - get the highest tx power from all chains. | 513 | * iwl_get_max_txpower_avg - get the highest tx power from all chains. |
| 513 | * find the highest tx power from all chains for the channel | 514 | * find the highest tx power from all chains for the channel |
| 514 | */ | 515 | */ |
| 515 | static s8 iwl_get_max_txpower_avg(struct iwl_cfg *cfg, | 516 | static s8 iwl_get_max_txpower_avg(const struct iwl_cfg *cfg, |
| 516 | struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, | 517 | struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, |
| 517 | int element, s8 *max_txpower_in_half_dbm) | 518 | int element, s8 *max_txpower_in_half_dbm) |
| 518 | { | 519 | { |
| @@ -588,7 +589,7 @@ iwl_eeprom_enh_txp_read_element(struct iwl_priv *priv, | |||
| 588 | #define TXP_CHECK_AND_PRINT(x) ((txp->flags & IWL_EEPROM_ENH_TXP_FL_##x) \ | 589 | #define TXP_CHECK_AND_PRINT(x) ((txp->flags & IWL_EEPROM_ENH_TXP_FL_##x) \ |
| 589 | ? # x " " : "") | 590 | ? # x " " : "") |
| 590 | 591 | ||
| 591 | void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) | 592 | static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) |
| 592 | { | 593 | { |
| 593 | struct iwl_shared *shrd = priv->shrd; | 594 | struct iwl_shared *shrd = priv->shrd; |
| 594 | struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; | 595 | struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; |
| @@ -1024,8 +1025,8 @@ int iwl_init_channel_map(struct iwl_priv *priv) | |||
| 1024 | * driver need to process addition information | 1025 | * driver need to process addition information |
| 1025 | * to determine the max channel tx power limits | 1026 | * to determine the max channel tx power limits |
| 1026 | */ | 1027 | */ |
| 1027 | if (cfg(priv)->lib->eeprom_ops.update_enhanced_txpower) | 1028 | if (cfg(priv)->lib->eeprom_ops.enhanced_txpower) |
| 1028 | cfg(priv)->lib->eeprom_ops.update_enhanced_txpower(priv); | 1029 | iwl_eeprom_enhanced_txpower(priv); |
| 1029 | 1030 | ||
| 1030 | return 0; | 1031 | return 0; |
| 1031 | } | 1032 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index cbb86116917b..e4a758340996 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h | |||
| @@ -302,14 +302,14 @@ extern const u8 iwl_eeprom_band_1[14]; | |||
| 302 | 302 | ||
| 303 | struct iwl_eeprom_ops { | 303 | struct iwl_eeprom_ops { |
| 304 | const u32 regulatory_bands[7]; | 304 | const u32 regulatory_bands[7]; |
| 305 | void (*update_enhanced_txpower) (struct iwl_priv *priv); | 305 | bool enhanced_txpower; |
| 306 | }; | 306 | }; |
| 307 | 307 | ||
| 308 | 308 | ||
| 309 | int iwl_eeprom_init(struct iwl_trans *trans, u32 hw_rev); | 309 | int iwl_eeprom_init(struct iwl_trans *trans, u32 hw_rev); |
| 310 | void iwl_eeprom_free(struct iwl_shared *shrd); | 310 | void iwl_eeprom_free(struct iwl_shared *shrd); |
| 311 | int iwl_eeprom_check_version(struct iwl_priv *priv); | 311 | int iwl_eeprom_check_version(struct iwl_priv *priv); |
| 312 | int iwl_eeprom_check_sku(struct iwl_priv *priv); | 312 | int iwl_eeprom_init_hw_params(struct iwl_priv *priv); |
| 313 | const u8 *iwl_eeprom_query_addr(const struct iwl_shared *shrd, size_t offset); | 313 | const u8 *iwl_eeprom_query_addr(const struct iwl_shared *shrd, size_t offset); |
| 314 | u16 iwl_eeprom_query16(const struct iwl_shared *shrd, size_t offset); | 314 | u16 iwl_eeprom_query16(const struct iwl_shared *shrd, size_t offset); |
| 315 | int iwl_init_channel_map(struct iwl_priv *priv); | 315 | int iwl_init_channel_map(struct iwl_priv *priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index 8bebeb003bef..7ca6c9526357 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h | |||
| @@ -60,8 +60,8 @@ | |||
| 60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 61 | *****************************************************************************/ | 61 | *****************************************************************************/ |
| 62 | 62 | ||
| 63 | #ifndef __iwl_ucode_h__ | 63 | #ifndef __iwl_fw_file_h__ |
| 64 | #define __iwl_ucode_h__ | 64 | #define __iwl_fw_file_h__ |
| 65 | 65 | ||
| 66 | #include <linux/netdevice.h> | 66 | #include <linux/netdevice.h> |
| 67 | 67 | ||
| @@ -126,22 +126,6 @@ enum iwl_ucode_tlv_type { | |||
| 126 | IWL_UCODE_TLV_FLAGS = 18, | 126 | IWL_UCODE_TLV_FLAGS = 18, |
| 127 | }; | 127 | }; |
| 128 | 128 | ||
| 129 | /** | ||
| 130 | * enum iwl_ucode_tlv_flag - ucode API flags | ||
| 131 | * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously | ||
| 132 | * was a separate TLV but moved here to save space. | ||
| 133 | * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID, | ||
| 134 | * treats good CRC threshold as a boolean | ||
| 135 | * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). | ||
| 136 | * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. | ||
| 137 | */ | ||
| 138 | enum iwl_ucode_tlv_flag { | ||
| 139 | IWL_UCODE_TLV_FLAGS_PAN = BIT(0), | ||
| 140 | IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), | ||
| 141 | IWL_UCODE_TLV_FLAGS_MFP = BIT(2), | ||
| 142 | IWL_UCODE_TLV_FLAGS_P2P = BIT(3), | ||
| 143 | }; | ||
| 144 | |||
| 145 | struct iwl_ucode_tlv { | 129 | struct iwl_ucode_tlv { |
| 146 | __le16 type; /* see above */ | 130 | __le16 type; /* see above */ |
| 147 | __le16 alternative; /* see comment */ | 131 | __le16 alternative; /* see comment */ |
| @@ -173,48 +157,4 @@ struct iwl_tlv_ucode_header { | |||
| 173 | u8 data[0]; | 157 | u8 data[0]; |
| 174 | }; | 158 | }; |
| 175 | 159 | ||
| 176 | struct iwl_ucode_capabilities { | 160 | #endif /* __iwl_fw_file_h__ */ |
| 177 | u32 max_probe_length; | ||
| 178 | u32 standard_phy_calibration_size; | ||
| 179 | u32 flags; | ||
| 180 | }; | ||
| 181 | |||
| 182 | /* one for each uCode image (inst/data, boot/init/runtime) */ | ||
| 183 | struct fw_desc { | ||
| 184 | dma_addr_t p_addr; /* hardware address */ | ||
| 185 | void *v_addr; /* software address */ | ||
| 186 | u32 len; /* size in bytes */ | ||
| 187 | }; | ||
| 188 | |||
| 189 | struct fw_img { | ||
| 190 | struct fw_desc code; /* firmware code image */ | ||
| 191 | struct fw_desc data; /* firmware data image */ | ||
| 192 | }; | ||
| 193 | |||
| 194 | /** | ||
| 195 | * struct iwl_fw - variables associated with the firmware | ||
| 196 | * | ||
| 197 | * @ucode_ver: ucode version from the ucode file | ||
| 198 | * @fw_version: firmware version string | ||
| 199 | * @ucode_rt: run time ucode image | ||
| 200 | * @ucode_init: init ucode image | ||
| 201 | * @ucode_wowlan: wake on wireless ucode image (optional) | ||
| 202 | * @ucode_capa: capabilities parsed from the ucode file. | ||
| 203 | * @enhance_sensitivity_table: device can do enhanced sensitivity. | ||
| 204 | */ | ||
| 205 | struct iwl_fw { | ||
| 206 | |||
| 207 | u32 ucode_ver; | ||
| 208 | |||
| 209 | char fw_version[ETHTOOL_BUSINFO_LEN]; | ||
| 210 | |||
| 211 | /* ucode images */ | ||
| 212 | struct fw_img ucode_rt; | ||
| 213 | struct fw_img ucode_init; | ||
| 214 | struct fw_img ucode_wowlan; | ||
| 215 | |||
| 216 | struct iwl_ucode_capabilities ucode_capa; | ||
| 217 | bool enhance_sensitivity_table; | ||
| 218 | }; | ||
| 219 | |||
| 220 | #endif /* __iwl_ucode_h__ */ | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-wifi.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index d5cba07a24c8..453812a21176 100644 --- a/drivers/net/wireless/iwlwifi/iwl-wifi.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h | |||
| @@ -60,52 +60,87 @@ | |||
| 60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 61 | *****************************************************************************/ | 61 | *****************************************************************************/ |
| 62 | 62 | ||
| 63 | #ifndef __iwl_wifi_h__ | 63 | #ifndef __iwl_fw_h__ |
| 64 | #define __iwl_wifi_h__ | 64 | #define __iwl_fw_h__ |
| 65 | #include <linux/types.h> | ||
| 65 | 66 | ||
| 66 | #include "iwl-shared.h" | 67 | /** |
| 67 | #include "iwl-ucode.h" | 68 | * enum iwl_ucode_tlv_flag - ucode API flags |
| 69 | * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously | ||
| 70 | * was a separate TLV but moved here to save space. | ||
| 71 | * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID, | ||
| 72 | * treats good CRC threshold as a boolean | ||
| 73 | * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). | ||
| 74 | * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. | ||
| 75 | */ | ||
| 76 | enum iwl_ucode_tlv_flag { | ||
| 77 | IWL_UCODE_TLV_FLAGS_PAN = BIT(0), | ||
| 78 | IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), | ||
| 79 | IWL_UCODE_TLV_FLAGS_MFP = BIT(2), | ||
| 80 | IWL_UCODE_TLV_FLAGS_P2P = BIT(3), | ||
| 81 | }; | ||
| 82 | |||
| 83 | /* The default calibrate table size if not specified by firmware file */ | ||
| 84 | #define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE 18 | ||
| 85 | #define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE 19 | ||
| 86 | #define IWL_MAX_PHY_CALIBRATE_TBL_SIZE 253 | ||
| 68 | 87 | ||
| 69 | #define UCODE_EXPERIMENTAL_INDEX 100 | 88 | struct iwl_ucode_capabilities { |
| 89 | u32 max_probe_length; | ||
| 90 | u32 standard_phy_calibration_size; | ||
| 91 | u32 flags; | ||
| 92 | }; | ||
| 93 | |||
| 94 | /* one for each uCode image (inst/data, boot/init/runtime) */ | ||
| 95 | struct fw_desc { | ||
| 96 | dma_addr_t p_addr; /* hardware address */ | ||
| 97 | void *v_addr; /* software address */ | ||
| 98 | u32 len; /* size in bytes */ | ||
| 99 | }; | ||
| 100 | |||
| 101 | struct fw_img { | ||
| 102 | struct fw_desc code; /* firmware code image */ | ||
| 103 | struct fw_desc data; /* firmware data image */ | ||
| 104 | }; | ||
| 105 | |||
| 106 | /* uCode version contains 4 values: Major/Minor/API/Serial */ | ||
| 107 | #define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24) | ||
| 108 | #define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16) | ||
| 109 | #define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8) | ||
| 110 | #define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF) | ||
| 70 | 111 | ||
| 71 | /** | 112 | /** |
| 72 | * struct iwl_nic - nic common data | 113 | * struct iwl_fw - variables associated with the firmware |
| 73 | * @fw: the iwl_fw structure | 114 | * |
| 74 | * @shrd: pointer to common shared structure | 115 | * @ucode_ver: ucode version from the ucode file |
| 75 | * @op_mode: the running op_mode | 116 | * @fw_version: firmware version string |
| 76 | * @fw_index: firmware revision to try loading | 117 | * @ucode_rt: run time ucode image |
| 77 | * @firmware_name: composite filename of ucode file to load | 118 | * @ucode_init: init ucode image |
| 119 | * @ucode_wowlan: wake on wireless ucode image (optional) | ||
| 120 | * @ucode_capa: capabilities parsed from the ucode file. | ||
| 121 | * @enhance_sensitivity_table: device can do enhanced sensitivity. | ||
| 78 | * @init_evtlog_ptr: event log offset for init ucode. | 122 | * @init_evtlog_ptr: event log offset for init ucode. |
| 79 | * @init_evtlog_size: event log size for init ucode. | 123 | * @init_evtlog_size: event log size for init ucode. |
| 80 | * @init_errlog_ptr: error log offfset for init ucode. | 124 | * @init_errlog_ptr: error log offfset for init ucode. |
| 81 | * @inst_evtlog_ptr: event log offset for runtime ucode. | 125 | * @inst_evtlog_ptr: event log offset for runtime ucode. |
| 82 | * @inst_evtlog_size: event log size for runtime ucode. | 126 | * @inst_evtlog_size: event log size for runtime ucode. |
| 83 | * @inst_errlog_ptr: error log offfset for runtime ucode. | 127 | * @inst_errlog_ptr: error log offfset for runtime ucode. |
| 84 | * @request_firmware_complete: the firmware has been obtained from user space | ||
| 85 | */ | 128 | */ |
| 86 | struct iwl_nic { | 129 | struct iwl_fw { |
| 87 | struct iwl_fw fw; | 130 | u32 ucode_ver; |
| 131 | |||
| 132 | char fw_version[ETHTOOL_BUSINFO_LEN]; | ||
| 88 | 133 | ||
| 89 | struct iwl_shared *shrd; | 134 | /* ucode images */ |
| 90 | struct iwl_op_mode *op_mode; | 135 | struct fw_img ucode_rt; |
| 136 | struct fw_img ucode_init; | ||
| 137 | struct fw_img ucode_wowlan; | ||
| 91 | 138 | ||
| 92 | int fw_index; /* firmware we're trying to load */ | 139 | struct iwl_ucode_capabilities ucode_capa; |
| 93 | char firmware_name[25]; /* name of firmware file to load */ | 140 | bool enhance_sensitivity_table; |
| 94 | 141 | ||
| 95 | u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; | 142 | u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; |
| 96 | u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; | 143 | u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; |
| 97 | |||
| 98 | struct completion request_firmware_complete; | ||
| 99 | }; | 144 | }; |
| 100 | 145 | ||
| 101 | 146 | #endif /* __iwl_fw_h__ */ | |
| 102 | int __must_check iwl_request_firmware(struct iwl_nic *nic, bool first); | ||
| 103 | void iwl_dealloc_ucode(struct iwl_nic *nic); | ||
| 104 | |||
| 105 | int iwl_send_bt_env(struct iwl_trans *trans, u8 action, u8 type); | ||
| 106 | void iwl_send_prio_tbl(struct iwl_trans *trans); | ||
| 107 | int iwl_init_alive_start(struct iwl_trans *trans); | ||
| 108 | int iwl_run_init_ucode(struct iwl_trans *trans); | ||
| 109 | int iwl_load_ucode_wait_alive(struct iwl_trans *trans, | ||
| 110 | enum iwl_ucode_type ucode_type); | ||
| 111 | #endif /* __iwl_wifi_h__ */ | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index e2e3b5c9cf7f..081dd34d2387 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c | |||
| @@ -118,16 +118,17 @@ int iwl_grab_nic_access_silent(struct iwl_trans *trans) | |||
| 118 | return 0; | 118 | return 0; |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | int iwl_grab_nic_access(struct iwl_trans *trans) | 121 | bool iwl_grab_nic_access(struct iwl_trans *trans) |
| 122 | { | 122 | { |
| 123 | int ret = iwl_grab_nic_access_silent(trans); | 123 | int ret = iwl_grab_nic_access_silent(trans); |
| 124 | if (ret) { | 124 | if (unlikely(ret)) { |
| 125 | u32 val = iwl_read32(trans, CSR_GP_CNTRL); | 125 | u32 val = iwl_read32(trans, CSR_GP_CNTRL); |
| 126 | IWL_ERR(trans, | 126 | WARN_ONCE(1, "Timeout waiting for hardware access " |
| 127 | "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val); | 127 | "(CSR_GP_CNTRL 0x%08x)\n", val); |
| 128 | return false; | ||
| 128 | } | 129 | } |
| 129 | 130 | ||
| 130 | return ret; | 131 | return true; |
| 131 | } | 132 | } |
| 132 | 133 | ||
| 133 | void iwl_release_nic_access(struct iwl_trans *trans) | 134 | void iwl_release_nic_access(struct iwl_trans *trans) |
| @@ -135,6 +136,13 @@ void iwl_release_nic_access(struct iwl_trans *trans) | |||
| 135 | lockdep_assert_held(&trans->reg_lock); | 136 | lockdep_assert_held(&trans->reg_lock); |
| 136 | __iwl_clear_bit(trans, CSR_GP_CNTRL, | 137 | __iwl_clear_bit(trans, CSR_GP_CNTRL, |
| 137 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 138 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
| 139 | /* | ||
| 140 | * Above we read the CSR_GP_CNTRL register, which will flush | ||
| 141 | * any previous writes, but we need the write that clears the | ||
| 142 | * MAC_ACCESS_REQ bit to be performed before any other writes | ||
| 143 | * scheduled on different CPUs (after we drop reg_lock). | ||
| 144 | */ | ||
| 145 | mmiowb(); | ||
| 138 | } | 146 | } |
| 139 | 147 | ||
| 140 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) | 148 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) |
| @@ -156,7 +164,7 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) | |||
| 156 | unsigned long flags; | 164 | unsigned long flags; |
| 157 | 165 | ||
| 158 | spin_lock_irqsave(&trans->reg_lock, flags); | 166 | spin_lock_irqsave(&trans->reg_lock, flags); |
| 159 | if (!iwl_grab_nic_access(trans)) { | 167 | if (likely(iwl_grab_nic_access(trans))) { |
| 160 | iwl_write32(trans, reg, value); | 168 | iwl_write32(trans, reg, value); |
| 161 | iwl_release_nic_access(trans); | 169 | iwl_release_nic_access(trans); |
| 162 | } | 170 | } |
| @@ -181,7 +189,6 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, | |||
| 181 | static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 reg) | 189 | static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 reg) |
| 182 | { | 190 | { |
| 183 | iwl_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); | 191 | iwl_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); |
| 184 | rmb(); | ||
| 185 | return iwl_read32(trans, HBUS_TARG_PRPH_RDAT); | 192 | return iwl_read32(trans, HBUS_TARG_PRPH_RDAT); |
| 186 | } | 193 | } |
| 187 | 194 | ||
| @@ -189,7 +196,6 @@ static inline void __iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) | |||
| 189 | { | 196 | { |
| 190 | iwl_write32(trans, HBUS_TARG_PRPH_WADDR, | 197 | iwl_write32(trans, HBUS_TARG_PRPH_WADDR, |
| 191 | ((addr & 0x0000FFFF) | (3 << 24))); | 198 | ((addr & 0x0000FFFF) | (3 << 24))); |
| 192 | wmb(); | ||
| 193 | iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); | 199 | iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); |
| 194 | } | 200 | } |
| 195 | 201 | ||
| @@ -211,7 +217,7 @@ void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) | |||
| 211 | unsigned long flags; | 217 | unsigned long flags; |
| 212 | 218 | ||
| 213 | spin_lock_irqsave(&trans->reg_lock, flags); | 219 | spin_lock_irqsave(&trans->reg_lock, flags); |
| 214 | if (!iwl_grab_nic_access(trans)) { | 220 | if (likely(iwl_grab_nic_access(trans))) { |
| 215 | __iwl_write_prph(trans, addr, val); | 221 | __iwl_write_prph(trans, addr, val); |
| 216 | iwl_release_nic_access(trans); | 222 | iwl_release_nic_access(trans); |
| 217 | } | 223 | } |
| @@ -223,9 +229,11 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) | |||
| 223 | unsigned long flags; | 229 | unsigned long flags; |
| 224 | 230 | ||
| 225 | spin_lock_irqsave(&trans->reg_lock, flags); | 231 | spin_lock_irqsave(&trans->reg_lock, flags); |
| 226 | iwl_grab_nic_access(trans); | 232 | if (likely(iwl_grab_nic_access(trans))) { |
| 227 | __iwl_write_prph(trans, reg, __iwl_read_prph(trans, reg) | mask); | 233 | __iwl_write_prph(trans, reg, |
| 228 | iwl_release_nic_access(trans); | 234 | __iwl_read_prph(trans, reg) | mask); |
| 235 | iwl_release_nic_access(trans); | ||
| 236 | } | ||
| 229 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 237 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
| 230 | } | 238 | } |
| 231 | 239 | ||
| @@ -235,10 +243,11 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg, | |||
| 235 | unsigned long flags; | 243 | unsigned long flags; |
| 236 | 244 | ||
| 237 | spin_lock_irqsave(&trans->reg_lock, flags); | 245 | spin_lock_irqsave(&trans->reg_lock, flags); |
| 238 | iwl_grab_nic_access(trans); | 246 | if (likely(iwl_grab_nic_access(trans))) { |
| 239 | __iwl_write_prph(trans, reg, | 247 | __iwl_write_prph(trans, reg, |
| 240 | (__iwl_read_prph(trans, reg) & mask) | bits); | 248 | (__iwl_read_prph(trans, reg) & mask) | bits); |
| 241 | iwl_release_nic_access(trans); | 249 | iwl_release_nic_access(trans); |
| 250 | } | ||
| 242 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 251 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
| 243 | } | 252 | } |
| 244 | 253 | ||
| @@ -248,10 +257,11 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) | |||
| 248 | u32 val; | 257 | u32 val; |
| 249 | 258 | ||
| 250 | spin_lock_irqsave(&trans->reg_lock, flags); | 259 | spin_lock_irqsave(&trans->reg_lock, flags); |
| 251 | iwl_grab_nic_access(trans); | 260 | if (likely(iwl_grab_nic_access(trans))) { |
| 252 | val = __iwl_read_prph(trans, reg); | 261 | val = __iwl_read_prph(trans, reg); |
| 253 | __iwl_write_prph(trans, reg, (val & ~mask)); | 262 | __iwl_write_prph(trans, reg, (val & ~mask)); |
| 254 | iwl_release_nic_access(trans); | 263 | iwl_release_nic_access(trans); |
| 264 | } | ||
| 255 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 265 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
| 256 | } | 266 | } |
| 257 | 267 | ||
| @@ -263,15 +273,12 @@ void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, | |||
| 263 | u32 *vals = buf; | 273 | u32 *vals = buf; |
| 264 | 274 | ||
| 265 | spin_lock_irqsave(&trans->reg_lock, flags); | 275 | spin_lock_irqsave(&trans->reg_lock, flags); |
| 266 | iwl_grab_nic_access(trans); | 276 | if (likely(iwl_grab_nic_access(trans))) { |
| 267 | 277 | iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); | |
| 268 | iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); | 278 | for (offs = 0; offs < words; offs++) |
| 269 | rmb(); | 279 | vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); |
| 270 | 280 | iwl_release_nic_access(trans); | |
| 271 | for (offs = 0; offs < words; offs++) | 281 | } |
| 272 | vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); | ||
| 273 | |||
| 274 | iwl_release_nic_access(trans); | ||
| 275 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 282 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
| 276 | } | 283 | } |
| 277 | 284 | ||
| @@ -292,10 +299,8 @@ int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, | |||
| 292 | u32 *vals = buf; | 299 | u32 *vals = buf; |
| 293 | 300 | ||
| 294 | spin_lock_irqsave(&trans->reg_lock, flags); | 301 | spin_lock_irqsave(&trans->reg_lock, flags); |
| 295 | if (!iwl_grab_nic_access(trans)) { | 302 | if (likely(iwl_grab_nic_access(trans))) { |
| 296 | iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); | 303 | iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); |
| 297 | wmb(); | ||
| 298 | |||
| 299 | for (offs = 0; offs < words; offs++) | 304 | for (offs = 0; offs < words; offs++) |
| 300 | iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]); | 305 | iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]); |
| 301 | iwl_release_nic_access(trans); | 306 | iwl_release_nic_access(trans); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index 782486fc2f8f..09b856768f62 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h | |||
| @@ -35,20 +35,20 @@ | |||
| 35 | 35 | ||
| 36 | static inline void iwl_write8(struct iwl_trans *trans, u32 ofs, u8 val) | 36 | static inline void iwl_write8(struct iwl_trans *trans, u32 ofs, u8 val) |
| 37 | { | 37 | { |
| 38 | trace_iwlwifi_dev_iowrite8(priv(trans), ofs, val); | 38 | trace_iwlwifi_dev_iowrite8(trans->dev, ofs, val); |
| 39 | iwl_trans_write8(trans, ofs, val); | 39 | iwl_trans_write8(trans, ofs, val); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | static inline void iwl_write32(struct iwl_trans *trans, u32 ofs, u32 val) | 42 | static inline void iwl_write32(struct iwl_trans *trans, u32 ofs, u32 val) |
| 43 | { | 43 | { |
| 44 | trace_iwlwifi_dev_iowrite32(priv(trans), ofs, val); | 44 | trace_iwlwifi_dev_iowrite32(trans->dev, ofs, val); |
| 45 | iwl_trans_write32(trans, ofs, val); | 45 | iwl_trans_write32(trans, ofs, val); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs) | 48 | static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs) |
| 49 | { | 49 | { |
| 50 | u32 val = iwl_trans_read32(trans, ofs); | 50 | u32 val = iwl_trans_read32(trans, ofs); |
| 51 | trace_iwlwifi_dev_ioread32(priv(trans), ofs, val); | 51 | trace_iwlwifi_dev_ioread32(trans->dev, ofs, val); |
| 52 | return val; | 52 | return val; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| @@ -61,7 +61,7 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, | |||
| 61 | int timeout); | 61 | int timeout); |
| 62 | 62 | ||
| 63 | int iwl_grab_nic_access_silent(struct iwl_trans *trans); | 63 | int iwl_grab_nic_access_silent(struct iwl_trans *trans); |
| 64 | int iwl_grab_nic_access(struct iwl_trans *trans); | 64 | bool iwl_grab_nic_access(struct iwl_trans *trans); |
| 65 | void iwl_release_nic_access(struct iwl_trans *trans); | 65 | void iwl_release_nic_access(struct iwl_trans *trans); |
| 66 | 66 | ||
| 67 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg); | 67 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 5c7741f07aa0..1993a2b7ae63 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c | |||
| @@ -112,7 +112,7 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) | |||
| 112 | iwl_write32(trans(priv), CSR_LED_REG, | 112 | iwl_write32(trans(priv), CSR_LED_REG, |
| 113 | reg & CSR_LED_BSM_CTRL_MSK); | 113 | reg & CSR_LED_BSM_CTRL_MSK); |
| 114 | 114 | ||
| 115 | return iwl_trans_send_cmd(trans(priv), &cmd); | 115 | return iwl_dvm_send_cmd(priv, &cmd); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | /* Set led pattern command */ | 118 | /* Set led pattern command */ |
| @@ -126,7 +126,7 @@ static int iwl_led_cmd(struct iwl_priv *priv, | |||
| 126 | }; | 126 | }; |
| 127 | int ret; | 127 | int ret; |
| 128 | 128 | ||
| 129 | if (!test_bit(STATUS_READY, &priv->shrd->status)) | 129 | if (!test_bit(STATUS_READY, &priv->status)) |
| 130 | return -EBUSY; | 130 | return -EBUSY; |
| 131 | 131 | ||
| 132 | if (priv->blink_on == on && priv->blink_off == off) | 132 | if (priv->blink_on == on && priv->blink_off == off) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 03f770543d8e..9212ee3bef9b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c | |||
| @@ -42,9 +42,7 @@ | |||
| 42 | 42 | ||
| 43 | #include <asm/div64.h> | 43 | #include <asm/div64.h> |
| 44 | 44 | ||
| 45 | #include "iwl-ucode.h" | ||
| 46 | #include "iwl-eeprom.h" | 45 | #include "iwl-eeprom.h" |
| 47 | #include "iwl-wifi.h" | ||
| 48 | #include "iwl-dev.h" | 46 | #include "iwl-dev.h" |
| 49 | #include "iwl-core.h" | 47 | #include "iwl-core.h" |
| 50 | #include "iwl-io.h" | 48 | #include "iwl-io.h" |
| @@ -136,7 +134,7 @@ iwlagn_iface_combinations_p2p[] = { | |||
| 136 | * other mac80211 functions grouped here. | 134 | * other mac80211 functions grouped here. |
| 137 | */ | 135 | */ |
| 138 | int iwlagn_mac_setup_register(struct iwl_priv *priv, | 136 | int iwlagn_mac_setup_register(struct iwl_priv *priv, |
| 139 | struct iwl_ucode_capabilities *capa) | 137 | const struct iwl_ucode_capabilities *capa) |
| 140 | { | 138 | { |
| 141 | int ret; | 139 | int ret; |
| 142 | struct ieee80211_hw *hw = priv->hw; | 140 | struct ieee80211_hw *hw = priv->hw; |
| @@ -161,11 +159,14 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, | |||
| 161 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | | 159 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | |
| 162 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | 160 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; |
| 163 | 161 | ||
| 164 | if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE) | 162 | if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) |
| 165 | hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | 163 | hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | |
| 166 | IEEE80211_HW_SUPPORTS_STATIC_SMPS; | 164 | IEEE80211_HW_SUPPORTS_STATIC_SMPS; |
| 167 | 165 | ||
| 166 | #ifndef CONFIG_IWLWIFI_EXPERIMENTAL_MFP | ||
| 167 | /* enable 11w if the uCode advertise */ | ||
| 168 | if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP) | 168 | if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP) |
| 169 | #endif /* !CONFIG_IWLWIFI_EXPERIMENTAL_MFP */ | ||
| 169 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; | 170 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; |
| 170 | 171 | ||
| 171 | hw->sta_data_size = sizeof(struct iwl_station_priv); | 172 | hw->sta_data_size = sizeof(struct iwl_station_priv); |
| @@ -195,7 +196,8 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, | |||
| 195 | WIPHY_FLAG_DISABLE_BEACON_HINTS | | 196 | WIPHY_FLAG_DISABLE_BEACON_HINTS | |
| 196 | WIPHY_FLAG_IBSS_RSN; | 197 | WIPHY_FLAG_IBSS_RSN; |
| 197 | 198 | ||
| 198 | if (nic(priv)->fw.ucode_wowlan.code.len && | 199 | if (priv->fw->ucode_wowlan.code.len && |
| 200 | trans(priv)->ops->wowlan_suspend && | ||
| 199 | device_can_wakeup(trans(priv)->dev)) { | 201 | device_can_wakeup(trans(priv)->dev)) { |
| 200 | hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | | 202 | hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | |
| 201 | WIPHY_WOWLAN_DISCONNECT | | 203 | WIPHY_WOWLAN_DISCONNECT | |
| @@ -262,9 +264,9 @@ static int __iwl_up(struct iwl_priv *priv) | |||
| 262 | struct iwl_rxon_context *ctx; | 264 | struct iwl_rxon_context *ctx; |
| 263 | int ret; | 265 | int ret; |
| 264 | 266 | ||
| 265 | lockdep_assert_held(&priv->shrd->mutex); | 267 | lockdep_assert_held(&priv->mutex); |
| 266 | 268 | ||
| 267 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { | 269 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
| 268 | IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); | 270 | IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); |
| 269 | return -EIO; | 271 | return -EIO; |
| 270 | } | 272 | } |
| @@ -277,13 +279,13 @@ static int __iwl_up(struct iwl_priv *priv) | |||
| 277 | } | 279 | } |
| 278 | } | 280 | } |
| 279 | 281 | ||
| 280 | ret = iwl_run_init_ucode(trans(priv)); | 282 | ret = iwl_run_init_ucode(priv); |
| 281 | if (ret) { | 283 | if (ret) { |
| 282 | IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret); | 284 | IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret); |
| 283 | goto error; | 285 | goto error; |
| 284 | } | 286 | } |
| 285 | 287 | ||
| 286 | ret = iwl_load_ucode_wait_alive(trans(priv), IWL_UCODE_REGULAR); | 288 | ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR); |
| 287 | if (ret) { | 289 | if (ret) { |
| 288 | IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret); | 290 | IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret); |
| 289 | goto error; | 291 | goto error; |
| @@ -295,9 +297,9 @@ static int __iwl_up(struct iwl_priv *priv) | |||
| 295 | return 0; | 297 | return 0; |
| 296 | 298 | ||
| 297 | error: | 299 | error: |
| 298 | set_bit(STATUS_EXIT_PENDING, &priv->shrd->status); | 300 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
| 299 | iwl_down(priv); | 301 | iwl_down(priv); |
| 300 | clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status); | 302 | clear_bit(STATUS_EXIT_PENDING, &priv->status); |
| 301 | 303 | ||
| 302 | IWL_ERR(priv, "Unable to initialize device.\n"); | 304 | IWL_ERR(priv, "Unable to initialize device.\n"); |
| 303 | return ret; | 305 | return ret; |
| @@ -311,16 +313,16 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw) | |||
| 311 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 313 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
| 312 | 314 | ||
| 313 | /* we should be verifying the device is ready to be opened */ | 315 | /* we should be verifying the device is ready to be opened */ |
| 314 | mutex_lock(&priv->shrd->mutex); | 316 | mutex_lock(&priv->mutex); |
| 315 | ret = __iwl_up(priv); | 317 | ret = __iwl_up(priv); |
| 316 | mutex_unlock(&priv->shrd->mutex); | 318 | mutex_unlock(&priv->mutex); |
| 317 | if (ret) | 319 | if (ret) |
| 318 | return ret; | 320 | return ret; |
| 319 | 321 | ||
| 320 | IWL_DEBUG_INFO(priv, "Start UP work done.\n"); | 322 | IWL_DEBUG_INFO(priv, "Start UP work done.\n"); |
| 321 | 323 | ||
| 322 | /* Now we should be done, and the READY bit should be set. */ | 324 | /* Now we should be done, and the READY bit should be set. */ |
| 323 | if (WARN_ON(!test_bit(STATUS_READY, &priv->shrd->status))) | 325 | if (WARN_ON(!test_bit(STATUS_READY, &priv->status))) |
| 324 | ret = -EIO; | 326 | ret = -EIO; |
| 325 | 327 | ||
| 326 | iwlagn_led_enable(priv); | 328 | iwlagn_led_enable(priv); |
| @@ -341,9 +343,9 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw) | |||
| 341 | 343 | ||
| 342 | priv->is_open = 0; | 344 | priv->is_open = 0; |
| 343 | 345 | ||
| 344 | mutex_lock(&priv->shrd->mutex); | 346 | mutex_lock(&priv->mutex); |
| 345 | iwl_down(priv); | 347 | iwl_down(priv); |
| 346 | mutex_unlock(&priv->shrd->mutex); | 348 | mutex_unlock(&priv->mutex); |
| 347 | 349 | ||
| 348 | iwl_cancel_deferred_work(priv); | 350 | iwl_cancel_deferred_work(priv); |
| 349 | 351 | ||
| @@ -368,7 +370,7 @@ static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, | |||
| 368 | return; | 370 | return; |
| 369 | 371 | ||
| 370 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 372 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
| 371 | mutex_lock(&priv->shrd->mutex); | 373 | mutex_lock(&priv->mutex); |
| 372 | 374 | ||
| 373 | if (priv->contexts[IWL_RXON_CTX_BSS].vif != vif) | 375 | if (priv->contexts[IWL_RXON_CTX_BSS].vif != vif) |
| 374 | goto out; | 376 | goto out; |
| @@ -380,7 +382,7 @@ static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, | |||
| 380 | priv->have_rekey_data = true; | 382 | priv->have_rekey_data = true; |
| 381 | 383 | ||
| 382 | out: | 384 | out: |
| 383 | mutex_unlock(&priv->shrd->mutex); | 385 | mutex_unlock(&priv->mutex); |
| 384 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 386 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
| 385 | } | 387 | } |
| 386 | 388 | ||
| @@ -397,7 +399,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, | |||
| 397 | return -EINVAL; | 399 | return -EINVAL; |
| 398 | 400 | ||
| 399 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 401 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
| 400 | mutex_lock(&priv->shrd->mutex); | 402 | mutex_lock(&priv->mutex); |
| 401 | 403 | ||
| 402 | /* Don't attempt WoWLAN when not associated, tear down instead. */ | 404 | /* Don't attempt WoWLAN when not associated, tear down instead. */ |
| 403 | if (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION || | 405 | if (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION || |
| @@ -406,24 +408,22 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, | |||
| 406 | goto out; | 408 | goto out; |
| 407 | } | 409 | } |
| 408 | 410 | ||
| 409 | ret = iwlagn_suspend(priv, hw, wowlan); | 411 | ret = iwlagn_suspend(priv, wowlan); |
| 410 | if (ret) | 412 | if (ret) |
| 411 | goto error; | 413 | goto error; |
| 412 | 414 | ||
| 413 | device_set_wakeup_enable(trans(priv)->dev, true); | 415 | device_set_wakeup_enable(trans(priv)->dev, true); |
| 414 | 416 | ||
| 415 | /* Now let the ucode operate on its own */ | 417 | iwl_trans_wowlan_suspend(trans(priv)); |
| 416 | iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET, | ||
| 417 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | ||
| 418 | 418 | ||
| 419 | goto out; | 419 | goto out; |
| 420 | 420 | ||
| 421 | error: | 421 | error: |
| 422 | priv->shrd->wowlan = false; | 422 | priv->wowlan = false; |
| 423 | iwlagn_prepare_restart(priv); | 423 | iwlagn_prepare_restart(priv); |
| 424 | ieee80211_restart_hw(priv->hw); | 424 | ieee80211_restart_hw(priv->hw); |
| 425 | out: | 425 | out: |
| 426 | mutex_unlock(&priv->shrd->mutex); | 426 | mutex_unlock(&priv->mutex); |
| 427 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 427 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
| 428 | 428 | ||
| 429 | return ret; | 429 | return ret; |
| @@ -439,7 +439,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
| 439 | int ret = -EIO; | 439 | int ret = -EIO; |
| 440 | 440 | ||
| 441 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 441 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
| 442 | mutex_lock(&priv->shrd->mutex); | 442 | mutex_lock(&priv->mutex); |
| 443 | 443 | ||
| 444 | iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, | 444 | iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, |
| 445 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | 445 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); |
| @@ -448,7 +448,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
| 448 | if (iwlagn_hw_valid_rtc_data_addr(base)) { | 448 | if (iwlagn_hw_valid_rtc_data_addr(base)) { |
| 449 | spin_lock_irqsave(&trans(priv)->reg_lock, flags); | 449 | spin_lock_irqsave(&trans(priv)->reg_lock, flags); |
| 450 | ret = iwl_grab_nic_access_silent(trans(priv)); | 450 | ret = iwl_grab_nic_access_silent(trans(priv)); |
| 451 | if (ret == 0) { | 451 | if (likely(ret == 0)) { |
| 452 | iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, base); | 452 | iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, base); |
| 453 | status = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); | 453 | status = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
| 454 | iwl_release_nic_access(trans(priv)); | 454 | iwl_release_nic_access(trans(priv)); |
| @@ -457,17 +457,16 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
| 457 | 457 | ||
| 458 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 458 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
| 459 | if (ret == 0) { | 459 | if (ret == 0) { |
| 460 | struct iwl_nic *nic = nic(priv); | ||
| 461 | if (!priv->wowlan_sram) | 460 | if (!priv->wowlan_sram) |
| 462 | priv->wowlan_sram = | 461 | priv->wowlan_sram = |
| 463 | kzalloc(nic->fw.ucode_wowlan.data.len, | 462 | kzalloc(priv->fw->ucode_wowlan.data.len, |
| 464 | GFP_KERNEL); | 463 | GFP_KERNEL); |
| 465 | 464 | ||
| 466 | if (priv->wowlan_sram) | 465 | if (priv->wowlan_sram) |
| 467 | _iwl_read_targ_mem_words( | 466 | _iwl_read_targ_mem_words( |
| 468 | trans(priv), 0x800000, | 467 | trans(priv), 0x800000, |
| 469 | priv->wowlan_sram, | 468 | priv->wowlan_sram, |
| 470 | nic->fw.ucode_wowlan.data.len / 4); | 469 | priv->fw->ucode_wowlan.data.len / 4); |
| 471 | } | 470 | } |
| 472 | #endif | 471 | #endif |
| 473 | } | 472 | } |
| @@ -475,7 +474,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
| 475 | /* we'll clear ctx->vif during iwlagn_prepare_restart() */ | 474 | /* we'll clear ctx->vif during iwlagn_prepare_restart() */ |
| 476 | vif = ctx->vif; | 475 | vif = ctx->vif; |
| 477 | 476 | ||
| 478 | priv->shrd->wowlan = false; | 477 | priv->wowlan = false; |
| 479 | 478 | ||
| 480 | device_set_wakeup_enable(trans(priv)->dev, false); | 479 | device_set_wakeup_enable(trans(priv)->dev, false); |
| 481 | 480 | ||
| @@ -485,7 +484,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
| 485 | iwl_connection_init_rx_config(priv, ctx); | 484 | iwl_connection_init_rx_config(priv, ctx); |
| 486 | iwlagn_set_rxon_chain(priv, ctx); | 485 | iwlagn_set_rxon_chain(priv, ctx); |
| 487 | 486 | ||
| 488 | mutex_unlock(&priv->shrd->mutex); | 487 | mutex_unlock(&priv->mutex); |
| 489 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 488 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
| 490 | 489 | ||
| 491 | ieee80211_resume_disconnect(vif); | 490 | ieee80211_resume_disconnect(vif); |
| @@ -563,7 +562,7 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
| 563 | if (cmd == DISABLE_KEY && key->hw_key_idx == WEP_INVALID_OFFSET) | 562 | if (cmd == DISABLE_KEY && key->hw_key_idx == WEP_INVALID_OFFSET) |
| 564 | return 0; | 563 | return 0; |
| 565 | 564 | ||
| 566 | mutex_lock(&priv->shrd->mutex); | 565 | mutex_lock(&priv->mutex); |
| 567 | iwl_scan_cancel_timeout(priv, 100); | 566 | iwl_scan_cancel_timeout(priv, 100); |
| 568 | 567 | ||
| 569 | BUILD_BUG_ON(WEP_INVALID_OFFSET == IWLAGN_HW_KEY_DEFAULT); | 568 | BUILD_BUG_ON(WEP_INVALID_OFFSET == IWLAGN_HW_KEY_DEFAULT); |
| @@ -614,7 +613,7 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
| 614 | ret = -EINVAL; | 613 | ret = -EINVAL; |
| 615 | } | 614 | } |
| 616 | 615 | ||
| 617 | mutex_unlock(&priv->shrd->mutex); | 616 | mutex_unlock(&priv->mutex); |
| 618 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 617 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
| 619 | 618 | ||
| 620 | return ret; | 619 | return ret; |
| @@ -633,11 +632,11 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
| 633 | IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", | 632 | IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", |
| 634 | sta->addr, tid); | 633 | sta->addr, tid); |
| 635 | 634 | ||
| 636 | if (!(cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE)) | 635 | if (!(hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE)) |
| 637 | return -EACCES; | 636 | return -EACCES; |
| 638 | 637 | ||
| 639 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 638 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
| 640 | mutex_lock(&priv->shrd->mutex); | 639 | mutex_lock(&priv->mutex); |
| 641 | 640 | ||
| 642 | switch (action) { | 641 | switch (action) { |
| 643 | case IEEE80211_AMPDU_RX_START: | 642 | case IEEE80211_AMPDU_RX_START: |
| @@ -649,8 +648,6 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
| 649 | case IEEE80211_AMPDU_RX_STOP: | 648 | case IEEE80211_AMPDU_RX_STOP: |
| 650 | IWL_DEBUG_HT(priv, "stop Rx\n"); | 649 | IWL_DEBUG_HT(priv, "stop Rx\n"); |
| 651 | ret = iwl_sta_rx_agg_stop(priv, sta, tid); | 650 | ret = iwl_sta_rx_agg_stop(priv, sta, tid); |
| 652 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | ||
| 653 | ret = 0; | ||
| 654 | break; | 651 | break; |
| 655 | case IEEE80211_AMPDU_TX_START: | 652 | case IEEE80211_AMPDU_TX_START: |
| 656 | if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) | 653 | if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) |
| @@ -666,10 +663,8 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
| 666 | IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n", | 663 | IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n", |
| 667 | priv->agg_tids_count); | 664 | priv->agg_tids_count); |
| 668 | } | 665 | } |
| 669 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 666 | if (!priv->agg_tids_count && |
| 670 | ret = 0; | 667 | hw_params(priv).use_rts_for_aggregation) { |
| 671 | if (!priv->agg_tids_count && cfg(priv)->ht_params && | ||
| 672 | cfg(priv)->ht_params->use_rts_for_aggregation) { | ||
| 673 | /* | 668 | /* |
| 674 | * switch off RTS/CTS if it was previously enabled | 669 | * switch off RTS/CTS if it was previously enabled |
| 675 | */ | 670 | */ |
| @@ -683,7 +678,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
| 683 | ret = iwlagn_tx_agg_oper(priv, vif, sta, tid, buf_size); | 678 | ret = iwlagn_tx_agg_oper(priv, vif, sta, tid, buf_size); |
| 684 | break; | 679 | break; |
| 685 | } | 680 | } |
| 686 | mutex_unlock(&priv->shrd->mutex); | 681 | mutex_unlock(&priv->mutex); |
| 687 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 682 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
| 688 | return ret; | 683 | return ret; |
| 689 | } | 684 | } |
| @@ -696,12 +691,9 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, | |||
| 696 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | 691 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; |
| 697 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | 692 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; |
| 698 | bool is_ap = vif->type == NL80211_IFTYPE_STATION; | 693 | bool is_ap = vif->type == NL80211_IFTYPE_STATION; |
| 699 | int ret = 0; | 694 | int ret; |
| 700 | u8 sta_id; | 695 | u8 sta_id; |
| 701 | 696 | ||
| 702 | IWL_DEBUG_MAC80211(priv, "received request to add station %pM\n", | ||
| 703 | sta->addr); | ||
| 704 | mutex_lock(&priv->shrd->mutex); | ||
| 705 | IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", | 697 | IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", |
| 706 | sta->addr); | 698 | sta->addr); |
| 707 | sta_priv->sta_id = IWL_INVALID_STATION; | 699 | sta_priv->sta_id = IWL_INVALID_STATION; |
| @@ -716,17 +708,119 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, | |||
| 716 | IWL_ERR(priv, "Unable to add station %pM (%d)\n", | 708 | IWL_ERR(priv, "Unable to add station %pM (%d)\n", |
| 717 | sta->addr, ret); | 709 | sta->addr, ret); |
| 718 | /* Should we return success if return code is EEXIST ? */ | 710 | /* Should we return success if return code is EEXIST ? */ |
| 719 | goto out; | 711 | return ret; |
| 720 | } | 712 | } |
| 721 | 713 | ||
| 722 | sta_priv->sta_id = sta_id; | 714 | sta_priv->sta_id = sta_id; |
| 723 | 715 | ||
| 724 | /* Initialize rate scaling */ | 716 | return 0; |
| 725 | IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", | 717 | } |
| 726 | sta->addr); | 718 | |
| 727 | iwl_rs_rate_init(priv, sta, sta_id); | 719 | static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, |
| 728 | out: | 720 | struct ieee80211_vif *vif, |
| 729 | mutex_unlock(&priv->shrd->mutex); | 721 | struct ieee80211_sta *sta) |
| 722 | { | ||
| 723 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | ||
| 724 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | ||
| 725 | int ret; | ||
| 726 | |||
| 727 | IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", sta->addr); | ||
| 728 | |||
| 729 | if (vif->type == NL80211_IFTYPE_STATION) { | ||
| 730 | /* | ||
| 731 | * Station will be removed from device when the RXON | ||
| 732 | * is set to unassociated -- just deactivate it here | ||
| 733 | * to avoid re-programming it. | ||
| 734 | */ | ||
| 735 | ret = 0; | ||
| 736 | iwl_deactivate_station(priv, sta_priv->sta_id, sta->addr); | ||
| 737 | } else { | ||
| 738 | ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr); | ||
| 739 | if (ret) | ||
| 740 | IWL_DEBUG_QUIET_RFKILL(priv, | ||
| 741 | "Error removing station %pM\n", sta->addr); | ||
| 742 | } | ||
| 743 | return ret; | ||
| 744 | } | ||
| 745 | |||
| 746 | static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, | ||
| 747 | struct ieee80211_vif *vif, | ||
| 748 | struct ieee80211_sta *sta, | ||
| 749 | enum ieee80211_sta_state old_state, | ||
| 750 | enum ieee80211_sta_state new_state) | ||
| 751 | { | ||
| 752 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | ||
| 753 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
| 754 | enum { | ||
| 755 | NONE, ADD, REMOVE, HT_RATE_INIT, ADD_RATE_INIT, | ||
| 756 | } op = NONE; | ||
| 757 | int ret; | ||
| 758 | |||
| 759 | IWL_DEBUG_MAC80211(priv, "station %pM state change %d->%d\n", | ||
| 760 | sta->addr, old_state, new_state); | ||
| 761 | |||
| 762 | mutex_lock(&priv->mutex); | ||
| 763 | if (vif->type == NL80211_IFTYPE_STATION) { | ||
| 764 | if (old_state == IEEE80211_STA_NOTEXIST && | ||
| 765 | new_state == IEEE80211_STA_NONE) | ||
| 766 | op = ADD; | ||
| 767 | else if (old_state == IEEE80211_STA_NONE && | ||
| 768 | new_state == IEEE80211_STA_NOTEXIST) | ||
| 769 | op = REMOVE; | ||
| 770 | else if (old_state == IEEE80211_STA_AUTH && | ||
| 771 | new_state == IEEE80211_STA_ASSOC) | ||
| 772 | op = HT_RATE_INIT; | ||
| 773 | } else { | ||
| 774 | if (old_state == IEEE80211_STA_AUTH && | ||
| 775 | new_state == IEEE80211_STA_ASSOC) | ||
| 776 | op = ADD_RATE_INIT; | ||
| 777 | else if (old_state == IEEE80211_STA_ASSOC && | ||
| 778 | new_state == IEEE80211_STA_AUTH) | ||
| 779 | op = REMOVE; | ||
| 780 | } | ||
| 781 | |||
| 782 | switch (op) { | ||
| 783 | case ADD: | ||
| 784 | ret = iwlagn_mac_sta_add(hw, vif, sta); | ||
| 785 | break; | ||
| 786 | case REMOVE: | ||
| 787 | ret = iwlagn_mac_sta_remove(hw, vif, sta); | ||
| 788 | break; | ||
| 789 | case ADD_RATE_INIT: | ||
| 790 | ret = iwlagn_mac_sta_add(hw, vif, sta); | ||
| 791 | if (ret) | ||
| 792 | break; | ||
| 793 | /* Initialize rate scaling */ | ||
| 794 | IWL_DEBUG_INFO(priv, | ||
| 795 | "Initializing rate scaling for station %pM\n", | ||
| 796 | sta->addr); | ||
| 797 | iwl_rs_rate_init(priv, sta, iwl_sta_id(sta)); | ||
| 798 | ret = 0; | ||
| 799 | break; | ||
| 800 | case HT_RATE_INIT: | ||
| 801 | /* Initialize rate scaling */ | ||
| 802 | ret = iwl_sta_update_ht(priv, vif_priv->ctx, sta); | ||
| 803 | if (ret) | ||
| 804 | break; | ||
| 805 | IWL_DEBUG_INFO(priv, | ||
| 806 | "Initializing rate scaling for station %pM\n", | ||
| 807 | sta->addr); | ||
| 808 | iwl_rs_rate_init(priv, sta, iwl_sta_id(sta)); | ||
| 809 | ret = 0; | ||
| 810 | break; | ||
| 811 | default: | ||
| 812 | ret = 0; | ||
| 813 | break; | ||
| 814 | } | ||
| 815 | |||
| 816 | /* | ||
| 817 | * mac80211 might WARN if we fail, but due the way we | ||
| 818 | * (badly) handle hard rfkill, we might fail here | ||
| 819 | */ | ||
| 820 | if (iwl_is_rfkill(priv)) | ||
| 821 | ret = 0; | ||
| 822 | |||
| 823 | mutex_unlock(&priv->mutex); | ||
| 730 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 824 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
| 731 | 825 | ||
| 732 | return ret; | 826 | return ret; |
| @@ -753,14 +847,14 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
| 753 | 847 | ||
| 754 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 848 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
| 755 | 849 | ||
| 756 | mutex_lock(&priv->shrd->mutex); | 850 | mutex_lock(&priv->mutex); |
| 757 | 851 | ||
| 758 | if (iwl_is_rfkill(priv->shrd)) | 852 | if (iwl_is_rfkill(priv)) |
| 759 | goto out; | 853 | goto out; |
| 760 | 854 | ||
| 761 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) || | 855 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || |
| 762 | test_bit(STATUS_SCANNING, &priv->shrd->status) || | 856 | test_bit(STATUS_SCANNING, &priv->status) || |
| 763 | test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status)) | 857 | test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) |
| 764 | goto out; | 858 | goto out; |
| 765 | 859 | ||
| 766 | if (!iwl_is_associated_ctx(ctx)) | 860 | if (!iwl_is_associated_ctx(ctx)) |
| @@ -779,8 +873,6 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
| 779 | goto out; | 873 | goto out; |
| 780 | } | 874 | } |
| 781 | 875 | ||
| 782 | spin_lock_irq(&priv->shrd->lock); | ||
| 783 | |||
| 784 | priv->current_ht_config.smps = conf->smps_mode; | 876 | priv->current_ht_config.smps = conf->smps_mode; |
| 785 | 877 | ||
| 786 | /* Configure HT40 channels */ | 878 | /* Configure HT40 channels */ |
| @@ -797,23 +889,21 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
| 797 | iwl_set_rxon_ht(priv, ht_conf); | 889 | iwl_set_rxon_ht(priv, ht_conf); |
| 798 | iwl_set_flags_for_band(priv, ctx, channel->band, ctx->vif); | 890 | iwl_set_flags_for_band(priv, ctx, channel->band, ctx->vif); |
| 799 | 891 | ||
| 800 | spin_unlock_irq(&priv->shrd->lock); | ||
| 801 | |||
| 802 | iwl_set_rate(priv); | 892 | iwl_set_rate(priv); |
| 803 | /* | 893 | /* |
| 804 | * at this point, staging_rxon has the | 894 | * at this point, staging_rxon has the |
| 805 | * configuration for channel switch | 895 | * configuration for channel switch |
| 806 | */ | 896 | */ |
| 807 | set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); | 897 | set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); |
| 808 | priv->switch_channel = cpu_to_le16(ch); | 898 | priv->switch_channel = cpu_to_le16(ch); |
| 809 | if (cfg(priv)->lib->set_channel_switch(priv, ch_switch)) { | 899 | if (cfg(priv)->lib->set_channel_switch(priv, ch_switch)) { |
| 810 | clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); | 900 | clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); |
| 811 | priv->switch_channel = 0; | 901 | priv->switch_channel = 0; |
| 812 | ieee80211_chswitch_done(ctx->vif, false); | 902 | ieee80211_chswitch_done(ctx->vif, false); |
| 813 | } | 903 | } |
| 814 | 904 | ||
| 815 | out: | 905 | out: |
| 816 | mutex_unlock(&priv->shrd->mutex); | 906 | mutex_unlock(&priv->mutex); |
| 817 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 907 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
| 818 | } | 908 | } |
| 819 | 909 | ||
| @@ -843,7 +933,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, | |||
| 843 | 933 | ||
| 844 | #undef CHK | 934 | #undef CHK |
| 845 | 935 | ||
| 846 | mutex_lock(&priv->shrd->mutex); | 936 | mutex_lock(&priv->mutex); |
| 847 | 937 | ||
| 848 | for_each_context(priv, ctx) { | 938 | for_each_context(priv, ctx) { |
| 849 | ctx->staging.filter_flags &= ~filter_nand; | 939 | ctx->staging.filter_flags &= ~filter_nand; |
| @@ -855,7 +945,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, | |||
| 855 | */ | 945 | */ |
| 856 | } | 946 | } |
| 857 | 947 | ||
| 858 | mutex_unlock(&priv->shrd->mutex); | 948 | mutex_unlock(&priv->mutex); |
| 859 | 949 | ||
| 860 | /* | 950 | /* |
| 861 | * Receiving all multicast frames is always enabled by the | 951 | * Receiving all multicast frames is always enabled by the |
| @@ -871,14 +961,14 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) | |||
| 871 | { | 961 | { |
| 872 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 962 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
| 873 | 963 | ||
| 874 | mutex_lock(&priv->shrd->mutex); | 964 | mutex_lock(&priv->mutex); |
| 875 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 965 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
| 876 | 966 | ||
| 877 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { | 967 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
| 878 | IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n"); | 968 | IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n"); |
| 879 | goto done; | 969 | goto done; |
| 880 | } | 970 | } |
| 881 | if (iwl_is_rfkill(priv->shrd)) { | 971 | if (iwl_is_rfkill(priv)) { |
| 882 | IWL_DEBUG_TX(priv, "Aborting flush due to RF Kill\n"); | 972 | IWL_DEBUG_TX(priv, "Aborting flush due to RF Kill\n"); |
| 883 | goto done; | 973 | goto done; |
| 884 | } | 974 | } |
| @@ -897,7 +987,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) | |||
| 897 | IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n"); | 987 | IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n"); |
| 898 | iwl_trans_wait_tx_queue_empty(trans(priv)); | 988 | iwl_trans_wait_tx_queue_empty(trans(priv)); |
| 899 | done: | 989 | done: |
| 900 | mutex_unlock(&priv->shrd->mutex); | 990 | mutex_unlock(&priv->mutex); |
| 901 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 991 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
| 902 | } | 992 | } |
| 903 | 993 | ||
| @@ -917,9 +1007,9 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, | |||
| 917 | return -EOPNOTSUPP; | 1007 | return -EOPNOTSUPP; |
| 918 | 1008 | ||
| 919 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 1009 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
| 920 | mutex_lock(&priv->shrd->mutex); | 1010 | mutex_lock(&priv->mutex); |
| 921 | 1011 | ||
| 922 | if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { | 1012 | if (test_bit(STATUS_SCAN_HW, &priv->status)) { |
| 923 | err = -EBUSY; | 1013 | err = -EBUSY; |
| 924 | goto out; | 1014 | goto out; |
| 925 | } | 1015 | } |
| @@ -988,7 +1078,7 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, | |||
| 988 | iwlagn_disable_roc(priv); | 1078 | iwlagn_disable_roc(priv); |
| 989 | 1079 | ||
| 990 | out: | 1080 | out: |
| 991 | mutex_unlock(&priv->shrd->mutex); | 1081 | mutex_unlock(&priv->mutex); |
| 992 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1082 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
| 993 | 1083 | ||
| 994 | return err; | 1084 | return err; |
| @@ -1002,102 +1092,22 @@ static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) | |||
| 1002 | return -EOPNOTSUPP; | 1092 | return -EOPNOTSUPP; |
| 1003 | 1093 | ||
| 1004 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 1094 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
| 1005 | mutex_lock(&priv->shrd->mutex); | 1095 | mutex_lock(&priv->mutex); |
| 1006 | iwl_scan_cancel_timeout(priv, priv->hw_roc_duration); | 1096 | iwl_scan_cancel_timeout(priv, priv->hw_roc_duration); |
| 1007 | iwlagn_disable_roc(priv); | 1097 | iwlagn_disable_roc(priv); |
| 1008 | mutex_unlock(&priv->shrd->mutex); | 1098 | mutex_unlock(&priv->mutex); |
| 1009 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1099 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
| 1010 | 1100 | ||
| 1011 | return 0; | 1101 | return 0; |
| 1012 | } | 1102 | } |
| 1013 | 1103 | ||
| 1014 | static int iwlagn_mac_tx_sync(struct ieee80211_hw *hw, | ||
| 1015 | struct ieee80211_vif *vif, | ||
| 1016 | const u8 *bssid, | ||
| 1017 | enum ieee80211_tx_sync_type type) | ||
| 1018 | { | ||
| 1019 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | ||
| 1020 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
| 1021 | struct iwl_rxon_context *ctx = vif_priv->ctx; | ||
| 1022 | int ret; | ||
| 1023 | u8 sta_id; | ||
| 1024 | |||
| 1025 | if (ctx->ctxid != IWL_RXON_CTX_PAN) | ||
| 1026 | return 0; | ||
| 1027 | |||
| 1028 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
| 1029 | mutex_lock(&priv->shrd->mutex); | ||
| 1030 | |||
| 1031 | if (iwl_is_associated_ctx(ctx)) { | ||
| 1032 | ret = 0; | ||
| 1033 | goto out; | ||
| 1034 | } | ||
| 1035 | |||
| 1036 | if (ctx->preauth_bssid || test_bit(STATUS_SCAN_HW, | ||
| 1037 | &priv->shrd->status)) { | ||
| 1038 | ret = -EBUSY; | ||
| 1039 | goto out; | ||
| 1040 | } | ||
| 1041 | |||
| 1042 | ret = iwl_add_station_common(priv, ctx, bssid, true, NULL, &sta_id); | ||
| 1043 | if (ret) | ||
| 1044 | goto out; | ||
| 1045 | |||
| 1046 | if (WARN_ON(sta_id != ctx->ap_sta_id)) { | ||
| 1047 | ret = -EIO; | ||
| 1048 | goto out_remove_sta; | ||
| 1049 | } | ||
| 1050 | |||
| 1051 | memcpy(ctx->bssid, bssid, ETH_ALEN); | ||
| 1052 | ctx->preauth_bssid = true; | ||
| 1053 | |||
| 1054 | ret = iwlagn_commit_rxon(priv, ctx); | ||
| 1055 | |||
| 1056 | if (ret == 0) | ||
| 1057 | goto out; | ||
| 1058 | |||
| 1059 | out_remove_sta: | ||
| 1060 | iwl_remove_station(priv, sta_id, bssid); | ||
| 1061 | out: | ||
| 1062 | mutex_unlock(&priv->shrd->mutex); | ||
| 1063 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
| 1064 | |||
| 1065 | return ret; | ||
| 1066 | } | ||
| 1067 | |||
| 1068 | static void iwlagn_mac_finish_tx_sync(struct ieee80211_hw *hw, | ||
| 1069 | struct ieee80211_vif *vif, | ||
| 1070 | const u8 *bssid, | ||
| 1071 | enum ieee80211_tx_sync_type type) | ||
| 1072 | { | ||
| 1073 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | ||
| 1074 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
| 1075 | struct iwl_rxon_context *ctx = vif_priv->ctx; | ||
| 1076 | |||
| 1077 | if (ctx->ctxid != IWL_RXON_CTX_PAN) | ||
| 1078 | return; | ||
| 1079 | |||
| 1080 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
| 1081 | mutex_lock(&priv->shrd->mutex); | ||
| 1082 | |||
| 1083 | if (iwl_is_associated_ctx(ctx)) | ||
| 1084 | goto out; | ||
| 1085 | |||
| 1086 | iwl_remove_station(priv, ctx->ap_sta_id, bssid); | ||
| 1087 | ctx->preauth_bssid = false; | ||
| 1088 | /* no need to commit */ | ||
| 1089 | out: | ||
| 1090 | mutex_unlock(&priv->shrd->mutex); | ||
| 1091 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
| 1092 | } | ||
| 1093 | |||
| 1094 | static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, | 1104 | static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, |
| 1095 | enum ieee80211_rssi_event rssi_event) | 1105 | enum ieee80211_rssi_event rssi_event) |
| 1096 | { | 1106 | { |
| 1097 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1107 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
| 1098 | 1108 | ||
| 1099 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 1109 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
| 1100 | mutex_lock(&priv->shrd->mutex); | 1110 | mutex_lock(&priv->mutex); |
| 1101 | 1111 | ||
| 1102 | if (cfg(priv)->bt_params && | 1112 | if (cfg(priv)->bt_params && |
| 1103 | cfg(priv)->bt_params->advanced_bt_coexist) { | 1113 | cfg(priv)->bt_params->advanced_bt_coexist) { |
| @@ -1112,7 +1122,7 @@ static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, | |||
| 1112 | "ignoring RSSI callback\n"); | 1122 | "ignoring RSSI callback\n"); |
| 1113 | } | 1123 | } |
| 1114 | 1124 | ||
| 1115 | mutex_unlock(&priv->shrd->mutex); | 1125 | mutex_unlock(&priv->mutex); |
| 1116 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1126 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
| 1117 | } | 1127 | } |
| 1118 | 1128 | ||
| @@ -1133,7 +1143,6 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | |||
| 1133 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1143 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
| 1134 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | 1144 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; |
| 1135 | struct iwl_rxon_context *ctx = vif_priv->ctx; | 1145 | struct iwl_rxon_context *ctx = vif_priv->ctx; |
| 1136 | unsigned long flags; | ||
| 1137 | int q; | 1146 | int q; |
| 1138 | 1147 | ||
| 1139 | if (WARN_ON(!ctx)) | 1148 | if (WARN_ON(!ctx)) |
| @@ -1141,7 +1150,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | |||
| 1141 | 1150 | ||
| 1142 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 1151 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
| 1143 | 1152 | ||
| 1144 | if (!iwl_is_ready_rf(priv->shrd)) { | 1153 | if (!iwl_is_ready_rf(priv)) { |
| 1145 | IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); | 1154 | IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); |
| 1146 | return -EIO; | 1155 | return -EIO; |
| 1147 | } | 1156 | } |
| @@ -1153,7 +1162,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | |||
| 1153 | 1162 | ||
| 1154 | q = AC_NUM - 1 - queue; | 1163 | q = AC_NUM - 1 - queue; |
| 1155 | 1164 | ||
| 1156 | spin_lock_irqsave(&priv->shrd->lock, flags); | 1165 | mutex_lock(&priv->mutex); |
| 1157 | 1166 | ||
| 1158 | ctx->qos_data.def_qos_parm.ac[q].cw_min = | 1167 | ctx->qos_data.def_qos_parm.ac[q].cw_min = |
| 1159 | cpu_to_le16(params->cw_min); | 1168 | cpu_to_le16(params->cw_min); |
| @@ -1165,7 +1174,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | |||
| 1165 | 1174 | ||
| 1166 | ctx->qos_data.def_qos_parm.ac[q].reserved1 = 0; | 1175 | ctx->qos_data.def_qos_parm.ac[q].reserved1 = 0; |
| 1167 | 1176 | ||
| 1168 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | 1177 | mutex_unlock(&priv->mutex); |
| 1169 | 1178 | ||
| 1170 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1179 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
| 1171 | return 0; | 1180 | return 0; |
| @@ -1193,7 +1202,7 @@ static int iwl_setup_interface(struct iwl_priv *priv, | |||
| 1193 | struct ieee80211_vif *vif = ctx->vif; | 1202 | struct ieee80211_vif *vif = ctx->vif; |
| 1194 | int err; | 1203 | int err; |
| 1195 | 1204 | ||
| 1196 | lockdep_assert_held(&priv->shrd->mutex); | 1205 | lockdep_assert_held(&priv->mutex); |
| 1197 | 1206 | ||
| 1198 | /* | 1207 | /* |
| 1199 | * This variable will be correct only when there's just | 1208 | * This variable will be correct only when there's just |
| @@ -1238,11 +1247,11 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, | |||
| 1238 | 1247 | ||
| 1239 | cancel_delayed_work_sync(&priv->hw_roc_disable_work); | 1248 | cancel_delayed_work_sync(&priv->hw_roc_disable_work); |
| 1240 | 1249 | ||
| 1241 | mutex_lock(&priv->shrd->mutex); | 1250 | mutex_lock(&priv->mutex); |
| 1242 | 1251 | ||
| 1243 | iwlagn_disable_roc(priv); | 1252 | iwlagn_disable_roc(priv); |
| 1244 | 1253 | ||
| 1245 | if (!iwl_is_ready_rf(priv->shrd)) { | 1254 | if (!iwl_is_ready_rf(priv)) { |
| 1246 | IWL_WARN(priv, "Try to add interface when device not ready\n"); | 1255 | IWL_WARN(priv, "Try to add interface when device not ready\n"); |
| 1247 | err = -EINVAL; | 1256 | err = -EINVAL; |
| 1248 | goto out; | 1257 | goto out; |
| @@ -1285,7 +1294,7 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, | |||
| 1285 | ctx->vif = NULL; | 1294 | ctx->vif = NULL; |
| 1286 | priv->iw_mode = NL80211_IFTYPE_STATION; | 1295 | priv->iw_mode = NL80211_IFTYPE_STATION; |
| 1287 | out: | 1296 | out: |
| 1288 | mutex_unlock(&priv->shrd->mutex); | 1297 | mutex_unlock(&priv->mutex); |
| 1289 | 1298 | ||
| 1290 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1299 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
| 1291 | return err; | 1300 | return err; |
| @@ -1297,7 +1306,7 @@ static void iwl_teardown_interface(struct iwl_priv *priv, | |||
| 1297 | { | 1306 | { |
| 1298 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | 1307 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); |
| 1299 | 1308 | ||
| 1300 | lockdep_assert_held(&priv->shrd->mutex); | 1309 | lockdep_assert_held(&priv->mutex); |
| 1301 | 1310 | ||
| 1302 | if (priv->scan_vif == vif) { | 1311 | if (priv->scan_vif == vif) { |
| 1303 | iwl_scan_cancel_timeout(priv, 200); | 1312 | iwl_scan_cancel_timeout(priv, 200); |
| @@ -1329,7 +1338,7 @@ static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw, | |||
| 1329 | 1338 | ||
| 1330 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 1339 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
| 1331 | 1340 | ||
| 1332 | mutex_lock(&priv->shrd->mutex); | 1341 | mutex_lock(&priv->mutex); |
| 1333 | 1342 | ||
| 1334 | if (WARN_ON(ctx->vif != vif)) { | 1343 | if (WARN_ON(ctx->vif != vif)) { |
| 1335 | struct iwl_rxon_context *tmp; | 1344 | struct iwl_rxon_context *tmp; |
| @@ -1342,7 +1351,7 @@ static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw, | |||
| 1342 | 1351 | ||
| 1343 | iwl_teardown_interface(priv, vif, false); | 1352 | iwl_teardown_interface(priv, vif, false); |
| 1344 | 1353 | ||
| 1345 | mutex_unlock(&priv->shrd->mutex); | 1354 | mutex_unlock(&priv->mutex); |
| 1346 | 1355 | ||
| 1347 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1356 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
| 1348 | 1357 | ||
| @@ -1364,9 +1373,9 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw, | |||
| 1364 | 1373 | ||
| 1365 | newtype = ieee80211_iftype_p2p(newtype, newp2p); | 1374 | newtype = ieee80211_iftype_p2p(newtype, newp2p); |
| 1366 | 1375 | ||
| 1367 | mutex_lock(&priv->shrd->mutex); | 1376 | mutex_lock(&priv->mutex); |
| 1368 | 1377 | ||
| 1369 | if (!ctx->vif || !iwl_is_ready_rf(priv->shrd)) { | 1378 | if (!ctx->vif || !iwl_is_ready_rf(priv)) { |
| 1370 | /* | 1379 | /* |
| 1371 | * Huh? But wait ... this can maybe happen when | 1380 | * Huh? But wait ... this can maybe happen when |
| 1372 | * we're in the middle of a firmware restart! | 1381 | * we're in the middle of a firmware restart! |
| @@ -1428,7 +1437,7 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw, | |||
| 1428 | err = 0; | 1437 | err = 0; |
| 1429 | 1438 | ||
| 1430 | out: | 1439 | out: |
| 1431 | mutex_unlock(&priv->shrd->mutex); | 1440 | mutex_unlock(&priv->mutex); |
| 1432 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1441 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
| 1433 | 1442 | ||
| 1434 | return err; | 1443 | return err; |
| @@ -1446,7 +1455,7 @@ static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, | |||
| 1446 | if (req->n_channels == 0) | 1455 | if (req->n_channels == 0) |
| 1447 | return -EINVAL; | 1456 | return -EINVAL; |
| 1448 | 1457 | ||
| 1449 | mutex_lock(&priv->shrd->mutex); | 1458 | mutex_lock(&priv->mutex); |
| 1450 | 1459 | ||
| 1451 | /* | 1460 | /* |
| 1452 | * If an internal scan is in progress, just set | 1461 | * If an internal scan is in progress, just set |
| @@ -1475,47 +1484,20 @@ static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, | |||
| 1475 | 1484 | ||
| 1476 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1485 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
| 1477 | 1486 | ||
| 1478 | mutex_unlock(&priv->shrd->mutex); | 1487 | mutex_unlock(&priv->mutex); |
| 1479 | |||
| 1480 | return ret; | ||
| 1481 | } | ||
| 1482 | |||
| 1483 | static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, | ||
| 1484 | struct ieee80211_vif *vif, | ||
| 1485 | struct ieee80211_sta *sta) | ||
| 1486 | { | ||
| 1487 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | ||
| 1488 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | ||
| 1489 | int ret; | ||
| 1490 | |||
| 1491 | IWL_DEBUG_MAC80211(priv, "enter: received request to remove " | ||
| 1492 | "station %pM\n", sta->addr); | ||
| 1493 | mutex_lock(&priv->shrd->mutex); | ||
| 1494 | IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", | ||
| 1495 | sta->addr); | ||
| 1496 | ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr); | ||
| 1497 | if (ret) | ||
| 1498 | IWL_DEBUG_QUIET_RFKILL(priv, "Error removing station %pM\n", | ||
| 1499 | sta->addr); | ||
| 1500 | mutex_unlock(&priv->shrd->mutex); | ||
| 1501 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
| 1502 | 1488 | ||
| 1503 | return ret; | 1489 | return ret; |
| 1504 | } | 1490 | } |
| 1505 | 1491 | ||
| 1506 | static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) | 1492 | static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) |
| 1507 | { | 1493 | { |
| 1508 | unsigned long flags; | 1494 | struct iwl_addsta_cmd cmd = { |
| 1509 | 1495 | .mode = STA_CONTROL_MODIFY_MSK, | |
| 1510 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1496 | .station_flags_msk = STA_FLG_PWR_SAVE_MSK, |
| 1511 | priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK; | 1497 | .sta.sta_id = sta_id, |
| 1512 | priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; | 1498 | }; |
| 1513 | priv->stations[sta_id].sta.sta.modify_mask = 0; | ||
| 1514 | priv->stations[sta_id].sta.sleep_tx_count = 0; | ||
| 1515 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | ||
| 1516 | iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | ||
| 1517 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
| 1518 | 1499 | ||
| 1500 | iwl_send_add_sta(priv, &cmd, CMD_ASYNC); | ||
| 1519 | } | 1501 | } |
| 1520 | 1502 | ||
| 1521 | static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, | 1503 | static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, |
| @@ -1572,8 +1554,7 @@ struct ieee80211_ops iwlagn_hw_ops = { | |||
| 1572 | .ampdu_action = iwlagn_mac_ampdu_action, | 1554 | .ampdu_action = iwlagn_mac_ampdu_action, |
| 1573 | .hw_scan = iwlagn_mac_hw_scan, | 1555 | .hw_scan = iwlagn_mac_hw_scan, |
| 1574 | .sta_notify = iwlagn_mac_sta_notify, | 1556 | .sta_notify = iwlagn_mac_sta_notify, |
| 1575 | .sta_add = iwlagn_mac_sta_add, | 1557 | .sta_state = iwlagn_mac_sta_state, |
| 1576 | .sta_remove = iwlagn_mac_sta_remove, | ||
| 1577 | .channel_switch = iwlagn_mac_channel_switch, | 1558 | .channel_switch = iwlagn_mac_channel_switch, |
| 1578 | .flush = iwlagn_mac_flush, | 1559 | .flush = iwlagn_mac_flush, |
| 1579 | .tx_last_beacon = iwlagn_mac_tx_last_beacon, | 1560 | .tx_last_beacon = iwlagn_mac_tx_last_beacon, |
| @@ -1582,8 +1563,6 @@ struct ieee80211_ops iwlagn_hw_ops = { | |||
| 1582 | .rssi_callback = iwlagn_mac_rssi_callback, | 1563 | .rssi_callback = iwlagn_mac_rssi_callback, |
| 1583 | CFG80211_TESTMODE_CMD(iwlagn_mac_testmode_cmd) | 1564 | CFG80211_TESTMODE_CMD(iwlagn_mac_testmode_cmd) |
| 1584 | CFG80211_TESTMODE_DUMP(iwlagn_mac_testmode_dump) | 1565 | CFG80211_TESTMODE_DUMP(iwlagn_mac_testmode_dump) |
| 1585 | .tx_sync = iwlagn_mac_tx_sync, | ||
| 1586 | .finish_tx_sync = iwlagn_mac_finish_tx_sync, | ||
| 1587 | .set_tim = iwlagn_mac_set_tim, | 1566 | .set_tim = iwlagn_mac_set_tim, |
| 1588 | }; | 1567 | }; |
| 1589 | 1568 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c new file mode 100644 index 000000000000..88dc4a0f96b4 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c | |||
| @@ -0,0 +1,157 @@ | |||
| 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) 2007 - 2012 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 - 2012 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 | #include <linux/sched.h> | ||
| 64 | |||
| 65 | #include "iwl-notif-wait.h" | ||
| 66 | |||
| 67 | |||
| 68 | void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_wait) | ||
| 69 | { | ||
| 70 | spin_lock_init(¬if_wait->notif_wait_lock); | ||
| 71 | INIT_LIST_HEAD(¬if_wait->notif_waits); | ||
| 72 | init_waitqueue_head(¬if_wait->notif_waitq); | ||
| 73 | } | ||
| 74 | |||
| 75 | void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait, | ||
| 76 | struct iwl_rx_packet *pkt) | ||
| 77 | { | ||
| 78 | if (!list_empty(¬if_wait->notif_waits)) { | ||
| 79 | struct iwl_notification_wait *w; | ||
| 80 | |||
| 81 | spin_lock(¬if_wait->notif_wait_lock); | ||
| 82 | list_for_each_entry(w, ¬if_wait->notif_waits, list) { | ||
| 83 | if (w->cmd != pkt->hdr.cmd) | ||
| 84 | continue; | ||
| 85 | w->triggered = true; | ||
| 86 | if (w->fn) | ||
| 87 | w->fn(notif_wait, pkt, w->fn_data); | ||
| 88 | } | ||
| 89 | spin_unlock(¬if_wait->notif_wait_lock); | ||
| 90 | |||
| 91 | wake_up_all(¬if_wait->notif_waitq); | ||
| 92 | } | ||
| 93 | } | ||
| 94 | |||
| 95 | void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait) | ||
| 96 | { | ||
| 97 | unsigned long flags; | ||
| 98 | struct iwl_notification_wait *wait_entry; | ||
| 99 | |||
| 100 | spin_lock_irqsave(¬if_wait->notif_wait_lock, flags); | ||
| 101 | list_for_each_entry(wait_entry, ¬if_wait->notif_waits, list) | ||
| 102 | wait_entry->aborted = true; | ||
| 103 | spin_unlock_irqrestore(¬if_wait->notif_wait_lock, flags); | ||
| 104 | |||
| 105 | wake_up_all(¬if_wait->notif_waitq); | ||
| 106 | } | ||
| 107 | |||
| 108 | |||
| 109 | void | ||
| 110 | iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait, | ||
| 111 | struct iwl_notification_wait *wait_entry, | ||
| 112 | u8 cmd, | ||
| 113 | void (*fn)(struct iwl_notif_wait_data *notif_wait, | ||
| 114 | struct iwl_rx_packet *pkt, void *data), | ||
| 115 | void *fn_data) | ||
| 116 | { | ||
| 117 | wait_entry->fn = fn; | ||
| 118 | wait_entry->fn_data = fn_data; | ||
| 119 | wait_entry->cmd = cmd; | ||
| 120 | wait_entry->triggered = false; | ||
| 121 | wait_entry->aborted = false; | ||
| 122 | |||
| 123 | spin_lock_bh(¬if_wait->notif_wait_lock); | ||
| 124 | list_add(&wait_entry->list, ¬if_wait->notif_waits); | ||
| 125 | spin_unlock_bh(¬if_wait->notif_wait_lock); | ||
| 126 | } | ||
| 127 | |||
| 128 | int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, | ||
| 129 | struct iwl_notification_wait *wait_entry, | ||
| 130 | unsigned long timeout) | ||
| 131 | { | ||
| 132 | int ret; | ||
| 133 | |||
| 134 | ret = wait_event_timeout(notif_wait->notif_waitq, | ||
| 135 | wait_entry->triggered || wait_entry->aborted, | ||
| 136 | timeout); | ||
| 137 | |||
| 138 | spin_lock_bh(¬if_wait->notif_wait_lock); | ||
| 139 | list_del(&wait_entry->list); | ||
| 140 | spin_unlock_bh(¬if_wait->notif_wait_lock); | ||
| 141 | |||
| 142 | if (wait_entry->aborted) | ||
| 143 | return -EIO; | ||
| 144 | |||
| 145 | /* return value is always >= 0 */ | ||
| 146 | if (ret <= 0) | ||
| 147 | return -ETIMEDOUT; | ||
| 148 | return 0; | ||
| 149 | } | ||
| 150 | |||
| 151 | void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait, | ||
| 152 | struct iwl_notification_wait *wait_entry) | ||
| 153 | { | ||
| 154 | spin_lock_bh(¬if_wait->notif_wait_lock); | ||
| 155 | list_del(&wait_entry->list); | ||
| 156 | spin_unlock_bh(¬if_wait->notif_wait_lock); | ||
| 157 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h index 506c062343b2..5e8af957aa7b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h | |||
| @@ -41,7 +41,6 @@ | |||
| 41 | * notice, this list of conditions and the following disclaimer. | 41 | * notice, this list of conditions and the following disclaimer. |
| 42 | * * Redistributions in binary form must reproduce the above copyright | 42 | * * Redistributions in binary form must reproduce the above copyright |
| 43 | * notice, this list of conditions and the following disclaimer in | 43 | * notice, this list of conditions and the following disclaimer in |
| 44 | * the documentation and/or other materials provided with the | ||
| 45 | * distribution. | 44 | * distribution. |
| 46 | * * Neither the name Intel Corporation nor the names of its | 45 | * * Neither the name Intel Corporation nor the names of its |
| 47 | * contributors may be used to endorse or promote products derived | 46 | * contributors may be used to endorse or promote products derived |
| @@ -60,18 +59,71 @@ | |||
| 60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 59 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 61 | * | 60 | * |
| 62 | *****************************************************************************/ | 61 | *****************************************************************************/ |
| 62 | #ifndef __iwl_notif_wait_h__ | ||
| 63 | #define __iwl_notif_wait_h__ | ||
| 64 | |||
| 65 | #include <linux/wait.h> | ||
| 63 | 66 | ||
| 64 | #include "iwl-trans.h" | 67 | #include "iwl-trans.h" |
| 65 | 68 | ||
| 66 | int iwl_trans_send_cmd_pdu(struct iwl_trans *trans, u8 id, | 69 | struct iwl_notif_wait_data { |
| 67 | u32 flags, u16 len, const void *data) | 70 | struct list_head notif_waits; |
| 68 | { | 71 | spinlock_t notif_wait_lock; |
| 69 | struct iwl_host_cmd cmd = { | 72 | wait_queue_head_t notif_waitq; |
| 70 | .id = id, | 73 | }; |
| 71 | .len = { len, }, | 74 | |
| 72 | .data = { data, }, | 75 | /** |
| 73 | .flags = flags, | 76 | * struct iwl_notification_wait - notification wait entry |
| 74 | }; | 77 | * @list: list head for global list |
| 78 | * @fn: function called with the notification | ||
| 79 | * @cmd: command ID | ||
| 80 | * | ||
| 81 | * This structure is not used directly, to wait for a | ||
| 82 | * notification declare it on the stack, and call | ||
| 83 | * iwlagn_init_notification_wait() with appropriate | ||
| 84 | * parameters. Then do whatever will cause the ucode | ||
| 85 | * to notify the driver, and to wait for that then | ||
| 86 | * call iwlagn_wait_notification(). | ||
| 87 | * | ||
| 88 | * Each notification is one-shot. If at some point we | ||
| 89 | * need to support multi-shot notifications (which | ||
| 90 | * can't be allocated on the stack) we need to modify | ||
| 91 | * the code for them. | ||
| 92 | */ | ||
| 93 | struct iwl_notification_wait { | ||
| 94 | struct list_head list; | ||
| 95 | |||
| 96 | void (*fn)(struct iwl_notif_wait_data *notif_data, | ||
| 97 | struct iwl_rx_packet *pkt, void *data); | ||
| 98 | void *fn_data; | ||
| 99 | |||
| 100 | u8 cmd; | ||
| 101 | bool triggered, aborted; | ||
| 102 | }; | ||
| 103 | |||
| 104 | |||
| 105 | /* caller functions */ | ||
| 106 | void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_data); | ||
| 107 | void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_data, | ||
| 108 | struct iwl_rx_packet *pkt); | ||
| 109 | void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_data); | ||
| 110 | |||
| 111 | /* user functions */ | ||
| 112 | void __acquires(wait_entry) | ||
| 113 | iwl_init_notification_wait(struct iwl_notif_wait_data *notif_data, | ||
| 114 | struct iwl_notification_wait *wait_entry, | ||
| 115 | u8 cmd, | ||
| 116 | void (*fn)(struct iwl_notif_wait_data *notif_data, | ||
| 117 | struct iwl_rx_packet *pkt, void *data), | ||
| 118 | void *fn_data); | ||
| 119 | |||
| 120 | int __must_check __releases(wait_entry) | ||
| 121 | iwl_wait_notification(struct iwl_notif_wait_data *notif_data, | ||
| 122 | struct iwl_notification_wait *wait_entry, | ||
| 123 | unsigned long timeout); | ||
| 124 | |||
| 125 | void __releases(wait_entry) | ||
| 126 | iwl_remove_notification(struct iwl_notif_wait_data *notif_data, | ||
| 127 | struct iwl_notification_wait *wait_entry); | ||
| 75 | 128 | ||
| 76 | return iwl_trans_send_cmd(trans, &cmd); | 129 | #endif /* __iwl_notif_wait_h__ */ |
| 77 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h index d4fc9be2d2f3..6ea4163ff56a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h | |||
| @@ -67,7 +67,8 @@ struct iwl_op_mode; | |||
| 67 | struct iwl_trans; | 67 | struct iwl_trans; |
| 68 | struct sk_buff; | 68 | struct sk_buff; |
| 69 | struct iwl_device_cmd; | 69 | struct iwl_device_cmd; |
| 70 | struct iwl_rx_mem_buffer; | 70 | struct iwl_rx_cmd_buffer; |
| 71 | struct iwl_fw; | ||
| 71 | 72 | ||
| 72 | /** | 73 | /** |
| 73 | * DOC: Operational mode - what is it ? | 74 | * DOC: Operational mode - what is it ? |
| @@ -121,17 +122,23 @@ struct iwl_rx_mem_buffer; | |||
| 121 | * there are Tx packets pending in the transport layer. | 122 | * there are Tx packets pending in the transport layer. |
| 122 | * Must be atomic | 123 | * Must be atomic |
| 123 | * @nic_error: error notification. Must be atomic | 124 | * @nic_error: error notification. Must be atomic |
| 125 | * @cmd_queue_full: Called when the command queue gets full. Must be atomic. | ||
| 126 | * @nic_config: configure NIC, called before firmware is started. | ||
| 127 | * May sleep | ||
| 124 | */ | 128 | */ |
| 125 | struct iwl_op_mode_ops { | 129 | struct iwl_op_mode_ops { |
| 126 | struct iwl_op_mode *(*start)(struct iwl_trans *trans); | 130 | struct iwl_op_mode *(*start)(struct iwl_trans *trans, |
| 131 | const struct iwl_fw *fw); | ||
| 127 | void (*stop)(struct iwl_op_mode *op_mode); | 132 | void (*stop)(struct iwl_op_mode *op_mode); |
| 128 | int (*rx)(struct iwl_op_mode *op_mode, struct iwl_rx_mem_buffer *rxb, | 133 | int (*rx)(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, |
| 129 | struct iwl_device_cmd *cmd); | 134 | struct iwl_device_cmd *cmd); |
| 130 | void (*queue_full)(struct iwl_op_mode *op_mode, u8 ac); | 135 | void (*queue_full)(struct iwl_op_mode *op_mode, u8 ac); |
| 131 | void (*queue_not_full)(struct iwl_op_mode *op_mode, u8 ac); | 136 | void (*queue_not_full)(struct iwl_op_mode *op_mode, u8 ac); |
| 132 | void (*hw_rf_kill)(struct iwl_op_mode *op_mode, bool state); | 137 | void (*hw_rf_kill)(struct iwl_op_mode *op_mode, bool state); |
| 133 | void (*free_skb)(struct iwl_op_mode *op_mode, struct sk_buff *skb); | 138 | void (*free_skb)(struct iwl_op_mode *op_mode, struct sk_buff *skb); |
| 134 | void (*nic_error)(struct iwl_op_mode *op_mode); | 139 | void (*nic_error)(struct iwl_op_mode *op_mode); |
| 140 | void (*cmd_queue_full)(struct iwl_op_mode *op_mode); | ||
| 141 | void (*nic_config)(struct iwl_op_mode *op_mode); | ||
| 135 | }; | 142 | }; |
| 136 | 143 | ||
| 137 | /** | 144 | /** |
| @@ -156,7 +163,7 @@ static inline void iwl_op_mode_stop(struct iwl_op_mode *op_mode) | |||
| 156 | } | 163 | } |
| 157 | 164 | ||
| 158 | static inline int iwl_op_mode_rx(struct iwl_op_mode *op_mode, | 165 | static inline int iwl_op_mode_rx(struct iwl_op_mode *op_mode, |
| 159 | struct iwl_rx_mem_buffer *rxb, | 166 | struct iwl_rx_cmd_buffer *rxb, |
| 160 | struct iwl_device_cmd *cmd) | 167 | struct iwl_device_cmd *cmd) |
| 161 | { | 168 | { |
| 162 | return op_mode->ops->rx(op_mode, rxb, cmd); | 169 | return op_mode->ops->rx(op_mode, rxb, cmd); |
| @@ -190,6 +197,17 @@ static inline void iwl_op_mode_nic_error(struct iwl_op_mode *op_mode) | |||
| 190 | op_mode->ops->nic_error(op_mode); | 197 | op_mode->ops->nic_error(op_mode); |
| 191 | } | 198 | } |
| 192 | 199 | ||
| 200 | static inline void iwl_op_mode_cmd_queue_full(struct iwl_op_mode *op_mode) | ||
| 201 | { | ||
| 202 | op_mode->ops->cmd_queue_full(op_mode); | ||
| 203 | } | ||
| 204 | |||
| 205 | static inline void iwl_op_mode_nic_config(struct iwl_op_mode *op_mode) | ||
| 206 | { | ||
| 207 | might_sleep(); | ||
| 208 | op_mode->ops->nic_config(op_mode); | ||
| 209 | } | ||
| 210 | |||
| 193 | /***************************************************** | 211 | /***************************************************** |
| 194 | * Op mode layers implementations | 212 | * Op mode layers implementations |
| 195 | ******************************************************/ | 213 | ******************************************************/ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 06e004157dcc..c5e339ee918b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c | |||
| @@ -263,7 +263,7 @@ MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); | |||
| 263 | 263 | ||
| 264 | static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 264 | static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
| 265 | { | 265 | { |
| 266 | struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); | 266 | const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); |
| 267 | struct iwl_shared *shrd; | 267 | struct iwl_shared *shrd; |
| 268 | struct iwl_trans *iwl_trans; | 268 | struct iwl_trans *iwl_trans; |
| 269 | int err; | 269 | int err; |
| @@ -278,17 +278,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 278 | 278 | ||
| 279 | #ifdef CONFIG_IWLWIFI_IDI | 279 | #ifdef CONFIG_IWLWIFI_IDI |
| 280 | iwl_trans = iwl_trans_idi_alloc(shrd, pdev, ent); | 280 | iwl_trans = iwl_trans_idi_alloc(shrd, pdev, ent); |
| 281 | if (iwl_trans == NULL) { | ||
| 282 | err = -ENOMEM; | ||
| 283 | goto out_free_bus; | ||
| 284 | } | ||
| 285 | |||
| 286 | shrd->trans = iwl_trans; | ||
| 287 | pci_set_drvdata(pdev, iwl_trans); | ||
| 288 | |||
| 289 | err = iwl_drv_start(shrd, iwl_trans, cfg); | ||
| 290 | #else | 281 | #else |
| 291 | iwl_trans = iwl_trans_pcie_alloc(shrd, pdev, ent); | 282 | iwl_trans = iwl_trans_pcie_alloc(shrd, pdev, ent); |
| 283 | #endif | ||
| 292 | if (iwl_trans == NULL) { | 284 | if (iwl_trans == NULL) { |
| 293 | err = -ENOMEM; | 285 | err = -ENOMEM; |
| 294 | goto out_free_bus; | 286 | goto out_free_bus; |
| @@ -298,7 +290,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 298 | pci_set_drvdata(pdev, iwl_trans); | 290 | pci_set_drvdata(pdev, iwl_trans); |
| 299 | 291 | ||
| 300 | err = iwl_drv_start(shrd, iwl_trans, cfg); | 292 | err = iwl_drv_start(shrd, iwl_trans, cfg); |
| 301 | #endif | ||
| 302 | if (err) | 293 | if (err) |
| 303 | goto out_free_trans; | 294 | goto out_free_trans; |
| 304 | 295 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index fd008c4e41fd..958d9d09aee3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c | |||
| @@ -215,7 +215,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, | |||
| 215 | else | 215 | else |
| 216 | cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK; | 216 | cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK; |
| 217 | 217 | ||
| 218 | if (hw_params(priv).shadow_reg_enable) | 218 | if (cfg(priv)->base_params->shadow_reg_enable) |
| 219 | cmd->flags |= IWL_POWER_SHADOW_REG_ENA; | 219 | cmd->flags |= IWL_POWER_SHADOW_REG_ENA; |
| 220 | else | 220 | else |
| 221 | cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; | 221 | cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; |
| @@ -301,7 +301,7 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv, | |||
| 301 | if (priv->power_data.bus_pm) | 301 | if (priv->power_data.bus_pm) |
| 302 | cmd->flags |= IWL_POWER_PCI_PM_MSK; | 302 | cmd->flags |= IWL_POWER_PCI_PM_MSK; |
| 303 | 303 | ||
| 304 | if (hw_params(priv).shadow_reg_enable) | 304 | if (cfg(priv)->base_params->shadow_reg_enable) |
| 305 | cmd->flags |= IWL_POWER_SHADOW_REG_ENA; | 305 | cmd->flags |= IWL_POWER_SHADOW_REG_ENA; |
| 306 | else | 306 | else |
| 307 | cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; | 307 | cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; |
| @@ -336,7 +336,7 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd) | |||
| 336 | le32_to_cpu(cmd->sleep_interval[3]), | 336 | le32_to_cpu(cmd->sleep_interval[3]), |
| 337 | le32_to_cpu(cmd->sleep_interval[4])); | 337 | le32_to_cpu(cmd->sleep_interval[4])); |
| 338 | 338 | ||
| 339 | return iwl_trans_send_cmd_pdu(trans(priv), POWER_TABLE_CMD, CMD_SYNC, | 339 | return iwl_dvm_send_cmd_pdu(priv, POWER_TABLE_CMD, CMD_SYNC, |
| 340 | sizeof(struct iwl_powertable_cmd), cmd); | 340 | sizeof(struct iwl_powertable_cmd), cmd); |
| 341 | } | 341 | } |
| 342 | 342 | ||
| @@ -348,7 +348,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, | |||
| 348 | 348 | ||
| 349 | dtimper = priv->hw->conf.ps_dtim_period ?: 1; | 349 | dtimper = priv->hw->conf.ps_dtim_period ?: 1; |
| 350 | 350 | ||
| 351 | if (priv->shrd->wowlan) | 351 | if (priv->wowlan) |
| 352 | iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper); | 352 | iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper); |
| 353 | else if (!cfg(priv)->base_params->no_idle_support && | 353 | else if (!cfg(priv)->base_params->no_idle_support && |
| 354 | priv->hw->conf.flags & IEEE80211_CONF_IDLE) | 354 | priv->hw->conf.flags & IEEE80211_CONF_IDLE) |
| @@ -383,7 +383,7 @@ int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, | |||
| 383 | int ret; | 383 | int ret; |
| 384 | bool update_chains; | 384 | bool update_chains; |
| 385 | 385 | ||
| 386 | lockdep_assert_held(&priv->shrd->mutex); | 386 | lockdep_assert_held(&priv->mutex); |
| 387 | 387 | ||
| 388 | /* Don't update the RX chain when chain noise calibration is running */ | 388 | /* Don't update the RX chain when chain noise calibration is running */ |
| 389 | update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE || | 389 | update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE || |
| @@ -392,12 +392,12 @@ int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, | |||
| 392 | if (!memcmp(&priv->power_data.sleep_cmd, cmd, sizeof(*cmd)) && !force) | 392 | if (!memcmp(&priv->power_data.sleep_cmd, cmd, sizeof(*cmd)) && !force) |
| 393 | return 0; | 393 | return 0; |
| 394 | 394 | ||
| 395 | if (!iwl_is_ready_rf(priv->shrd)) | 395 | if (!iwl_is_ready_rf(priv)) |
| 396 | return -EIO; | 396 | return -EIO; |
| 397 | 397 | ||
| 398 | /* scan complete use sleep_power_next, need to be updated */ | 398 | /* scan complete use sleep_power_next, need to be updated */ |
| 399 | memcpy(&priv->power_data.sleep_cmd_next, cmd, sizeof(*cmd)); | 399 | memcpy(&priv->power_data.sleep_cmd_next, cmd, sizeof(*cmd)); |
| 400 | if (test_bit(STATUS_SCANNING, &priv->shrd->status) && !force) { | 400 | if (test_bit(STATUS_SCANNING, &priv->status) && !force) { |
| 401 | IWL_DEBUG_INFO(priv, "Defer power set mode while scanning\n"); | 401 | IWL_DEBUG_INFO(priv, "Defer power set mode while scanning\n"); |
| 402 | return 0; | 402 | return 0; |
| 403 | } | 403 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index a4d11016c3b4..75dc20bd965b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h | |||
| @@ -216,10 +216,6 @@ | |||
| 216 | #define SCD_TRANS_TBL_OFFSET_QUEUE(x) \ | 216 | #define SCD_TRANS_TBL_OFFSET_QUEUE(x) \ |
| 217 | ((SCD_TRANS_TBL_MEM_LOWER_BOUND + ((x) * 2)) & 0xfffc) | 217 | ((SCD_TRANS_TBL_MEM_LOWER_BOUND + ((x) * 2)) & 0xfffc) |
| 218 | 218 | ||
| 219 | #define SCD_QUEUECHAIN_SEL_ALL(priv) \ | ||
| 220 | (((1<<hw_params(priv).max_txq_num) - 1) &\ | ||
| 221 | (~(1<<(priv)->shrd->cmd_queue))) | ||
| 222 | |||
| 223 | #define SCD_BASE (PRPH_BASE + 0xa02c00) | 219 | #define SCD_BASE (PRPH_BASE + 0xa02c00) |
| 224 | 220 | ||
| 225 | #define SCD_SRAM_BASE_ADDR (SCD_BASE + 0x0) | 221 | #define SCD_SRAM_BASE_ADDR (SCD_BASE + 0x0) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 42ee1c410efd..902efe4bc898 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
| @@ -57,39 +57,39 @@ | |||
| 57 | static int iwl_send_scan_abort(struct iwl_priv *priv) | 57 | static int iwl_send_scan_abort(struct iwl_priv *priv) |
| 58 | { | 58 | { |
| 59 | int ret; | 59 | int ret; |
| 60 | struct iwl_rx_packet *pkt; | ||
| 61 | struct iwl_host_cmd cmd = { | 60 | struct iwl_host_cmd cmd = { |
| 62 | .id = REPLY_SCAN_ABORT_CMD, | 61 | .id = REPLY_SCAN_ABORT_CMD, |
| 63 | .flags = CMD_SYNC | CMD_WANT_SKB, | 62 | .flags = CMD_SYNC | CMD_WANT_SKB, |
| 64 | }; | 63 | }; |
| 64 | __le32 *status; | ||
| 65 | 65 | ||
| 66 | /* Exit instantly with error when device is not ready | 66 | /* Exit instantly with error when device is not ready |
| 67 | * to receive scan abort command or it does not perform | 67 | * to receive scan abort command or it does not perform |
| 68 | * hardware scan currently */ | 68 | * hardware scan currently */ |
| 69 | if (!test_bit(STATUS_READY, &priv->shrd->status) || | 69 | if (!test_bit(STATUS_READY, &priv->status) || |
| 70 | !test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status) || | 70 | !test_bit(STATUS_GEO_CONFIGURED, &priv->status) || |
| 71 | !test_bit(STATUS_SCAN_HW, &priv->shrd->status) || | 71 | !test_bit(STATUS_SCAN_HW, &priv->status) || |
| 72 | test_bit(STATUS_FW_ERROR, &priv->shrd->status) || | 72 | test_bit(STATUS_FW_ERROR, &priv->shrd->status)) |
| 73 | test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | ||
| 74 | return -EIO; | 73 | return -EIO; |
| 75 | 74 | ||
| 76 | ret = iwl_trans_send_cmd(trans(priv), &cmd); | 75 | ret = iwl_dvm_send_cmd(priv, &cmd); |
| 77 | if (ret) | 76 | if (ret) |
| 78 | return ret; | 77 | return ret; |
| 79 | 78 | ||
| 80 | pkt = (struct iwl_rx_packet *)cmd.reply_page; | 79 | status = (void *)cmd.resp_pkt->data; |
| 81 | if (pkt->u.status != CAN_ABORT_STATUS) { | 80 | if (*status != CAN_ABORT_STATUS) { |
| 82 | /* The scan abort will return 1 for success or | 81 | /* The scan abort will return 1 for success or |
| 83 | * 2 for "failure". A failure condition can be | 82 | * 2 for "failure". A failure condition can be |
| 84 | * due to simply not being in an active scan which | 83 | * due to simply not being in an active scan which |
| 85 | * can occur if we send the scan abort before we | 84 | * can occur if we send the scan abort before we |
| 86 | * the microcode has notified us that a scan is | 85 | * the microcode has notified us that a scan is |
| 87 | * completed. */ | 86 | * completed. */ |
| 88 | IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n", pkt->u.status); | 87 | IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n", |
| 88 | le32_to_cpu(*status)); | ||
| 89 | ret = -EIO; | 89 | ret = -EIO; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | iwl_free_pages(priv->shrd, cmd.reply_page); | 92 | iwl_free_resp(&cmd); |
| 93 | return ret; | 93 | return ret; |
| 94 | } | 94 | } |
| 95 | 95 | ||
| @@ -116,20 +116,20 @@ static void iwl_process_scan_complete(struct iwl_priv *priv) | |||
| 116 | { | 116 | { |
| 117 | bool aborted; | 117 | bool aborted; |
| 118 | 118 | ||
| 119 | lockdep_assert_held(&priv->shrd->mutex); | 119 | lockdep_assert_held(&priv->mutex); |
| 120 | 120 | ||
| 121 | if (!test_and_clear_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status)) | 121 | if (!test_and_clear_bit(STATUS_SCAN_COMPLETE, &priv->status)) |
| 122 | return; | 122 | return; |
| 123 | 123 | ||
| 124 | IWL_DEBUG_SCAN(priv, "Completed scan.\n"); | 124 | IWL_DEBUG_SCAN(priv, "Completed scan.\n"); |
| 125 | 125 | ||
| 126 | cancel_delayed_work(&priv->scan_check); | 126 | cancel_delayed_work(&priv->scan_check); |
| 127 | 127 | ||
| 128 | aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->shrd->status); | 128 | aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status); |
| 129 | if (aborted) | 129 | if (aborted) |
| 130 | IWL_DEBUG_SCAN(priv, "Aborted scan completed.\n"); | 130 | IWL_DEBUG_SCAN(priv, "Aborted scan completed.\n"); |
| 131 | 131 | ||
| 132 | if (!test_and_clear_bit(STATUS_SCANNING, &priv->shrd->status)) { | 132 | if (!test_and_clear_bit(STATUS_SCANNING, &priv->status)) { |
| 133 | IWL_DEBUG_SCAN(priv, "Scan already completed.\n"); | 133 | IWL_DEBUG_SCAN(priv, "Scan already completed.\n"); |
| 134 | goto out_settings; | 134 | goto out_settings; |
| 135 | } | 135 | } |
| @@ -165,7 +165,7 @@ out_complete: | |||
| 165 | 165 | ||
| 166 | out_settings: | 166 | out_settings: |
| 167 | /* Can we still talk to firmware ? */ | 167 | /* Can we still talk to firmware ? */ |
| 168 | if (!iwl_is_ready_rf(priv->shrd)) | 168 | if (!iwl_is_ready_rf(priv)) |
| 169 | return; | 169 | return; |
| 170 | 170 | ||
| 171 | iwlagn_post_scan(priv); | 171 | iwlagn_post_scan(priv); |
| @@ -173,18 +173,18 @@ out_settings: | |||
| 173 | 173 | ||
| 174 | void iwl_force_scan_end(struct iwl_priv *priv) | 174 | void iwl_force_scan_end(struct iwl_priv *priv) |
| 175 | { | 175 | { |
| 176 | lockdep_assert_held(&priv->shrd->mutex); | 176 | lockdep_assert_held(&priv->mutex); |
| 177 | 177 | ||
| 178 | if (!test_bit(STATUS_SCANNING, &priv->shrd->status)) { | 178 | if (!test_bit(STATUS_SCANNING, &priv->status)) { |
| 179 | IWL_DEBUG_SCAN(priv, "Forcing scan end while not scanning\n"); | 179 | IWL_DEBUG_SCAN(priv, "Forcing scan end while not scanning\n"); |
| 180 | return; | 180 | return; |
| 181 | } | 181 | } |
| 182 | 182 | ||
| 183 | IWL_DEBUG_SCAN(priv, "Forcing scan end\n"); | 183 | IWL_DEBUG_SCAN(priv, "Forcing scan end\n"); |
| 184 | clear_bit(STATUS_SCANNING, &priv->shrd->status); | 184 | clear_bit(STATUS_SCANNING, &priv->status); |
| 185 | clear_bit(STATUS_SCAN_HW, &priv->shrd->status); | 185 | clear_bit(STATUS_SCAN_HW, &priv->status); |
| 186 | clear_bit(STATUS_SCAN_ABORTING, &priv->shrd->status); | 186 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); |
| 187 | clear_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status); | 187 | clear_bit(STATUS_SCAN_COMPLETE, &priv->status); |
| 188 | iwl_complete_scan(priv, true); | 188 | iwl_complete_scan(priv, true); |
| 189 | } | 189 | } |
| 190 | 190 | ||
| @@ -192,14 +192,14 @@ static void iwl_do_scan_abort(struct iwl_priv *priv) | |||
| 192 | { | 192 | { |
| 193 | int ret; | 193 | int ret; |
| 194 | 194 | ||
| 195 | lockdep_assert_held(&priv->shrd->mutex); | 195 | lockdep_assert_held(&priv->mutex); |
| 196 | 196 | ||
| 197 | if (!test_bit(STATUS_SCANNING, &priv->shrd->status)) { | 197 | if (!test_bit(STATUS_SCANNING, &priv->status)) { |
| 198 | IWL_DEBUG_SCAN(priv, "Not performing scan to abort\n"); | 198 | IWL_DEBUG_SCAN(priv, "Not performing scan to abort\n"); |
| 199 | return; | 199 | return; |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | if (test_and_set_bit(STATUS_SCAN_ABORTING, &priv->shrd->status)) { | 202 | if (test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) { |
| 203 | IWL_DEBUG_SCAN(priv, "Scan abort in progress\n"); | 203 | IWL_DEBUG_SCAN(priv, "Scan abort in progress\n"); |
| 204 | return; | 204 | return; |
| 205 | } | 205 | } |
| @@ -231,14 +231,14 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) | |||
| 231 | { | 231 | { |
| 232 | unsigned long timeout = jiffies + msecs_to_jiffies(ms); | 232 | unsigned long timeout = jiffies + msecs_to_jiffies(ms); |
| 233 | 233 | ||
| 234 | lockdep_assert_held(&priv->shrd->mutex); | 234 | lockdep_assert_held(&priv->mutex); |
| 235 | 235 | ||
| 236 | IWL_DEBUG_SCAN(priv, "Scan cancel timeout\n"); | 236 | IWL_DEBUG_SCAN(priv, "Scan cancel timeout\n"); |
| 237 | 237 | ||
| 238 | iwl_do_scan_abort(priv); | 238 | iwl_do_scan_abort(priv); |
| 239 | 239 | ||
| 240 | while (time_before_eq(jiffies, timeout)) { | 240 | while (time_before_eq(jiffies, timeout)) { |
| 241 | if (!test_bit(STATUS_SCAN_HW, &priv->shrd->status)) | 241 | if (!test_bit(STATUS_SCAN_HW, &priv->status)) |
| 242 | goto finished; | 242 | goto finished; |
| 243 | msleep(20); | 243 | msleep(20); |
| 244 | } | 244 | } |
| @@ -261,13 +261,12 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) | |||
| 261 | 261 | ||
| 262 | /* Service response to REPLY_SCAN_CMD (0x80) */ | 262 | /* Service response to REPLY_SCAN_CMD (0x80) */ |
| 263 | static int iwl_rx_reply_scan(struct iwl_priv *priv, | 263 | static int iwl_rx_reply_scan(struct iwl_priv *priv, |
| 264 | struct iwl_rx_mem_buffer *rxb, | 264 | struct iwl_rx_cmd_buffer *rxb, |
| 265 | struct iwl_device_cmd *cmd) | 265 | struct iwl_device_cmd *cmd) |
| 266 | { | 266 | { |
| 267 | #ifdef CONFIG_IWLWIFI_DEBUG | 267 | #ifdef CONFIG_IWLWIFI_DEBUG |
| 268 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 268 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 269 | struct iwl_scanreq_notification *notif = | 269 | struct iwl_scanreq_notification *notif = (void *)pkt->data; |
| 270 | (struct iwl_scanreq_notification *)pkt->u.raw; | ||
| 271 | 270 | ||
| 272 | IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status); | 271 | IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status); |
| 273 | #endif | 272 | #endif |
| @@ -276,12 +275,12 @@ static int iwl_rx_reply_scan(struct iwl_priv *priv, | |||
| 276 | 275 | ||
| 277 | /* Service SCAN_START_NOTIFICATION (0x82) */ | 276 | /* Service SCAN_START_NOTIFICATION (0x82) */ |
| 278 | static int iwl_rx_scan_start_notif(struct iwl_priv *priv, | 277 | static int iwl_rx_scan_start_notif(struct iwl_priv *priv, |
| 279 | struct iwl_rx_mem_buffer *rxb, | 278 | struct iwl_rx_cmd_buffer *rxb, |
| 280 | struct iwl_device_cmd *cmd) | 279 | struct iwl_device_cmd *cmd) |
| 281 | { | 280 | { |
| 282 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 281 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 283 | struct iwl_scanstart_notification *notif = | 282 | struct iwl_scanstart_notification *notif = (void *)pkt->data; |
| 284 | (struct iwl_scanstart_notification *)pkt->u.raw; | 283 | |
| 285 | priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); | 284 | priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); |
| 286 | IWL_DEBUG_SCAN(priv, "Scan start: " | 285 | IWL_DEBUG_SCAN(priv, "Scan start: " |
| 287 | "%d [802.11%s] " | 286 | "%d [802.11%s] " |
| @@ -303,13 +302,12 @@ static int iwl_rx_scan_start_notif(struct iwl_priv *priv, | |||
| 303 | 302 | ||
| 304 | /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ | 303 | /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ |
| 305 | static int iwl_rx_scan_results_notif(struct iwl_priv *priv, | 304 | static int iwl_rx_scan_results_notif(struct iwl_priv *priv, |
| 306 | struct iwl_rx_mem_buffer *rxb, | 305 | struct iwl_rx_cmd_buffer *rxb, |
| 307 | struct iwl_device_cmd *cmd) | 306 | struct iwl_device_cmd *cmd) |
| 308 | { | 307 | { |
| 309 | #ifdef CONFIG_IWLWIFI_DEBUG | 308 | #ifdef CONFIG_IWLWIFI_DEBUG |
| 310 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 309 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 311 | struct iwl_scanresults_notification *notif = | 310 | struct iwl_scanresults_notification *notif = (void *)pkt->data; |
| 312 | (struct iwl_scanresults_notification *)pkt->u.raw; | ||
| 313 | 311 | ||
| 314 | IWL_DEBUG_SCAN(priv, "Scan ch.res: " | 312 | IWL_DEBUG_SCAN(priv, "Scan ch.res: " |
| 315 | "%d [802.11%s] " | 313 | "%d [802.11%s] " |
| @@ -329,11 +327,11 @@ static int iwl_rx_scan_results_notif(struct iwl_priv *priv, | |||
| 329 | 327 | ||
| 330 | /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ | 328 | /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ |
| 331 | static int iwl_rx_scan_complete_notif(struct iwl_priv *priv, | 329 | static int iwl_rx_scan_complete_notif(struct iwl_priv *priv, |
| 332 | struct iwl_rx_mem_buffer *rxb, | 330 | struct iwl_rx_cmd_buffer *rxb, |
| 333 | struct iwl_device_cmd *cmd) | 331 | struct iwl_device_cmd *cmd) |
| 334 | { | 332 | { |
| 335 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 333 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 336 | struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; | 334 | struct iwl_scancomplete_notification *scan_notif = (void *)pkt->data; |
| 337 | 335 | ||
| 338 | IWL_DEBUG_SCAN(priv, "Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", | 336 | IWL_DEBUG_SCAN(priv, "Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", |
| 339 | scan_notif->scanned_channels, | 337 | scan_notif->scanned_channels, |
| @@ -352,8 +350,8 @@ static int iwl_rx_scan_complete_notif(struct iwl_priv *priv, | |||
| 352 | * to clear, we need to set SCAN_COMPLETE before clearing SCAN_HW | 350 | * to clear, we need to set SCAN_COMPLETE before clearing SCAN_HW |
| 353 | * to avoid a race there. | 351 | * to avoid a race there. |
| 354 | */ | 352 | */ |
| 355 | set_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status); | 353 | set_bit(STATUS_SCAN_COMPLETE, &priv->status); |
| 356 | clear_bit(STATUS_SCAN_HW, &priv->shrd->status); | 354 | clear_bit(STATUS_SCAN_HW, &priv->status); |
| 357 | queue_work(priv->workqueue, &priv->scan_completed); | 355 | queue_work(priv->workqueue, &priv->scan_completed); |
| 358 | 356 | ||
| 359 | if (priv->iw_mode != NL80211_IFTYPE_ADHOC && | 357 | if (priv->iw_mode != NL80211_IFTYPE_ADHOC && |
| @@ -574,6 +572,53 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, | |||
| 574 | return added; | 572 | return added; |
| 575 | } | 573 | } |
| 576 | 574 | ||
| 575 | /** | ||
| 576 | * iwl_fill_probe_req - fill in all required fields and IE for probe request | ||
| 577 | */ | ||
| 578 | |||
| 579 | static u16 iwl_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta, | ||
| 580 | const u8 *ies, int ie_len, int left) | ||
| 581 | { | ||
| 582 | int len = 0; | ||
| 583 | u8 *pos = NULL; | ||
| 584 | |||
| 585 | /* Make sure there is enough space for the probe request, | ||
| 586 | * two mandatory IEs and the data */ | ||
| 587 | left -= 24; | ||
| 588 | if (left < 0) | ||
| 589 | return 0; | ||
| 590 | |||
| 591 | frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); | ||
| 592 | memcpy(frame->da, iwl_bcast_addr, ETH_ALEN); | ||
| 593 | memcpy(frame->sa, ta, ETH_ALEN); | ||
| 594 | memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN); | ||
| 595 | frame->seq_ctrl = 0; | ||
| 596 | |||
| 597 | len += 24; | ||
| 598 | |||
| 599 | /* ...next IE... */ | ||
| 600 | pos = &frame->u.probe_req.variable[0]; | ||
| 601 | |||
| 602 | /* fill in our indirect SSID IE */ | ||
| 603 | left -= 2; | ||
| 604 | if (left < 0) | ||
| 605 | return 0; | ||
| 606 | *pos++ = WLAN_EID_SSID; | ||
| 607 | *pos++ = 0; | ||
| 608 | |||
| 609 | len += 2; | ||
| 610 | |||
| 611 | if (WARN_ON(left < ie_len)) | ||
| 612 | return len; | ||
| 613 | |||
| 614 | if (ies && ie_len) { | ||
| 615 | memcpy(pos, ies, ie_len); | ||
| 616 | len += ie_len; | ||
| 617 | } | ||
| 618 | |||
| 619 | return (u16)len; | ||
| 620 | } | ||
| 621 | |||
| 577 | static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | 622 | static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) |
| 578 | { | 623 | { |
| 579 | struct iwl_host_cmd cmd = { | 624 | struct iwl_host_cmd cmd = { |
| @@ -596,7 +641,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
| 596 | u8 scan_tx_antennas = hw_params(priv).valid_tx_ant; | 641 | u8 scan_tx_antennas = hw_params(priv).valid_tx_ant; |
| 597 | int ret; | 642 | int ret; |
| 598 | 643 | ||
| 599 | lockdep_assert_held(&priv->shrd->mutex); | 644 | lockdep_assert_held(&priv->mutex); |
| 600 | 645 | ||
| 601 | if (vif) | 646 | if (vif) |
| 602 | ctx = iwl_rxon_ctx_from_vif(vif); | 647 | ctx = iwl_rxon_ctx_from_vif(vif); |
| @@ -793,7 +838,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
| 793 | scan->rx_chain = cpu_to_le16(rx_chain); | 838 | scan->rx_chain = cpu_to_le16(rx_chain); |
| 794 | switch (priv->scan_type) { | 839 | switch (priv->scan_type) { |
| 795 | case IWL_SCAN_NORMAL: | 840 | case IWL_SCAN_NORMAL: |
| 796 | cmd_len = iwl_fill_probe_req(priv, | 841 | cmd_len = iwl_fill_probe_req( |
| 797 | (struct ieee80211_mgmt *)scan->data, | 842 | (struct ieee80211_mgmt *)scan->data, |
| 798 | vif->addr, | 843 | vif->addr, |
| 799 | priv->scan_request->ie, | 844 | priv->scan_request->ie, |
| @@ -803,7 +848,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
| 803 | case IWL_SCAN_RADIO_RESET: | 848 | case IWL_SCAN_RADIO_RESET: |
| 804 | case IWL_SCAN_ROC: | 849 | case IWL_SCAN_ROC: |
| 805 | /* use bcast addr, will not be transmitted but must be valid */ | 850 | /* use bcast addr, will not be transmitted but must be valid */ |
| 806 | cmd_len = iwl_fill_probe_req(priv, | 851 | cmd_len = iwl_fill_probe_req( |
| 807 | (struct ieee80211_mgmt *)scan->data, | 852 | (struct ieee80211_mgmt *)scan->data, |
| 808 | iwl_bcast_addr, NULL, 0, | 853 | iwl_bcast_addr, NULL, 0, |
| 809 | IWL_MAX_SCAN_SIZE - sizeof(*scan)); | 854 | IWL_MAX_SCAN_SIZE - sizeof(*scan)); |
| @@ -882,15 +927,15 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
| 882 | scan->len = cpu_to_le16(cmd.len[0]); | 927 | scan->len = cpu_to_le16(cmd.len[0]); |
| 883 | 928 | ||
| 884 | /* set scan bit here for PAN params */ | 929 | /* set scan bit here for PAN params */ |
| 885 | set_bit(STATUS_SCAN_HW, &priv->shrd->status); | 930 | set_bit(STATUS_SCAN_HW, &priv->status); |
| 886 | 931 | ||
| 887 | ret = iwlagn_set_pan_params(priv); | 932 | ret = iwlagn_set_pan_params(priv); |
| 888 | if (ret) | 933 | if (ret) |
| 889 | return ret; | 934 | return ret; |
| 890 | 935 | ||
| 891 | ret = iwl_trans_send_cmd(trans(priv), &cmd); | 936 | ret = iwl_dvm_send_cmd(priv, &cmd); |
| 892 | if (ret) { | 937 | if (ret) { |
| 893 | clear_bit(STATUS_SCAN_HW, &priv->shrd->status); | 938 | clear_bit(STATUS_SCAN_HW, &priv->status); |
| 894 | iwlagn_set_pan_params(priv); | 939 | iwlagn_set_pan_params(priv); |
| 895 | } | 940 | } |
| 896 | 941 | ||
| @@ -913,22 +958,22 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, | |||
| 913 | { | 958 | { |
| 914 | int ret; | 959 | int ret; |
| 915 | 960 | ||
| 916 | lockdep_assert_held(&priv->shrd->mutex); | 961 | lockdep_assert_held(&priv->mutex); |
| 917 | 962 | ||
| 918 | cancel_delayed_work(&priv->scan_check); | 963 | cancel_delayed_work(&priv->scan_check); |
| 919 | 964 | ||
| 920 | if (!iwl_is_ready_rf(priv->shrd)) { | 965 | if (!iwl_is_ready_rf(priv)) { |
| 921 | IWL_WARN(priv, "Request scan called when driver not ready.\n"); | 966 | IWL_WARN(priv, "Request scan called when driver not ready.\n"); |
| 922 | return -EIO; | 967 | return -EIO; |
| 923 | } | 968 | } |
| 924 | 969 | ||
| 925 | if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { | 970 | if (test_bit(STATUS_SCAN_HW, &priv->status)) { |
| 926 | IWL_DEBUG_SCAN(priv, | 971 | IWL_DEBUG_SCAN(priv, |
| 927 | "Multiple concurrent scan requests in parallel.\n"); | 972 | "Multiple concurrent scan requests in parallel.\n"); |
| 928 | return -EBUSY; | 973 | return -EBUSY; |
| 929 | } | 974 | } |
| 930 | 975 | ||
| 931 | if (test_bit(STATUS_SCAN_ABORTING, &priv->shrd->status)) { | 976 | if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { |
| 932 | IWL_DEBUG_SCAN(priv, "Scan request while abort pending.\n"); | 977 | IWL_DEBUG_SCAN(priv, "Scan request while abort pending.\n"); |
| 933 | return -EBUSY; | 978 | return -EBUSY; |
| 934 | } | 979 | } |
| @@ -938,14 +983,14 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, | |||
| 938 | scan_type == IWL_SCAN_ROC ? "remain-on-channel " : | 983 | scan_type == IWL_SCAN_ROC ? "remain-on-channel " : |
| 939 | "internal short "); | 984 | "internal short "); |
| 940 | 985 | ||
| 941 | set_bit(STATUS_SCANNING, &priv->shrd->status); | 986 | set_bit(STATUS_SCANNING, &priv->status); |
| 942 | priv->scan_type = scan_type; | 987 | priv->scan_type = scan_type; |
| 943 | priv->scan_start = jiffies; | 988 | priv->scan_start = jiffies; |
| 944 | priv->scan_band = band; | 989 | priv->scan_band = band; |
| 945 | 990 | ||
| 946 | ret = iwlagn_request_scan(priv, vif); | 991 | ret = iwlagn_request_scan(priv, vif); |
| 947 | if (ret) { | 992 | if (ret) { |
| 948 | clear_bit(STATUS_SCANNING, &priv->shrd->status); | 993 | clear_bit(STATUS_SCANNING, &priv->status); |
| 949 | priv->scan_type = IWL_SCAN_NORMAL; | 994 | priv->scan_type = IWL_SCAN_NORMAL; |
| 950 | return ret; | 995 | return ret; |
| 951 | } | 996 | } |
| @@ -973,14 +1018,14 @@ static void iwl_bg_start_internal_scan(struct work_struct *work) | |||
| 973 | 1018 | ||
| 974 | IWL_DEBUG_SCAN(priv, "Start internal scan\n"); | 1019 | IWL_DEBUG_SCAN(priv, "Start internal scan\n"); |
| 975 | 1020 | ||
| 976 | mutex_lock(&priv->shrd->mutex); | 1021 | mutex_lock(&priv->mutex); |
| 977 | 1022 | ||
| 978 | if (priv->scan_type == IWL_SCAN_RADIO_RESET) { | 1023 | if (priv->scan_type == IWL_SCAN_RADIO_RESET) { |
| 979 | IWL_DEBUG_SCAN(priv, "Internal scan already in progress\n"); | 1024 | IWL_DEBUG_SCAN(priv, "Internal scan already in progress\n"); |
| 980 | goto unlock; | 1025 | goto unlock; |
| 981 | } | 1026 | } |
| 982 | 1027 | ||
| 983 | if (test_bit(STATUS_SCANNING, &priv->shrd->status)) { | 1028 | if (test_bit(STATUS_SCANNING, &priv->status)) { |
| 984 | IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); | 1029 | IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); |
| 985 | goto unlock; | 1030 | goto unlock; |
| 986 | } | 1031 | } |
| @@ -988,7 +1033,7 @@ static void iwl_bg_start_internal_scan(struct work_struct *work) | |||
| 988 | if (iwl_scan_initiate(priv, NULL, IWL_SCAN_RADIO_RESET, priv->band)) | 1033 | if (iwl_scan_initiate(priv, NULL, IWL_SCAN_RADIO_RESET, priv->band)) |
| 989 | IWL_DEBUG_SCAN(priv, "failed to start internal short scan\n"); | 1034 | IWL_DEBUG_SCAN(priv, "failed to start internal short scan\n"); |
| 990 | unlock: | 1035 | unlock: |
| 991 | mutex_unlock(&priv->shrd->mutex); | 1036 | mutex_unlock(&priv->mutex); |
| 992 | } | 1037 | } |
| 993 | 1038 | ||
| 994 | static void iwl_bg_scan_check(struct work_struct *data) | 1039 | static void iwl_bg_scan_check(struct work_struct *data) |
| @@ -1001,56 +1046,9 @@ static void iwl_bg_scan_check(struct work_struct *data) | |||
| 1001 | /* Since we are here firmware does not finish scan and | 1046 | /* Since we are here firmware does not finish scan and |
| 1002 | * most likely is in bad shape, so we don't bother to | 1047 | * most likely is in bad shape, so we don't bother to |
| 1003 | * send abort command, just force scan complete to mac80211 */ | 1048 | * send abort command, just force scan complete to mac80211 */ |
| 1004 | mutex_lock(&priv->shrd->mutex); | 1049 | mutex_lock(&priv->mutex); |
| 1005 | iwl_force_scan_end(priv); | 1050 | iwl_force_scan_end(priv); |
| 1006 | mutex_unlock(&priv->shrd->mutex); | 1051 | mutex_unlock(&priv->mutex); |
| 1007 | } | ||
| 1008 | |||
| 1009 | /** | ||
| 1010 | * iwl_fill_probe_req - fill in all required fields and IE for probe request | ||
| 1011 | */ | ||
| 1012 | |||
| 1013 | u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, | ||
| 1014 | const u8 *ta, const u8 *ies, int ie_len, int left) | ||
| 1015 | { | ||
| 1016 | int len = 0; | ||
| 1017 | u8 *pos = NULL; | ||
| 1018 | |||
| 1019 | /* Make sure there is enough space for the probe request, | ||
| 1020 | * two mandatory IEs and the data */ | ||
| 1021 | left -= 24; | ||
| 1022 | if (left < 0) | ||
| 1023 | return 0; | ||
| 1024 | |||
| 1025 | frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); | ||
| 1026 | memcpy(frame->da, iwl_bcast_addr, ETH_ALEN); | ||
| 1027 | memcpy(frame->sa, ta, ETH_ALEN); | ||
| 1028 | memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN); | ||
| 1029 | frame->seq_ctrl = 0; | ||
| 1030 | |||
| 1031 | len += 24; | ||
| 1032 | |||
| 1033 | /* ...next IE... */ | ||
| 1034 | pos = &frame->u.probe_req.variable[0]; | ||
| 1035 | |||
| 1036 | /* fill in our indirect SSID IE */ | ||
| 1037 | left -= 2; | ||
| 1038 | if (left < 0) | ||
| 1039 | return 0; | ||
| 1040 | *pos++ = WLAN_EID_SSID; | ||
| 1041 | *pos++ = 0; | ||
| 1042 | |||
| 1043 | len += 2; | ||
| 1044 | |||
| 1045 | if (WARN_ON(left < ie_len)) | ||
| 1046 | return len; | ||
| 1047 | |||
| 1048 | if (ies && ie_len) { | ||
| 1049 | memcpy(pos, ies, ie_len); | ||
| 1050 | len += ie_len; | ||
| 1051 | } | ||
| 1052 | |||
| 1053 | return (u16)len; | ||
| 1054 | } | 1052 | } |
| 1055 | 1053 | ||
| 1056 | static void iwl_bg_abort_scan(struct work_struct *work) | 1054 | static void iwl_bg_abort_scan(struct work_struct *work) |
| @@ -1061,9 +1059,9 @@ static void iwl_bg_abort_scan(struct work_struct *work) | |||
| 1061 | 1059 | ||
| 1062 | /* We keep scan_check work queued in case when firmware will not | 1060 | /* We keep scan_check work queued in case when firmware will not |
| 1063 | * report back scan completed notification */ | 1061 | * report back scan completed notification */ |
| 1064 | mutex_lock(&priv->shrd->mutex); | 1062 | mutex_lock(&priv->mutex); |
| 1065 | iwl_scan_cancel_timeout(priv, 200); | 1063 | iwl_scan_cancel_timeout(priv, 200); |
| 1066 | mutex_unlock(&priv->shrd->mutex); | 1064 | mutex_unlock(&priv->mutex); |
| 1067 | } | 1065 | } |
| 1068 | 1066 | ||
| 1069 | static void iwl_bg_scan_completed(struct work_struct *work) | 1067 | static void iwl_bg_scan_completed(struct work_struct *work) |
| @@ -1071,9 +1069,9 @@ static void iwl_bg_scan_completed(struct work_struct *work) | |||
| 1071 | struct iwl_priv *priv = | 1069 | struct iwl_priv *priv = |
| 1072 | container_of(work, struct iwl_priv, scan_completed); | 1070 | container_of(work, struct iwl_priv, scan_completed); |
| 1073 | 1071 | ||
| 1074 | mutex_lock(&priv->shrd->mutex); | 1072 | mutex_lock(&priv->mutex); |
| 1075 | iwl_process_scan_complete(priv); | 1073 | iwl_process_scan_complete(priv); |
| 1076 | mutex_unlock(&priv->shrd->mutex); | 1074 | mutex_unlock(&priv->mutex); |
| 1077 | } | 1075 | } |
| 1078 | 1076 | ||
| 1079 | void iwl_setup_scan_deferred_work(struct iwl_priv *priv) | 1077 | void iwl_setup_scan_deferred_work(struct iwl_priv *priv) |
| @@ -1091,8 +1089,8 @@ void iwl_cancel_scan_deferred_work(struct iwl_priv *priv) | |||
| 1091 | cancel_work_sync(&priv->scan_completed); | 1089 | cancel_work_sync(&priv->scan_completed); |
| 1092 | 1090 | ||
| 1093 | if (cancel_delayed_work_sync(&priv->scan_check)) { | 1091 | if (cancel_delayed_work_sync(&priv->scan_check)) { |
| 1094 | mutex_lock(&priv->shrd->mutex); | 1092 | mutex_lock(&priv->mutex); |
| 1095 | iwl_force_scan_end(priv); | 1093 | iwl_force_scan_end(priv); |
| 1096 | mutex_unlock(&priv->shrd->mutex); | 1094 | mutex_unlock(&priv->mutex); |
| 1097 | } | 1095 | } |
| 1098 | } | 1096 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index a6441623e6b1..cf34087aa2fe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h | |||
| @@ -65,12 +65,11 @@ | |||
| 65 | 65 | ||
| 66 | #include <linux/types.h> | 66 | #include <linux/types.h> |
| 67 | #include <linux/spinlock.h> | 67 | #include <linux/spinlock.h> |
| 68 | #include <linux/mutex.h> | ||
| 69 | #include <linux/gfp.h> | 68 | #include <linux/gfp.h> |
| 70 | #include <linux/mm.h> /* for page_address */ | ||
| 71 | #include <net/mac80211.h> | 69 | #include <net/mac80211.h> |
| 72 | 70 | ||
| 73 | #include "iwl-commands.h" | 71 | #include "iwl-commands.h" |
| 72 | #include "iwl-fw.h" | ||
| 74 | 73 | ||
| 75 | /** | 74 | /** |
| 76 | * DOC: shared area - role and goal | 75 | * DOC: shared area - role and goal |
| @@ -116,7 +115,6 @@ extern struct iwl_mod_params iwlagn_mod_params; | |||
| 116 | * Holds the module parameters | 115 | * Holds the module parameters |
| 117 | * | 116 | * |
| 118 | * @sw_crypto: using hardware encryption, default = 0 | 117 | * @sw_crypto: using hardware encryption, default = 0 |
| 119 | * @num_of_queues: number of tx queue, HW dependent | ||
| 120 | * @disable_11n: disable 11n capabilities, default = 0, | 118 | * @disable_11n: disable 11n capabilities, default = 0, |
| 121 | * use IWL_DISABLE_HT_* constants | 119 | * use IWL_DISABLE_HT_* constants |
| 122 | * @amsdu_size_8K: enable 8K amsdu size, default = 1 | 120 | * @amsdu_size_8K: enable 8K amsdu size, default = 1 |
| @@ -138,7 +136,6 @@ extern struct iwl_mod_params iwlagn_mod_params; | |||
| 138 | */ | 136 | */ |
| 139 | struct iwl_mod_params { | 137 | struct iwl_mod_params { |
| 140 | int sw_crypto; | 138 | int sw_crypto; |
| 141 | int num_of_queues; | ||
| 142 | unsigned int disable_11n; | 139 | unsigned int disable_11n; |
| 143 | int amsdu_size_8K; | 140 | int amsdu_size_8K; |
| 144 | int antenna; | 141 | int antenna; |
| @@ -163,7 +160,6 @@ struct iwl_mod_params { | |||
| 163 | * | 160 | * |
| 164 | * Holds the module parameters | 161 | * Holds the module parameters |
| 165 | * | 162 | * |
| 166 | * @max_txq_num: Max # Tx queues supported | ||
| 167 | * @num_ampdu_queues: num of ampdu queues | 163 | * @num_ampdu_queues: num of ampdu queues |
| 168 | * @tx_chains_num: Number of TX chains | 164 | * @tx_chains_num: Number of TX chains |
| 169 | * @rx_chains_num: Number of RX chains | 165 | * @rx_chains_num: Number of RX chains |
| @@ -177,16 +173,16 @@ struct iwl_mod_params { | |||
| 177 | * relevant for 1000, 6000 and up | 173 | * relevant for 1000, 6000 and up |
| 178 | * @wd_timeout: TX queues watchdog timeout | 174 | * @wd_timeout: TX queues watchdog timeout |
| 179 | * @struct iwl_sensitivity_ranges: range of sensitivity values | 175 | * @struct iwl_sensitivity_ranges: range of sensitivity values |
| 176 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic | ||
| 180 | */ | 177 | */ |
| 181 | struct iwl_hw_params { | 178 | struct iwl_hw_params { |
| 182 | u8 max_txq_num; | ||
| 183 | u8 num_ampdu_queues; | 179 | u8 num_ampdu_queues; |
| 184 | u8 tx_chains_num; | 180 | u8 tx_chains_num; |
| 185 | u8 rx_chains_num; | 181 | u8 rx_chains_num; |
| 186 | u8 valid_tx_ant; | 182 | u8 valid_tx_ant; |
| 187 | u8 valid_rx_ant; | 183 | u8 valid_rx_ant; |
| 188 | u8 ht40_channel; | 184 | u8 ht40_channel; |
| 189 | bool shadow_reg_enable; | 185 | bool use_rts_for_aggregation; |
| 190 | u16 sku; | 186 | u16 sku; |
| 191 | u32 rx_page_order; | 187 | u32 rx_page_order; |
| 192 | u32 ct_kill_threshold; | 188 | u32 ct_kill_threshold; |
| @@ -213,45 +209,6 @@ enum iwl_ucode_type { | |||
| 213 | IWL_UCODE_WOWLAN, | 209 | IWL_UCODE_WOWLAN, |
| 214 | }; | 210 | }; |
| 215 | 211 | ||
| 216 | /** | ||
| 217 | * struct iwl_notification_wait - notification wait entry | ||
| 218 | * @list: list head for global list | ||
| 219 | * @fn: function called with the notification | ||
| 220 | * @cmd: command ID | ||
| 221 | * | ||
| 222 | * This structure is not used directly, to wait for a | ||
| 223 | * notification declare it on the stack, and call | ||
| 224 | * iwlagn_init_notification_wait() with appropriate | ||
| 225 | * parameters. Then do whatever will cause the ucode | ||
| 226 | * to notify the driver, and to wait for that then | ||
| 227 | * call iwlagn_wait_notification(). | ||
| 228 | * | ||
| 229 | * Each notification is one-shot. If at some point we | ||
| 230 | * need to support multi-shot notifications (which | ||
| 231 | * can't be allocated on the stack) we need to modify | ||
| 232 | * the code for them. | ||
| 233 | */ | ||
| 234 | struct iwl_notification_wait { | ||
| 235 | struct list_head list; | ||
| 236 | |||
| 237 | void (*fn)(struct iwl_trans *trans, struct iwl_rx_packet *pkt, | ||
| 238 | void *data); | ||
| 239 | void *fn_data; | ||
| 240 | |||
| 241 | u8 cmd; | ||
| 242 | bool triggered, aborted; | ||
| 243 | }; | ||
| 244 | |||
| 245 | /** | ||
| 246 | * enum iwl_pa_type - Power Amplifier type | ||
| 247 | * @IWL_PA_SYSTEM: based on uCode configuration | ||
| 248 | * @IWL_PA_INTERNAL: use Internal only | ||
| 249 | */ | ||
| 250 | enum iwl_pa_type { | ||
| 251 | IWL_PA_SYSTEM = 0, | ||
| 252 | IWL_PA_INTERNAL = 1, | ||
| 253 | }; | ||
| 254 | |||
| 255 | /* | 212 | /* |
| 256 | * LED mode | 213 | * LED mode |
| 257 | * IWL_LED_DEFAULT: use device default | 214 | * IWL_LED_DEFAULT: use device default |
| @@ -268,6 +225,73 @@ enum iwl_led_mode { | |||
| 268 | IWL_LED_DISABLE, | 225 | IWL_LED_DISABLE, |
| 269 | }; | 226 | }; |
| 270 | 227 | ||
| 228 | /* | ||
| 229 | * @max_ll_items: max number of OTP blocks | ||
| 230 | * @shadow_ram_support: shadow support for OTP memory | ||
| 231 | * @led_compensation: compensate on the led on/off time per HW according | ||
| 232 | * to the deviation to achieve the desired led frequency. | ||
| 233 | * The detail algorithm is described in iwl-led.c | ||
| 234 | * @chain_noise_num_beacons: number of beacons used to compute chain noise | ||
| 235 | * @adv_thermal_throttle: support advance thermal throttle | ||
| 236 | * @support_ct_kill_exit: support ct kill exit condition | ||
| 237 | * @support_wimax_coexist: support wimax/wifi co-exist | ||
| 238 | * @plcp_delta_threshold: plcp error rate threshold used to trigger | ||
| 239 | * radio tuning when there is a high receiving plcp error rate | ||
| 240 | * @chain_noise_scale: default chain noise scale used for gain computation | ||
| 241 | * @wd_timeout: TX queues watchdog timeout | ||
| 242 | * @max_event_log_size: size of event log buffer size for ucode event logging | ||
| 243 | * @shadow_reg_enable: HW shadhow register bit | ||
| 244 | * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up | ||
| 245 | * @no_idle_support: do not support idle mode | ||
| 246 | * wd_disable: disable watchdog timer | ||
| 247 | */ | ||
| 248 | struct iwl_base_params { | ||
| 249 | int eeprom_size; | ||
| 250 | int num_of_queues; /* def: HW dependent */ | ||
| 251 | int num_of_ampdu_queues;/* def: HW dependent */ | ||
| 252 | /* for iwl_apm_init() */ | ||
| 253 | u32 pll_cfg_val; | ||
| 254 | |||
| 255 | const u16 max_ll_items; | ||
| 256 | const bool shadow_ram_support; | ||
| 257 | u16 led_compensation; | ||
| 258 | bool adv_thermal_throttle; | ||
| 259 | bool support_ct_kill_exit; | ||
| 260 | const bool support_wimax_coexist; | ||
| 261 | u8 plcp_delta_threshold; | ||
| 262 | s32 chain_noise_scale; | ||
| 263 | unsigned int wd_timeout; | ||
| 264 | u32 max_event_log_size; | ||
| 265 | const bool shadow_reg_enable; | ||
| 266 | const bool hd_v2; | ||
| 267 | const bool no_idle_support; | ||
| 268 | const bool wd_disable; | ||
| 269 | }; | ||
| 270 | |||
| 271 | /* | ||
| 272 | * @advanced_bt_coexist: support advanced bt coexist | ||
| 273 | * @bt_init_traffic_load: specify initial bt traffic load | ||
| 274 | * @bt_prio_boost: default bt priority boost value | ||
| 275 | * @agg_time_limit: maximum number of uSec in aggregation | ||
| 276 | * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode | ||
| 277 | */ | ||
| 278 | struct iwl_bt_params { | ||
| 279 | bool advanced_bt_coexist; | ||
| 280 | u8 bt_init_traffic_load; | ||
| 281 | u8 bt_prio_boost; | ||
| 282 | u16 agg_time_limit; | ||
| 283 | bool bt_sco_disable; | ||
| 284 | bool bt_session_2; | ||
| 285 | }; | ||
| 286 | /* | ||
| 287 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic | ||
| 288 | */ | ||
| 289 | struct iwl_ht_params { | ||
| 290 | const bool ht_greenfield_support; /* if used set to true */ | ||
| 291 | bool use_rts_for_aggregation; | ||
| 292 | enum ieee80211_smps_mode smps_mode; | ||
| 293 | }; | ||
| 294 | |||
| 271 | /** | 295 | /** |
| 272 | * struct iwl_cfg | 296 | * struct iwl_cfg |
| 273 | * @name: Offical name of the device | 297 | * @name: Offical name of the device |
| @@ -282,7 +306,6 @@ enum iwl_led_mode { | |||
| 282 | * @max_data_size: The maximal length of the fw data section | 306 | * @max_data_size: The maximal length of the fw data section |
| 283 | * @valid_tx_ant: valid transmit antenna | 307 | * @valid_tx_ant: valid transmit antenna |
| 284 | * @valid_rx_ant: valid receive antenna | 308 | * @valid_rx_ant: valid receive antenna |
| 285 | * @sku: sku information from EEPROM | ||
| 286 | * @eeprom_ver: EEPROM version | 309 | * @eeprom_ver: EEPROM version |
| 287 | * @eeprom_calib_ver: EEPROM calibration version | 310 | * @eeprom_calib_ver: EEPROM calibration version |
| 288 | * @lib: pointer to the lib ops | 311 | * @lib: pointer to the lib ops |
| @@ -290,7 +313,6 @@ enum iwl_led_mode { | |||
| 290 | * @base_params: pointer to basic parameters | 313 | * @base_params: pointer to basic parameters |
| 291 | * @ht_params: point to ht patameters | 314 | * @ht_params: point to ht patameters |
| 292 | * @bt_params: pointer to bt parameters | 315 | * @bt_params: pointer to bt parameters |
| 293 | * @pa_type: used by 6000 series only to identify the type of Power Amplifier | ||
| 294 | * @need_temp_offset_calib: need to perform temperature offset calibration | 316 | * @need_temp_offset_calib: need to perform temperature offset calibration |
| 295 | * @no_xtal_calib: some devices do not need crystal calibration data, | 317 | * @no_xtal_calib: some devices do not need crystal calibration data, |
| 296 | * don't send it to those | 318 | * don't send it to those |
| @@ -321,17 +343,15 @@ struct iwl_cfg { | |||
| 321 | const u32 max_inst_size; | 343 | const u32 max_inst_size; |
| 322 | u8 valid_tx_ant; | 344 | u8 valid_tx_ant; |
| 323 | u8 valid_rx_ant; | 345 | u8 valid_rx_ant; |
| 324 | u16 sku; | ||
| 325 | u16 eeprom_ver; | 346 | u16 eeprom_ver; |
| 326 | u16 eeprom_calib_ver; | 347 | u16 eeprom_calib_ver; |
| 327 | const struct iwl_lib_ops *lib; | 348 | const struct iwl_lib_ops *lib; |
| 328 | void (*additional_nic_config)(struct iwl_priv *priv); | 349 | void (*additional_nic_config)(struct iwl_priv *priv); |
| 329 | /* params not likely to change within a device family */ | 350 | /* params not likely to change within a device family */ |
| 330 | struct iwl_base_params *base_params; | 351 | const struct iwl_base_params *base_params; |
| 331 | /* params likely to change within a device family */ | 352 | /* params likely to change within a device family */ |
| 332 | struct iwl_ht_params *ht_params; | 353 | const struct iwl_ht_params *ht_params; |
| 333 | struct iwl_bt_params *bt_params; | 354 | const struct iwl_bt_params *bt_params; |
| 334 | enum iwl_pa_type pa_type; /* if used set to IWL_PA_SYSTEM */ | ||
| 335 | const bool need_temp_offset_calib; /* if used set to true */ | 355 | const bool need_temp_offset_calib; /* if used set to true */ |
| 336 | const bool no_xtal_calib; | 356 | const bool no_xtal_calib; |
| 337 | u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; | 357 | u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; |
| @@ -346,10 +366,6 @@ struct iwl_cfg { | |||
| 346 | /** | 366 | /** |
| 347 | * struct iwl_shared - shared fields for all the layers of the driver | 367 | * struct iwl_shared - shared fields for all the layers of the driver |
| 348 | * | 368 | * |
| 349 | * @dbg_level_dev: dbg level set per device. Prevails on | ||
| 350 | * iwlagn_mod_params.debug_level if set (!= 0) | ||
| 351 | * @ucode_owner: IWL_OWNERSHIP_* | ||
| 352 | * @cmd_queue: command queue number | ||
| 353 | * @status: STATUS_* | 369 | * @status: STATUS_* |
| 354 | * @wowlan: are we running wowlan uCode | 370 | * @wowlan: are we running wowlan uCode |
| 355 | * @valid_contexts: microcode/device supports multiple contexts | 371 | * @valid_contexts: microcode/device supports multiple contexts |
| @@ -360,39 +376,20 @@ struct iwl_cfg { | |||
| 360 | * @nic: pointer to the nic data | 376 | * @nic: pointer to the nic data |
| 361 | * @hw_params: see struct iwl_hw_params | 377 | * @hw_params: see struct iwl_hw_params |
| 362 | * @lock: protect general shared data | 378 | * @lock: protect general shared data |
| 363 | * @sta_lock: protects the station table. | 379 | * @wait_command_queue: the wait_queue for SYNC host commands |
| 364 | * If lock and sta_lock are needed, lock must be acquired first. | ||
| 365 | * @mutex: | ||
| 366 | * @wait_command_queue: the wait_queue for SYNC host command nad uCode load | ||
| 367 | * @eeprom: pointer to the eeprom/OTP image | 380 | * @eeprom: pointer to the eeprom/OTP image |
| 368 | * @ucode_type: indicator of loaded ucode image | 381 | * @ucode_type: indicator of loaded ucode image |
| 369 | * @notif_waits: things waiting for notification | ||
| 370 | * @notif_wait_lock: lock protecting notification | ||
| 371 | * @notif_waitq: head of notification wait queue | ||
| 372 | * @device_pointers: pointers to ucode event tables | 382 | * @device_pointers: pointers to ucode event tables |
| 373 | */ | 383 | */ |
| 374 | struct iwl_shared { | 384 | struct iwl_shared { |
| 375 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
| 376 | u32 dbg_level_dev; | ||
| 377 | #endif /* CONFIG_IWLWIFI_DEBUG */ | ||
| 378 | |||
| 379 | #define IWL_OWNERSHIP_DRIVER 0 | ||
| 380 | #define IWL_OWNERSHIP_TM 1 | ||
| 381 | u8 ucode_owner; | ||
| 382 | u8 cmd_queue; | ||
| 383 | unsigned long status; | 385 | unsigned long status; |
| 384 | bool wowlan; | ||
| 385 | u8 valid_contexts; | 386 | u8 valid_contexts; |
| 386 | 387 | ||
| 387 | struct iwl_cfg *cfg; | 388 | const struct iwl_cfg *cfg; |
| 388 | struct iwl_priv *priv; | ||
| 389 | struct iwl_trans *trans; | 389 | struct iwl_trans *trans; |
| 390 | struct iwl_nic *nic; | 390 | void *drv; |
| 391 | struct iwl_hw_params hw_params; | 391 | struct iwl_hw_params hw_params; |
| 392 | 392 | const struct iwl_fw *fw; | |
| 393 | spinlock_t lock; | ||
| 394 | spinlock_t sta_lock; | ||
| 395 | struct mutex mutex; | ||
| 396 | 393 | ||
| 397 | wait_queue_head_t wait_command_queue; | 394 | wait_queue_head_t wait_command_queue; |
| 398 | 395 | ||
| @@ -402,11 +399,6 @@ struct iwl_shared { | |||
| 402 | /* ucode related variables */ | 399 | /* ucode related variables */ |
| 403 | enum iwl_ucode_type ucode_type; | 400 | enum iwl_ucode_type ucode_type; |
| 404 | 401 | ||
| 405 | /* notification wait support */ | ||
| 406 | struct list_head notif_waits; | ||
| 407 | spinlock_t notif_wait_lock; | ||
| 408 | wait_queue_head_t notif_waitq; | ||
| 409 | |||
| 410 | struct { | 402 | struct { |
| 411 | u32 error_event_table; | 403 | u32 error_event_table; |
| 412 | u32 log_event_table; | 404 | u32 log_event_table; |
| @@ -415,111 +407,13 @@ struct iwl_shared { | |||
| 415 | }; | 407 | }; |
| 416 | 408 | ||
| 417 | /*Whatever _m is (iwl_trans, iwl_priv, these macros will work */ | 409 | /*Whatever _m is (iwl_trans, iwl_priv, these macros will work */ |
| 418 | #define priv(_m) ((_m)->shrd->priv) | ||
| 419 | #define cfg(_m) ((_m)->shrd->cfg) | 410 | #define cfg(_m) ((_m)->shrd->cfg) |
| 420 | #define nic(_m) ((_m)->shrd->nic) | ||
| 421 | #define trans(_m) ((_m)->shrd->trans) | 411 | #define trans(_m) ((_m)->shrd->trans) |
| 422 | #define hw_params(_m) ((_m)->shrd->hw_params) | 412 | #define hw_params(_m) ((_m)->shrd->hw_params) |
| 423 | 413 | ||
| 424 | #ifdef CONFIG_IWLWIFI_DEBUG | 414 | static inline bool iwl_have_debug_level(u32 level) |
| 425 | /* | ||
| 426 | * iwl_get_debug_level: Return active debug level for device | ||
| 427 | * | ||
| 428 | * Using sysfs it is possible to set per device debug level. This debug | ||
| 429 | * level will be used if set, otherwise the global debug level which can be | ||
| 430 | * set via module parameter is used. | ||
| 431 | */ | ||
| 432 | static inline u32 iwl_get_debug_level(struct iwl_shared *shrd) | ||
| 433 | { | ||
| 434 | if (shrd->dbg_level_dev) | ||
| 435 | return shrd->dbg_level_dev; | ||
| 436 | else | ||
| 437 | return iwlagn_mod_params.debug_level; | ||
| 438 | } | ||
| 439 | #else | ||
| 440 | static inline u32 iwl_get_debug_level(struct iwl_shared *shrd) | ||
| 441 | { | ||
| 442 | return iwlagn_mod_params.debug_level; | ||
| 443 | } | ||
| 444 | #endif | ||
| 445 | |||
| 446 | static inline void iwl_free_pages(struct iwl_shared *shrd, unsigned long page) | ||
| 447 | { | 415 | { |
| 448 | free_pages(page, shrd->hw_params.rx_page_order); | 416 | return iwlagn_mod_params.debug_level & level; |
| 449 | } | ||
| 450 | |||
| 451 | /** | ||
| 452 | * iwl_queue_inc_wrap - increment queue index, wrap back to beginning | ||
| 453 | * @index -- current index | ||
| 454 | * @n_bd -- total number of entries in queue (must be power of 2) | ||
| 455 | */ | ||
| 456 | static inline int iwl_queue_inc_wrap(int index, int n_bd) | ||
| 457 | { | ||
| 458 | return ++index & (n_bd - 1); | ||
| 459 | } | ||
| 460 | |||
| 461 | /** | ||
| 462 | * iwl_queue_dec_wrap - decrement queue index, wrap back to end | ||
| 463 | * @index -- current index | ||
| 464 | * @n_bd -- total number of entries in queue (must be power of 2) | ||
| 465 | */ | ||
| 466 | static inline int iwl_queue_dec_wrap(int index, int n_bd) | ||
| 467 | { | ||
| 468 | return --index & (n_bd - 1); | ||
| 469 | } | ||
| 470 | |||
| 471 | struct iwl_rx_mem_buffer { | ||
| 472 | dma_addr_t page_dma; | ||
| 473 | struct page *page; | ||
| 474 | struct list_head list; | ||
| 475 | }; | ||
| 476 | |||
| 477 | #define rxb_addr(r) page_address(r->page) | ||
| 478 | |||
| 479 | /* | ||
| 480 | * mac80211 queues, ACs, hardware queues, FIFOs. | ||
| 481 | * | ||
| 482 | * Cf. http://wireless.kernel.org/en/developers/Documentation/mac80211/queues | ||
| 483 | * | ||
| 484 | * Mac80211 uses the following numbers, which we get as from it | ||
| 485 | * by way of skb_get_queue_mapping(skb): | ||
| 486 | * | ||
| 487 | * VO 0 | ||
| 488 | * VI 1 | ||
| 489 | * BE 2 | ||
| 490 | * BK 3 | ||
| 491 | * | ||
| 492 | * | ||
| 493 | * Regular (not A-MPDU) frames are put into hardware queues corresponding | ||
| 494 | * to the FIFOs, see comments in iwl-prph.h. Aggregated frames get their | ||
| 495 | * own queue per aggregation session (RA/TID combination), such queues are | ||
| 496 | * set up to map into FIFOs too, for which we need an AC->FIFO mapping. In | ||
| 497 | * order to map frames to the right queue, we also need an AC->hw queue | ||
| 498 | * mapping. This is implemented here. | ||
| 499 | * | ||
| 500 | * Due to the way hw queues are set up (by the hw specific modules like | ||
| 501 | * iwl-4965.c, iwl-5000.c etc.), the AC->hw queue mapping is the identity | ||
| 502 | * mapping. | ||
| 503 | */ | ||
| 504 | |||
| 505 | static const u8 tid_to_ac[] = { | ||
| 506 | IEEE80211_AC_BE, | ||
| 507 | IEEE80211_AC_BK, | ||
| 508 | IEEE80211_AC_BK, | ||
| 509 | IEEE80211_AC_BE, | ||
| 510 | IEEE80211_AC_VI, | ||
| 511 | IEEE80211_AC_VI, | ||
| 512 | IEEE80211_AC_VO, | ||
| 513 | IEEE80211_AC_VO | ||
| 514 | }; | ||
| 515 | |||
| 516 | static inline int get_ac_from_tid(u16 tid) | ||
| 517 | { | ||
| 518 | if (likely(tid < ARRAY_SIZE(tid_to_ac))) | ||
| 519 | return tid_to_ac[tid]; | ||
| 520 | |||
| 521 | /* no support for TIDs 8-15 yet */ | ||
| 522 | return -EINVAL; | ||
| 523 | } | 417 | } |
| 524 | 418 | ||
| 525 | enum iwl_rxon_context_id { | 419 | enum iwl_rxon_context_id { |
| @@ -530,34 +424,9 @@ enum iwl_rxon_context_id { | |||
| 530 | }; | 424 | }; |
| 531 | 425 | ||
| 532 | int iwlagn_hw_valid_rtc_data_addr(u32 addr); | 426 | int iwlagn_hw_valid_rtc_data_addr(u32 addr); |
| 533 | void iwl_nic_config(struct iwl_priv *priv); | ||
| 534 | const char *get_cmd_string(u8 cmd); | 427 | const char *get_cmd_string(u8 cmd); |
| 535 | bool iwl_check_for_ct_kill(struct iwl_priv *priv); | ||
| 536 | |||
| 537 | |||
| 538 | /* notification wait support */ | ||
| 539 | void iwl_abort_notification_waits(struct iwl_shared *shrd); | ||
| 540 | void __acquires(wait_entry) | ||
| 541 | iwl_init_notification_wait(struct iwl_shared *shrd, | ||
| 542 | struct iwl_notification_wait *wait_entry, | ||
| 543 | u8 cmd, | ||
| 544 | void (*fn)(struct iwl_trans *trans, | ||
| 545 | struct iwl_rx_packet *pkt, | ||
| 546 | void *data), | ||
| 547 | void *fn_data); | ||
| 548 | int __must_check __releases(wait_entry) | ||
| 549 | iwl_wait_notification(struct iwl_shared *shrd, | ||
| 550 | struct iwl_notification_wait *wait_entry, | ||
| 551 | unsigned long timeout); | ||
| 552 | void __releases(wait_entry) | ||
| 553 | iwl_remove_notification(struct iwl_shared *shrd, | ||
| 554 | struct iwl_notification_wait *wait_entry); | ||
| 555 | 428 | ||
| 556 | #define IWL_CMD(x) case x: return #x | 429 | #define IWL_CMD(x) case x: return #x |
| 557 | #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) | ||
| 558 | |||
| 559 | #define IWL_TRAFFIC_ENTRIES (256) | ||
| 560 | #define IWL_TRAFFIC_ENTRY_SIZE (64) | ||
| 561 | 430 | ||
| 562 | /***************************************************** | 431 | /***************************************************** |
| 563 | * DRIVER STATUS FUNCTIONS | 432 | * DRIVER STATUS FUNCTIONS |
| @@ -583,46 +452,4 @@ iwl_remove_notification(struct iwl_shared *shrd, | |||
| 583 | #define STATUS_CHANNEL_SWITCH_PENDING 19 | 452 | #define STATUS_CHANNEL_SWITCH_PENDING 19 |
| 584 | #define STATUS_SCAN_COMPLETE 20 | 453 | #define STATUS_SCAN_COMPLETE 20 |
| 585 | 454 | ||
| 586 | static inline int iwl_is_ready(struct iwl_shared *shrd) | ||
| 587 | { | ||
| 588 | /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are | ||
| 589 | * set but EXIT_PENDING is not */ | ||
| 590 | return test_bit(STATUS_READY, &shrd->status) && | ||
| 591 | test_bit(STATUS_GEO_CONFIGURED, &shrd->status) && | ||
| 592 | !test_bit(STATUS_EXIT_PENDING, &shrd->status); | ||
| 593 | } | ||
| 594 | |||
| 595 | static inline int iwl_is_alive(struct iwl_shared *shrd) | ||
| 596 | { | ||
| 597 | return test_bit(STATUS_ALIVE, &shrd->status); | ||
| 598 | } | ||
| 599 | |||
| 600 | static inline int iwl_is_init(struct iwl_shared *shrd) | ||
| 601 | { | ||
| 602 | return test_bit(STATUS_INIT, &shrd->status); | ||
| 603 | } | ||
| 604 | |||
| 605 | static inline int iwl_is_rfkill_hw(struct iwl_shared *shrd) | ||
| 606 | { | ||
| 607 | return test_bit(STATUS_RF_KILL_HW, &shrd->status); | ||
| 608 | } | ||
| 609 | |||
| 610 | static inline int iwl_is_rfkill(struct iwl_shared *shrd) | ||
| 611 | { | ||
| 612 | return iwl_is_rfkill_hw(shrd); | ||
| 613 | } | ||
| 614 | |||
| 615 | static inline int iwl_is_ctkill(struct iwl_shared *shrd) | ||
| 616 | { | ||
| 617 | return test_bit(STATUS_CT_KILL, &shrd->status); | ||
| 618 | } | ||
| 619 | |||
| 620 | static inline int iwl_is_ready_rf(struct iwl_shared *shrd) | ||
| 621 | { | ||
| 622 | if (iwl_is_rfkill(shrd)) | ||
| 623 | return 0; | ||
| 624 | |||
| 625 | return iwl_is_ready(shrd); | ||
| 626 | } | ||
| 627 | |||
| 628 | #endif /* #__iwl_shared_h__ */ | 455 | #endif /* #__iwl_shared_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 23eea06a74ad..b06c6763cb7a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c | |||
| @@ -70,7 +70,6 @@ | |||
| 70 | #include <net/mac80211.h> | 70 | #include <net/mac80211.h> |
| 71 | #include <net/netlink.h> | 71 | #include <net/netlink.h> |
| 72 | 72 | ||
| 73 | #include "iwl-wifi.h" | ||
| 74 | #include "iwl-dev.h" | 73 | #include "iwl-dev.h" |
| 75 | #include "iwl-core.h" | 74 | #include "iwl-core.h" |
| 76 | #include "iwl-debug.h" | 75 | #include "iwl-debug.h" |
| @@ -79,6 +78,7 @@ | |||
| 79 | #include "iwl-testmode.h" | 78 | #include "iwl-testmode.h" |
| 80 | #include "iwl-trans.h" | 79 | #include "iwl-trans.h" |
| 81 | #include "iwl-fh.h" | 80 | #include "iwl-fh.h" |
| 81 | #include "iwl-prph.h" | ||
| 82 | 82 | ||
| 83 | 83 | ||
| 84 | /* Periphery registers absolute lower bound. This is used in order to | 84 | /* Periphery registers absolute lower bound. This is used in order to |
| @@ -125,13 +125,15 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { | |||
| 125 | [IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, }, | 125 | [IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, }, |
| 126 | [IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, }, | 126 | [IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, }, |
| 127 | [IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, }, | 127 | [IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, }, |
| 128 | |||
| 129 | [IWL_TM_ATTR_ENABLE_NOTIFICATION] = {.type = NLA_FLAG, }, | ||
| 128 | }; | 130 | }; |
| 129 | 131 | ||
| 130 | /* | 132 | /* |
| 131 | * See the struct iwl_rx_packet in iwl-commands.h for the format of the | 133 | * See the struct iwl_rx_packet in iwl-commands.h for the format of the |
| 132 | * received events from the device | 134 | * received events from the device |
| 133 | */ | 135 | */ |
| 134 | static inline int get_event_length(struct iwl_rx_mem_buffer *rxb) | 136 | static inline int get_event_length(struct iwl_rx_cmd_buffer *rxb) |
| 135 | { | 137 | { |
| 136 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 138 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 137 | if (pkt) | 139 | if (pkt) |
| @@ -162,7 +164,7 @@ static inline int get_event_length(struct iwl_rx_mem_buffer *rxb) | |||
| 162 | */ | 164 | */ |
| 163 | 165 | ||
| 164 | static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv, | 166 | static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv, |
| 165 | struct iwl_rx_mem_buffer *rxb) | 167 | struct iwl_rx_cmd_buffer *rxb) |
| 166 | { | 168 | { |
| 167 | struct ieee80211_hw *hw = priv->hw; | 169 | struct ieee80211_hw *hw = priv->hw; |
| 168 | struct sk_buff *skb; | 170 | struct sk_buff *skb; |
| @@ -183,7 +185,8 @@ static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv, | |||
| 183 | return; | 185 | return; |
| 184 | } | 186 | } |
| 185 | NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT); | 187 | NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT); |
| 186 | NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data); | 188 | /* the length doesn't include len_n_flags field, so add it manually */ |
| 189 | NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length + sizeof(__le32), data); | ||
| 187 | cfg80211_testmode_event(skb, GFP_ATOMIC); | 190 | cfg80211_testmode_event(skb, GFP_ATOMIC); |
| 188 | return; | 191 | return; |
| 189 | 192 | ||
| @@ -194,7 +197,7 @@ nla_put_failure: | |||
| 194 | 197 | ||
| 195 | void iwl_testmode_init(struct iwl_priv *priv) | 198 | void iwl_testmode_init(struct iwl_priv *priv) |
| 196 | { | 199 | { |
| 197 | priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; | 200 | priv->pre_rx_handler = NULL; |
| 198 | priv->testmode_trace.trace_enabled = false; | 201 | priv->testmode_trace.trace_enabled = false; |
| 199 | priv->testmode_mem.read_in_progress = false; | 202 | priv->testmode_mem.read_in_progress = false; |
| 200 | } | 203 | } |
| @@ -283,7 +286,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb) | |||
| 283 | IWL_DEBUG_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x," | 286 | IWL_DEBUG_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x," |
| 284 | " len %d\n", cmd.id, cmd.flags, cmd.len[0]); | 287 | " len %d\n", cmd.id, cmd.flags, cmd.len[0]); |
| 285 | 288 | ||
| 286 | ret = iwl_trans_send_cmd(trans(priv), &cmd); | 289 | ret = iwl_dvm_send_cmd(priv, &cmd); |
| 287 | if (ret) { | 290 | if (ret) { |
| 288 | IWL_ERR(priv, "Failed to send hcmd\n"); | 291 | IWL_ERR(priv, "Failed to send hcmd\n"); |
| 289 | return ret; | 292 | return ret; |
| @@ -292,7 +295,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb) | |||
| 292 | return ret; | 295 | return ret; |
| 293 | 296 | ||
| 294 | /* Handling return of SKB to the user */ | 297 | /* Handling return of SKB to the user */ |
| 295 | pkt = (struct iwl_rx_packet *)cmd.reply_page; | 298 | pkt = cmd.resp_pkt; |
| 296 | if (!pkt) { | 299 | if (!pkt) { |
| 297 | IWL_ERR(priv, "HCMD received a null response packet\n"); | 300 | IWL_ERR(priv, "HCMD received a null response packet\n"); |
| 298 | return ret; | 301 | return ret; |
| @@ -309,7 +312,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb) | |||
| 309 | 312 | ||
| 310 | /* The reply is in a page, that we cannot send to user space. */ | 313 | /* The reply is in a page, that we cannot send to user space. */ |
| 311 | memcpy(reply_buf, &(pkt->hdr), reply_len); | 314 | memcpy(reply_buf, &(pkt->hdr), reply_len); |
| 312 | iwl_free_pages(priv->shrd, cmd.reply_page); | 315 | iwl_free_resp(&cmd); |
| 313 | 316 | ||
| 314 | NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT); | 317 | NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT); |
| 315 | NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf); | 318 | NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf); |
| @@ -419,23 +422,23 @@ static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv) | |||
| 419 | struct iwl_notification_wait calib_wait; | 422 | struct iwl_notification_wait calib_wait; |
| 420 | int ret; | 423 | int ret; |
| 421 | 424 | ||
| 422 | iwl_init_notification_wait(priv->shrd, &calib_wait, | 425 | iwl_init_notification_wait(&priv->notif_wait, &calib_wait, |
| 423 | CALIBRATION_COMPLETE_NOTIFICATION, | 426 | CALIBRATION_COMPLETE_NOTIFICATION, |
| 424 | NULL, NULL); | 427 | NULL, NULL); |
| 425 | ret = iwl_init_alive_start(trans(priv)); | 428 | ret = iwl_init_alive_start(priv); |
| 426 | if (ret) { | 429 | if (ret) { |
| 427 | IWL_ERR(priv, "Fail init calibration: %d\n", ret); | 430 | IWL_ERR(priv, "Fail init calibration: %d\n", ret); |
| 428 | goto cfg_init_calib_error; | 431 | goto cfg_init_calib_error; |
| 429 | } | 432 | } |
| 430 | 433 | ||
| 431 | ret = iwl_wait_notification(priv->shrd, &calib_wait, 2 * HZ); | 434 | ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, 2 * HZ); |
| 432 | if (ret) | 435 | if (ret) |
| 433 | IWL_ERR(priv, "Error detecting" | 436 | IWL_ERR(priv, "Error detecting" |
| 434 | " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret); | 437 | " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret); |
| 435 | return ret; | 438 | return ret; |
| 436 | 439 | ||
| 437 | cfg_init_calib_error: | 440 | cfg_init_calib_error: |
| 438 | iwl_remove_notification(priv->shrd, &calib_wait); | 441 | iwl_remove_notification(&priv->notif_wait, &calib_wait); |
| 439 | return ret; | 442 | return ret; |
| 440 | } | 443 | } |
| 441 | 444 | ||
| @@ -484,7 +487,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
| 484 | break; | 487 | break; |
| 485 | 488 | ||
| 486 | case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: | 489 | case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: |
| 487 | status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_INIT); | 490 | status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT); |
| 488 | if (status) | 491 | if (status) |
| 489 | IWL_ERR(priv, "Error loading init ucode: %d\n", status); | 492 | IWL_ERR(priv, "Error loading init ucode: %d\n", status); |
| 490 | break; | 493 | break; |
| @@ -495,7 +498,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
| 495 | break; | 498 | break; |
| 496 | 499 | ||
| 497 | case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: | 500 | case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: |
| 498 | status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_REGULAR); | 501 | status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR); |
| 499 | if (status) { | 502 | if (status) { |
| 500 | IWL_ERR(priv, | 503 | IWL_ERR(priv, |
| 501 | "Error loading runtime ucode: %d\n", status); | 504 | "Error loading runtime ucode: %d\n", status); |
| @@ -510,7 +513,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
| 510 | case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: | 513 | case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: |
| 511 | iwl_scan_cancel_timeout(priv, 200); | 514 | iwl_scan_cancel_timeout(priv, 200); |
| 512 | iwl_trans_stop_device(trans); | 515 | iwl_trans_stop_device(trans); |
| 513 | status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_WOWLAN); | 516 | status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); |
| 514 | if (status) { | 517 | if (status) { |
| 515 | IWL_ERR(priv, | 518 | IWL_ERR(priv, |
| 516 | "Error loading WOWLAN ucode: %d\n", status); | 519 | "Error loading WOWLAN ucode: %d\n", status); |
| @@ -553,7 +556,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
| 553 | 556 | ||
| 554 | case IWL_TM_CMD_APP2DEV_GET_FW_VERSION: | 557 | case IWL_TM_CMD_APP2DEV_GET_FW_VERSION: |
| 555 | IWL_INFO(priv, "uCode version raw: 0x%x\n", | 558 | IWL_INFO(priv, "uCode version raw: 0x%x\n", |
| 556 | nic(priv)->fw.ucode_ver); | 559 | priv->fw->ucode_ver); |
| 557 | 560 | ||
| 558 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); | 561 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); |
| 559 | if (!skb) { | 562 | if (!skb) { |
| @@ -561,7 +564,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
| 561 | return -ENOMEM; | 564 | return -ENOMEM; |
| 562 | } | 565 | } |
| 563 | NLA_PUT_U32(skb, IWL_TM_ATTR_FW_VERSION, | 566 | NLA_PUT_U32(skb, IWL_TM_ATTR_FW_VERSION, |
| 564 | nic(priv)->fw.ucode_ver); | 567 | priv->fw->ucode_ver); |
| 565 | status = cfg80211_testmode_reply(skb); | 568 | status = cfg80211_testmode_reply(skb); |
| 566 | if (status < 0) | 569 | if (status < 0) |
| 567 | IWL_ERR(priv, "Error sending msg : %d\n", status); | 570 | IWL_ERR(priv, "Error sending msg : %d\n", status); |
| @@ -590,16 +593,16 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
| 590 | } | 593 | } |
| 591 | switch (priv->shrd->ucode_type) { | 594 | switch (priv->shrd->ucode_type) { |
| 592 | case IWL_UCODE_REGULAR: | 595 | case IWL_UCODE_REGULAR: |
| 593 | inst_size = nic(priv)->fw.ucode_rt.code.len; | 596 | inst_size = priv->fw->ucode_rt.code.len; |
| 594 | data_size = nic(priv)->fw.ucode_rt.data.len; | 597 | data_size = priv->fw->ucode_rt.data.len; |
| 595 | break; | 598 | break; |
| 596 | case IWL_UCODE_INIT: | 599 | case IWL_UCODE_INIT: |
| 597 | inst_size = nic(priv)->fw.ucode_init.code.len; | 600 | inst_size = priv->fw->ucode_init.code.len; |
| 598 | data_size = nic(priv)->fw.ucode_init.data.len; | 601 | data_size = priv->fw->ucode_init.data.len; |
| 599 | break; | 602 | break; |
| 600 | case IWL_UCODE_WOWLAN: | 603 | case IWL_UCODE_WOWLAN: |
| 601 | inst_size = nic(priv)->fw.ucode_wowlan.code.len; | 604 | inst_size = priv->fw->ucode_wowlan.code.len; |
| 602 | data_size = nic(priv)->fw.ucode_wowlan.data.len; | 605 | data_size = priv->fw->ucode_wowlan.data.len; |
| 603 | break; | 606 | break; |
| 604 | case IWL_UCODE_NONE: | 607 | case IWL_UCODE_NONE: |
| 605 | IWL_ERR(priv, "No uCode has not been loaded\n"); | 608 | IWL_ERR(priv, "No uCode has not been loaded\n"); |
| @@ -713,7 +716,7 @@ nla_put_failure: | |||
| 713 | return -EMSGSIZE; | 716 | return -EMSGSIZE; |
| 714 | } | 717 | } |
| 715 | 718 | ||
| 716 | static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb, | 719 | static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, |
| 717 | struct sk_buff *skb, | 720 | struct sk_buff *skb, |
| 718 | struct netlink_callback *cb) | 721 | struct netlink_callback *cb) |
| 719 | { | 722 | { |
| @@ -770,9 +773,13 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb) | |||
| 770 | } | 773 | } |
| 771 | 774 | ||
| 772 | owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]); | 775 | owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]); |
| 773 | if ((owner == IWL_OWNERSHIP_DRIVER) || (owner == IWL_OWNERSHIP_TM)) | 776 | if (owner == IWL_OWNERSHIP_DRIVER) { |
| 774 | priv->shrd->ucode_owner = owner; | 777 | priv->ucode_owner = owner; |
| 775 | else { | 778 | priv->pre_rx_handler = NULL; |
| 779 | } else if (owner == IWL_OWNERSHIP_TM) { | ||
| 780 | priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; | ||
| 781 | priv->ucode_owner = owner; | ||
| 782 | } else { | ||
| 776 | IWL_ERR(priv, "Invalid owner\n"); | 783 | IWL_ERR(priv, "Invalid owner\n"); |
| 777 | return -EINVAL; | 784 | return -EINVAL; |
| 778 | } | 785 | } |
| @@ -905,9 +912,9 @@ static int iwl_testmode_indirect_mem(struct ieee80211_hw *hw, | |||
| 905 | } | 912 | } |
| 906 | } | 913 | } |
| 907 | 914 | ||
| 908 | static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw, struct nlattr **tb, | 915 | static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw, |
| 909 | struct sk_buff *skb, | 916 | struct sk_buff *skb, |
| 910 | struct netlink_callback *cb) | 917 | struct netlink_callback *cb) |
| 911 | { | 918 | { |
| 912 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 919 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
| 913 | int idx, length; | 920 | int idx, length; |
| @@ -937,6 +944,20 @@ static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw, struct nlattr **tb, | |||
| 937 | return -ENOBUFS; | 944 | return -ENOBUFS; |
| 938 | } | 945 | } |
| 939 | 946 | ||
| 947 | static int iwl_testmode_notifications(struct ieee80211_hw *hw, | ||
| 948 | struct nlattr **tb) | ||
| 949 | { | ||
| 950 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | ||
| 951 | bool enable; | ||
| 952 | |||
| 953 | enable = nla_get_flag(tb[IWL_TM_ATTR_ENABLE_NOTIFICATION]); | ||
| 954 | if (enable) | ||
| 955 | priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; | ||
| 956 | else | ||
| 957 | priv->pre_rx_handler = NULL; | ||
| 958 | return 0; | ||
| 959 | } | ||
| 960 | |||
| 940 | 961 | ||
| 941 | /* The testmode gnl message handler that takes the gnl message from the | 962 | /* The testmode gnl message handler that takes the gnl message from the |
| 942 | * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then | 963 | * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then |
| @@ -976,7 +997,7 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) | |||
| 976 | return -ENOMSG; | 997 | return -ENOMSG; |
| 977 | } | 998 | } |
| 978 | /* in case multiple accesses to the device happens */ | 999 | /* in case multiple accesses to the device happens */ |
| 979 | mutex_lock(&priv->shrd->mutex); | 1000 | mutex_lock(&priv->mutex); |
| 980 | 1001 | ||
| 981 | switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { | 1002 | switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { |
| 982 | case IWL_TM_CMD_APP2DEV_UCODE: | 1003 | case IWL_TM_CMD_APP2DEV_UCODE: |
| @@ -1022,13 +1043,19 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) | |||
| 1022 | result = iwl_testmode_indirect_mem(hw, tb); | 1043 | result = iwl_testmode_indirect_mem(hw, tb); |
| 1023 | break; | 1044 | break; |
| 1024 | 1045 | ||
| 1046 | case IWL_TM_CMD_APP2DEV_NOTIFICATIONS: | ||
| 1047 | IWL_DEBUG_INFO(priv, "testmode notifications cmd " | ||
| 1048 | "to driver\n"); | ||
| 1049 | result = iwl_testmode_notifications(hw, tb); | ||
| 1050 | break; | ||
| 1051 | |||
| 1025 | default: | 1052 | default: |
| 1026 | IWL_ERR(priv, "Unknown testmode command\n"); | 1053 | IWL_ERR(priv, "Unknown testmode command\n"); |
| 1027 | result = -ENOSYS; | 1054 | result = -ENOSYS; |
| 1028 | break; | 1055 | break; |
| 1029 | } | 1056 | } |
| 1030 | 1057 | ||
| 1031 | mutex_unlock(&priv->shrd->mutex); | 1058 | mutex_unlock(&priv->mutex); |
| 1032 | return result; | 1059 | return result; |
| 1033 | } | 1060 | } |
| 1034 | 1061 | ||
| @@ -1063,21 +1090,21 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
| 1063 | } | 1090 | } |
| 1064 | 1091 | ||
| 1065 | /* in case multiple accesses to the device happens */ | 1092 | /* in case multiple accesses to the device happens */ |
| 1066 | mutex_lock(&priv->shrd->mutex); | 1093 | mutex_lock(&priv->mutex); |
| 1067 | switch (cmd) { | 1094 | switch (cmd) { |
| 1068 | case IWL_TM_CMD_APP2DEV_READ_TRACE: | 1095 | case IWL_TM_CMD_APP2DEV_READ_TRACE: |
| 1069 | IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n"); | 1096 | IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n"); |
| 1070 | result = iwl_testmode_trace_dump(hw, tb, skb, cb); | 1097 | result = iwl_testmode_trace_dump(hw, skb, cb); |
| 1071 | break; | 1098 | break; |
| 1072 | case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP: | 1099 | case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP: |
| 1073 | IWL_DEBUG_INFO(priv, "testmode sram dump cmd to driver\n"); | 1100 | IWL_DEBUG_INFO(priv, "testmode sram dump cmd to driver\n"); |
| 1074 | result = iwl_testmode_buffer_dump(hw, tb, skb, cb); | 1101 | result = iwl_testmode_buffer_dump(hw, skb, cb); |
| 1075 | break; | 1102 | break; |
| 1076 | default: | 1103 | default: |
| 1077 | result = -EINVAL; | 1104 | result = -EINVAL; |
| 1078 | break; | 1105 | break; |
| 1079 | } | 1106 | } |
| 1080 | 1107 | ||
| 1081 | mutex_unlock(&priv->shrd->mutex); | 1108 | mutex_unlock(&priv->mutex); |
| 1082 | return result; | 1109 | return result; |
| 1083 | } | 1110 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index 69b2e80f4071..6ba211b09426 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h | |||
| @@ -122,6 +122,9 @@ | |||
| 122 | * Fore reading, a READ command is sent from the userspace and the data | 122 | * Fore reading, a READ command is sent from the userspace and the data |
| 123 | * is returned when the user calls a DUMP command. | 123 | * is returned when the user calls a DUMP command. |
| 124 | * For writing, only a WRITE command is used. | 124 | * For writing, only a WRITE command is used. |
| 125 | * @IWL_TM_CMD_APP2DEV_NOTIFICATIONS: | ||
| 126 | * Command to enable/disable notifications (currently RX packets) from the | ||
| 127 | * driver to userspace. | ||
| 125 | */ | 128 | */ |
| 126 | enum iwl_tm_cmd_t { | 129 | enum iwl_tm_cmd_t { |
| 127 | IWL_TM_CMD_APP2DEV_UCODE = 1, | 130 | IWL_TM_CMD_APP2DEV_UCODE = 1, |
| @@ -152,7 +155,8 @@ enum iwl_tm_cmd_t { | |||
| 152 | IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ = 26, | 155 | IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ = 26, |
| 153 | IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP = 27, | 156 | IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP = 27, |
| 154 | IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE = 28, | 157 | IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE = 28, |
| 155 | IWL_TM_CMD_MAX = 29, | 158 | IWL_TM_CMD_APP2DEV_NOTIFICATIONS = 29, |
| 159 | IWL_TM_CMD_MAX = 30, | ||
| 156 | }; | 160 | }; |
| 157 | 161 | ||
| 158 | /* | 162 | /* |
| @@ -256,6 +260,10 @@ enum iwl_tm_cmd_t { | |||
| 256 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE this flag | 260 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE this flag |
| 257 | * indicates that the user wants to receive the response of the command | 261 | * indicates that the user wants to receive the response of the command |
| 258 | * in a reply SKB. If it's not present, the response is not returned. | 262 | * in a reply SKB. If it's not present, the response is not returned. |
| 263 | * @IWL_TM_ATTR_ENABLE_NOTIFICATIONS: | ||
| 264 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_NOTIFICATIONS, this | ||
| 265 | * flag enables (if present) or disables (if not) the forwarding | ||
| 266 | * to userspace. | ||
| 259 | */ | 267 | */ |
| 260 | enum iwl_tm_attr_t { | 268 | enum iwl_tm_attr_t { |
| 261 | IWL_TM_ATTR_NOT_APPLICABLE = 0, | 269 | IWL_TM_ATTR_NOT_APPLICABLE = 0, |
| @@ -282,7 +290,8 @@ enum iwl_tm_attr_t { | |||
| 282 | IWL_TM_ATTR_FW_INST_SIZE = 21, | 290 | IWL_TM_ATTR_FW_INST_SIZE = 21, |
| 283 | IWL_TM_ATTR_FW_DATA_SIZE = 22, | 291 | IWL_TM_ATTR_FW_DATA_SIZE = 22, |
| 284 | IWL_TM_ATTR_UCODE_CMD_SKB = 23, | 292 | IWL_TM_ATTR_UCODE_CMD_SKB = 23, |
| 285 | IWL_TM_ATTR_MAX = 24, | 293 | IWL_TM_ATTR_ENABLE_NOTIFICATION = 24, |
| 294 | IWL_TM_ATTR_MAX = 25, | ||
| 286 | }; | 295 | }; |
| 287 | 296 | ||
| 288 | /* uCode trace buffer */ | 297 | /* uCode trace buffer */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 5b26b71ae3d5..67965599bb30 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
| 33 | #include <linux/interrupt.h> | 33 | #include <linux/interrupt.h> |
| 34 | #include <linux/skbuff.h> | 34 | #include <linux/skbuff.h> |
| 35 | #include <linux/wait.h> | ||
| 35 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
| 36 | 37 | ||
| 37 | #include "iwl-fh.h" | 38 | #include "iwl-fh.h" |
| @@ -49,6 +50,12 @@ struct iwl_host_cmd; | |||
| 49 | /*This file includes the declaration that are internal to the | 50 | /*This file includes the declaration that are internal to the |
| 50 | * trans_pcie layer */ | 51 | * trans_pcie layer */ |
| 51 | 52 | ||
| 53 | struct iwl_rx_mem_buffer { | ||
| 54 | dma_addr_t page_dma; | ||
| 55 | struct page *page; | ||
| 56 | struct list_head list; | ||
| 57 | }; | ||
| 58 | |||
| 52 | /** | 59 | /** |
| 53 | * struct isr_statistics - interrupt statistics | 60 | * struct isr_statistics - interrupt statistics |
| 54 | * | 61 | * |
| @@ -109,6 +116,26 @@ struct iwl_dma_ptr { | |||
| 109 | size_t size; | 116 | size_t size; |
| 110 | }; | 117 | }; |
| 111 | 118 | ||
| 119 | /** | ||
| 120 | * iwl_queue_inc_wrap - increment queue index, wrap back to beginning | ||
| 121 | * @index -- current index | ||
| 122 | * @n_bd -- total number of entries in queue (must be power of 2) | ||
| 123 | */ | ||
| 124 | static inline int iwl_queue_inc_wrap(int index, int n_bd) | ||
| 125 | { | ||
| 126 | return ++index & (n_bd - 1); | ||
| 127 | } | ||
| 128 | |||
| 129 | /** | ||
| 130 | * iwl_queue_dec_wrap - decrement queue index, wrap back to end | ||
| 131 | * @index -- current index | ||
| 132 | * @n_bd -- total number of entries in queue (must be power of 2) | ||
| 133 | */ | ||
| 134 | static inline int iwl_queue_dec_wrap(int index, int n_bd) | ||
| 135 | { | ||
| 136 | return --index & (n_bd - 1); | ||
| 137 | } | ||
| 138 | |||
| 112 | /* | 139 | /* |
| 113 | * This queue number is required for proper operation | 140 | * This queue number is required for proper operation |
| 114 | * because the ucode will stop/start the scheduler as | 141 | * because the ucode will stop/start the scheduler as |
| @@ -169,6 +196,7 @@ struct iwl_queue { | |||
| 169 | * @meta: array of meta data for each command/tx buffer | 196 | * @meta: array of meta data for each command/tx buffer |
| 170 | * @dma_addr_cmd: physical address of cmd/tx buffer array | 197 | * @dma_addr_cmd: physical address of cmd/tx buffer array |
| 171 | * @txb: array of per-TFD driver data | 198 | * @txb: array of per-TFD driver data |
| 199 | * lock: queue lock | ||
| 172 | * @time_stamp: time (in jiffies) of last read_ptr change | 200 | * @time_stamp: time (in jiffies) of last read_ptr change |
| 173 | * @need_update: indicates need to update read/write index | 201 | * @need_update: indicates need to update read/write index |
| 174 | * @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled | 202 | * @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled |
| @@ -187,6 +215,7 @@ struct iwl_tx_queue { | |||
| 187 | struct iwl_device_cmd **cmd; | 215 | struct iwl_device_cmd **cmd; |
| 188 | struct iwl_cmd_meta *meta; | 216 | struct iwl_cmd_meta *meta; |
| 189 | struct sk_buff **skbs; | 217 | struct sk_buff **skbs; |
| 218 | spinlock_t lock; | ||
| 190 | unsigned long time_stamp; | 219 | unsigned long time_stamp; |
| 191 | u8 need_update; | 220 | u8 need_update; |
| 192 | u8 sched_retry; | 221 | u8 sched_retry; |
| @@ -202,6 +231,7 @@ struct iwl_tx_queue { | |||
| 202 | * @rxq: all the RX queue data | 231 | * @rxq: all the RX queue data |
| 203 | * @rx_replenish: work that will be called when buffers need to be allocated | 232 | * @rx_replenish: work that will be called when buffers need to be allocated |
| 204 | * @trans: pointer to the generic transport area | 233 | * @trans: pointer to the generic transport area |
| 234 | * @irq - the irq number for the device | ||
| 205 | * @irq_requested: true when the irq has been requested | 235 | * @irq_requested: true when the irq has been requested |
| 206 | * @scd_base_addr: scheduler sram base address in SRAM | 236 | * @scd_base_addr: scheduler sram base address in SRAM |
| 207 | * @scd_bc_tbls: pointer to the byte count table of the scheduler | 237 | * @scd_bc_tbls: pointer to the byte count table of the scheduler |
| @@ -215,6 +245,10 @@ struct iwl_tx_queue { | |||
| 215 | * queue_stop_count: tracks what SW queue is stopped | 245 | * queue_stop_count: tracks what SW queue is stopped |
| 216 | * @pci_dev: basic pci-network driver stuff | 246 | * @pci_dev: basic pci-network driver stuff |
| 217 | * @hw_base: pci hardware address support | 247 | * @hw_base: pci hardware address support |
| 248 | * @ucode_write_complete: indicates that the ucode has been copied. | ||
| 249 | * @ucode_write_waitq: wait queue for uCode load | ||
| 250 | * @status - transport specific status flags | ||
| 251 | * @cmd_queue - command queue number | ||
| 218 | */ | 252 | */ |
| 219 | struct iwl_trans_pcie { | 253 | struct iwl_trans_pcie { |
| 220 | struct iwl_rx_queue rxq; | 254 | struct iwl_rx_queue rxq; |
| @@ -231,6 +265,7 @@ struct iwl_trans_pcie { | |||
| 231 | struct tasklet_struct irq_tasklet; | 265 | struct tasklet_struct irq_tasklet; |
| 232 | struct isr_statistics isr_stats; | 266 | struct isr_statistics isr_stats; |
| 233 | 267 | ||
| 268 | unsigned int irq; | ||
| 234 | spinlock_t irq_lock; | 269 | spinlock_t irq_lock; |
| 235 | u32 inta_mask; | 270 | u32 inta_mask; |
| 236 | u32 scd_base_addr; | 271 | u32 scd_base_addr; |
| @@ -251,6 +286,11 @@ struct iwl_trans_pcie { | |||
| 251 | /* PCI bus related data */ | 286 | /* PCI bus related data */ |
| 252 | struct pci_dev *pci_dev; | 287 | struct pci_dev *pci_dev; |
| 253 | void __iomem *hw_base; | 288 | void __iomem *hw_base; |
| 289 | |||
| 290 | bool ucode_write_complete; | ||
| 291 | wait_queue_head_t ucode_write_waitq; | ||
| 292 | unsigned long status; | ||
| 293 | u8 cmd_queue; | ||
| 254 | }; | 294 | }; |
| 255 | 295 | ||
| 256 | #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ | 296 | #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ |
| @@ -285,7 +325,7 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, | |||
| 285 | int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id); | 325 | int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id); |
| 286 | int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); | 326 | int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); |
| 287 | void iwl_tx_cmd_complete(struct iwl_trans *trans, | 327 | void iwl_tx_cmd_complete(struct iwl_trans *trans, |
| 288 | struct iwl_rx_mem_buffer *rxb, int handler_status); | 328 | struct iwl_rx_cmd_buffer *rxb, int handler_status); |
| 289 | void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, | 329 | void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, |
| 290 | struct iwl_tx_queue *txq, | 330 | struct iwl_tx_queue *txq, |
| 291 | u16 byte_cnt); | 331 | u16 byte_cnt); |
| @@ -318,7 +358,8 @@ void iwl_dump_csr(struct iwl_trans *trans); | |||
| 318 | ******************************************************/ | 358 | ******************************************************/ |
| 319 | static inline void iwl_disable_interrupts(struct iwl_trans *trans) | 359 | static inline void iwl_disable_interrupts(struct iwl_trans *trans) |
| 320 | { | 360 | { |
| 321 | clear_bit(STATUS_INT_ENABLED, &trans->shrd->status); | 361 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
| 362 | clear_bit(STATUS_INT_ENABLED, &trans_pcie->status); | ||
| 322 | 363 | ||
| 323 | /* disable interrupts from uCode/NIC to host */ | 364 | /* disable interrupts from uCode/NIC to host */ |
| 324 | iwl_write32(trans, CSR_INT_MASK, 0x00000000); | 365 | iwl_write32(trans, CSR_INT_MASK, 0x00000000); |
| @@ -332,14 +373,19 @@ static inline void iwl_disable_interrupts(struct iwl_trans *trans) | |||
| 332 | 373 | ||
| 333 | static inline void iwl_enable_interrupts(struct iwl_trans *trans) | 374 | static inline void iwl_enable_interrupts(struct iwl_trans *trans) |
| 334 | { | 375 | { |
| 335 | struct iwl_trans_pcie *trans_pcie = | 376 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
| 336 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
| 337 | 377 | ||
| 338 | IWL_DEBUG_ISR(trans, "Enabling interrupts\n"); | 378 | IWL_DEBUG_ISR(trans, "Enabling interrupts\n"); |
| 339 | set_bit(STATUS_INT_ENABLED, &trans->shrd->status); | 379 | set_bit(STATUS_INT_ENABLED, &trans_pcie->status); |
| 340 | iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask); | 380 | iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask); |
| 341 | } | 381 | } |
| 342 | 382 | ||
| 383 | static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) | ||
| 384 | { | ||
| 385 | IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); | ||
| 386 | iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); | ||
| 387 | } | ||
| 388 | |||
| 343 | /* | 389 | /* |
| 344 | * we have 8 bits used like this: | 390 | * we have 8 bits used like this: |
| 345 | * | 391 | * |
| @@ -365,7 +411,7 @@ static inline u8 iwl_get_queue_ac(struct iwl_tx_queue *txq) | |||
| 365 | } | 411 | } |
| 366 | 412 | ||
| 367 | static inline void iwl_wake_queue(struct iwl_trans *trans, | 413 | static inline void iwl_wake_queue(struct iwl_trans *trans, |
| 368 | struct iwl_tx_queue *txq, const char *msg) | 414 | struct iwl_tx_queue *txq) |
| 369 | { | 415 | { |
| 370 | u8 queue = txq->swq_id; | 416 | u8 queue = txq->swq_id; |
| 371 | u8 ac = queue & 3; | 417 | u8 ac = queue & 3; |
| @@ -376,19 +422,19 @@ static inline void iwl_wake_queue(struct iwl_trans *trans, | |||
| 376 | if (test_and_clear_bit(hwq, trans_pcie->queue_stopped)) { | 422 | if (test_and_clear_bit(hwq, trans_pcie->queue_stopped)) { |
| 377 | if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0) { | 423 | if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0) { |
| 378 | iwl_op_mode_queue_not_full(trans->op_mode, ac); | 424 | iwl_op_mode_queue_not_full(trans->op_mode, ac); |
| 379 | IWL_DEBUG_TX_QUEUES(trans, "Wake hwq %d ac %d. %s", | 425 | IWL_DEBUG_TX_QUEUES(trans, "Wake hwq %d ac %d", |
| 380 | hwq, ac, msg); | 426 | hwq, ac); |
| 381 | } else { | 427 | } else { |
| 382 | IWL_DEBUG_TX_QUEUES(trans, "Don't wake hwq %d ac %d" | 428 | IWL_DEBUG_TX_QUEUES(trans, |
| 383 | " stop count %d. %s", | 429 | "Don't wake hwq %d ac %d stop count %d", |
| 384 | hwq, ac, atomic_read(&trans_pcie-> | 430 | hwq, ac, |
| 385 | queue_stop_count[ac]), msg); | 431 | atomic_read(&trans_pcie->queue_stop_count[ac])); |
| 386 | } | 432 | } |
| 387 | } | 433 | } |
| 388 | } | 434 | } |
| 389 | 435 | ||
| 390 | static inline void iwl_stop_queue(struct iwl_trans *trans, | 436 | static inline void iwl_stop_queue(struct iwl_trans *trans, |
| 391 | struct iwl_tx_queue *txq, const char *msg) | 437 | struct iwl_tx_queue *txq) |
| 392 | { | 438 | { |
| 393 | u8 queue = txq->swq_id; | 439 | u8 queue = txq->swq_id; |
| 394 | u8 ac = queue & 3; | 440 | u8 ac = queue & 3; |
| @@ -399,34 +445,22 @@ static inline void iwl_stop_queue(struct iwl_trans *trans, | |||
| 399 | if (!test_and_set_bit(hwq, trans_pcie->queue_stopped)) { | 445 | if (!test_and_set_bit(hwq, trans_pcie->queue_stopped)) { |
| 400 | if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0) { | 446 | if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0) { |
| 401 | iwl_op_mode_queue_full(trans->op_mode, ac); | 447 | iwl_op_mode_queue_full(trans->op_mode, ac); |
| 402 | IWL_DEBUG_TX_QUEUES(trans, "Stop hwq %d ac %d" | 448 | IWL_DEBUG_TX_QUEUES(trans, |
| 403 | " stop count %d. %s", | 449 | "Stop hwq %d ac %d stop count %d", |
| 404 | hwq, ac, atomic_read(&trans_pcie-> | 450 | hwq, ac, |
| 405 | queue_stop_count[ac]), msg); | 451 | atomic_read(&trans_pcie->queue_stop_count[ac])); |
| 406 | } else { | 452 | } else { |
| 407 | IWL_DEBUG_TX_QUEUES(trans, "Don't stop hwq %d ac %d" | 453 | IWL_DEBUG_TX_QUEUES(trans, |
| 408 | " stop count %d. %s", | 454 | "Don't stop hwq %d ac %d stop count %d", |
| 409 | hwq, ac, atomic_read(&trans_pcie-> | 455 | hwq, ac, |
| 410 | queue_stop_count[ac]), msg); | 456 | atomic_read(&trans_pcie->queue_stop_count[ac])); |
| 411 | } | 457 | } |
| 412 | } else { | 458 | } else { |
| 413 | IWL_DEBUG_TX_QUEUES(trans, "stop hwq %d, but it is stopped/ %s", | 459 | IWL_DEBUG_TX_QUEUES(trans, "stop hwq %d, but it is stopped", |
| 414 | hwq, msg); | 460 | hwq); |
| 415 | } | 461 | } |
| 416 | } | 462 | } |
| 417 | 463 | ||
| 418 | #ifdef ieee80211_stop_queue | ||
| 419 | #undef ieee80211_stop_queue | ||
| 420 | #endif | ||
| 421 | |||
| 422 | #define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue | ||
| 423 | |||
| 424 | #ifdef ieee80211_wake_queue | ||
| 425 | #undef ieee80211_wake_queue | ||
| 426 | #endif | ||
| 427 | |||
| 428 | #define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue | ||
| 429 | |||
| 430 | static inline void iwl_txq_ctx_activate(struct iwl_trans_pcie *trans_pcie, | 464 | static inline void iwl_txq_ctx_activate(struct iwl_trans_pcie *trans_pcie, |
| 431 | int txq_id) | 465 | int txq_id) |
| 432 | { | 466 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 2c910fddaaf6..9bc3c73af5e9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | |||
| @@ -30,11 +30,9 @@ | |||
| 30 | #include <linux/wait.h> | 30 | #include <linux/wait.h> |
| 31 | #include <linux/gfp.h> | 31 | #include <linux/gfp.h> |
| 32 | 32 | ||
| 33 | /*TODO: Remove include to iwl-core.h*/ | 33 | #include "iwl-prph.h" |
| 34 | #include "iwl-core.h" | ||
| 35 | #include "iwl-io.h" | 34 | #include "iwl-io.h" |
| 36 | #include "iwl-trans-pcie-int.h" | 35 | #include "iwl-trans-pcie-int.h" |
| 37 | #include "iwl-wifi.h" | ||
| 38 | #include "iwl-op-mode.h" | 36 | #include "iwl-op-mode.h" |
| 39 | 37 | ||
| 40 | #ifdef CONFIG_IWLWIFI_IDI | 38 | #ifdef CONFIG_IWLWIFI_IDI |
| @@ -142,7 +140,7 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, | |||
| 142 | if (q->need_update == 0) | 140 | if (q->need_update == 0) |
| 143 | goto exit_unlock; | 141 | goto exit_unlock; |
| 144 | 142 | ||
| 145 | if (hw_params(trans).shadow_reg_enable) { | 143 | if (cfg(trans)->base_params->shadow_reg_enable) { |
| 146 | /* shadow register enabled */ | 144 | /* shadow register enabled */ |
| 147 | /* Device expects a multiple of 8 */ | 145 | /* Device expects a multiple of 8 */ |
| 148 | q->write_actual = (q->write & ~0x7); | 146 | q->write_actual = (q->write & ~0x7); |
| @@ -358,6 +356,113 @@ void iwl_bg_rx_replenish(struct work_struct *data) | |||
| 358 | iwlagn_rx_replenish(trans_pcie->trans); | 356 | iwlagn_rx_replenish(trans_pcie->trans); |
| 359 | } | 357 | } |
| 360 | 358 | ||
| 359 | static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, | ||
| 360 | struct iwl_rx_mem_buffer *rxb) | ||
| 361 | { | ||
| 362 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
| 363 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; | ||
| 364 | struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; | ||
| 365 | struct iwl_device_cmd *cmd; | ||
| 366 | unsigned long flags; | ||
| 367 | int len, err; | ||
| 368 | u16 sequence; | ||
| 369 | struct iwl_rx_cmd_buffer rxcb; | ||
| 370 | struct iwl_rx_packet *pkt; | ||
| 371 | bool reclaim; | ||
| 372 | int index, cmd_index; | ||
| 373 | |||
| 374 | if (WARN_ON(!rxb)) | ||
| 375 | return; | ||
| 376 | |||
| 377 | dma_unmap_page(trans->dev, rxb->page_dma, | ||
| 378 | PAGE_SIZE << hw_params(trans).rx_page_order, | ||
| 379 | DMA_FROM_DEVICE); | ||
| 380 | |||
| 381 | rxcb._page = rxb->page; | ||
| 382 | pkt = rxb_addr(&rxcb); | ||
| 383 | |||
| 384 | IWL_DEBUG_RX(trans, "%s, 0x%02x\n", | ||
| 385 | get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); | ||
| 386 | |||
| 387 | |||
| 388 | len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | ||
| 389 | len += sizeof(u32); /* account for status word */ | ||
| 390 | trace_iwlwifi_dev_rx(trans->dev, pkt, len); | ||
| 391 | |||
| 392 | /* Reclaim a command buffer only if this packet is a response | ||
| 393 | * to a (driver-originated) command. | ||
| 394 | * If the packet (e.g. Rx frame) originated from uCode, | ||
| 395 | * there is no command buffer to reclaim. | ||
| 396 | * Ucode should set SEQ_RX_FRAME bit if ucode-originated, | ||
| 397 | * but apparently a few don't get set; catch them here. */ | ||
| 398 | reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) && | ||
| 399 | (pkt->hdr.cmd != REPLY_RX_PHY_CMD) && | ||
| 400 | (pkt->hdr.cmd != REPLY_RX) && | ||
| 401 | (pkt->hdr.cmd != REPLY_RX_MPDU_CMD) && | ||
| 402 | (pkt->hdr.cmd != REPLY_COMPRESSED_BA) && | ||
| 403 | (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && | ||
| 404 | (pkt->hdr.cmd != REPLY_TX); | ||
| 405 | |||
| 406 | sequence = le16_to_cpu(pkt->hdr.sequence); | ||
| 407 | index = SEQ_TO_INDEX(sequence); | ||
| 408 | cmd_index = get_cmd_index(&txq->q, index); | ||
| 409 | |||
| 410 | if (reclaim) | ||
| 411 | cmd = txq->cmd[cmd_index]; | ||
| 412 | else | ||
| 413 | cmd = NULL; | ||
| 414 | |||
| 415 | /* warn if this is cmd response / notification and the uCode | ||
| 416 | * didn't set the SEQ_RX_FRAME for a frame that is | ||
| 417 | * uCode-originated | ||
| 418 | * If you saw this code after the second half of 2012, then | ||
| 419 | * please remove it | ||
| 420 | */ | ||
| 421 | WARN(pkt->hdr.cmd != REPLY_TX && reclaim == false && | ||
| 422 | (!(pkt->hdr.sequence & SEQ_RX_FRAME)), | ||
| 423 | "reclaim is false, SEQ_RX_FRAME unset: %s\n", | ||
| 424 | get_cmd_string(pkt->hdr.cmd)); | ||
| 425 | |||
| 426 | err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); | ||
| 427 | |||
| 428 | /* | ||
| 429 | * XXX: After here, we should always check rxcb._page | ||
| 430 | * against NULL before touching it or its virtual | ||
| 431 | * memory (pkt). Because some rx_handler might have | ||
| 432 | * already taken or freed the pages. | ||
| 433 | */ | ||
| 434 | |||
| 435 | if (reclaim) { | ||
| 436 | /* Invoke any callbacks, transfer the buffer to caller, | ||
| 437 | * and fire off the (possibly) blocking | ||
| 438 | * iwl_trans_send_cmd() | ||
| 439 | * as we reclaim the driver command queue */ | ||
| 440 | if (rxcb._page) | ||
| 441 | iwl_tx_cmd_complete(trans, &rxcb, err); | ||
| 442 | else | ||
| 443 | IWL_WARN(trans, "Claim null rxb?\n"); | ||
| 444 | } | ||
| 445 | |||
| 446 | /* page was stolen from us */ | ||
| 447 | if (rxcb._page == NULL) | ||
| 448 | rxb->page = NULL; | ||
| 449 | |||
| 450 | /* Reuse the page if possible. For notification packets and | ||
| 451 | * SKBs that fail to Rx correctly, add them back into the | ||
| 452 | * rx_free list for reuse later. */ | ||
| 453 | spin_lock_irqsave(&rxq->lock, flags); | ||
| 454 | if (rxb->page != NULL) { | ||
| 455 | rxb->page_dma = | ||
| 456 | dma_map_page(trans->dev, rxb->page, 0, | ||
| 457 | PAGE_SIZE << hw_params(trans).rx_page_order, | ||
| 458 | DMA_FROM_DEVICE); | ||
| 459 | list_add_tail(&rxb->list, &rxq->rx_free); | ||
| 460 | rxq->free_count++; | ||
| 461 | } else | ||
| 462 | list_add_tail(&rxb->list, &rxq->rx_used); | ||
| 463 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
| 464 | } | ||
| 465 | |||
| 361 | /** | 466 | /** |
| 362 | * iwl_rx_handle - Main entry function for receiving responses from uCode | 467 | * iwl_rx_handle - Main entry function for receiving responses from uCode |
| 363 | * | 468 | * |
| @@ -367,20 +472,12 @@ void iwl_bg_rx_replenish(struct work_struct *data) | |||
| 367 | */ | 472 | */ |
| 368 | static void iwl_rx_handle(struct iwl_trans *trans) | 473 | static void iwl_rx_handle(struct iwl_trans *trans) |
| 369 | { | 474 | { |
| 370 | struct iwl_rx_mem_buffer *rxb; | 475 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
| 371 | struct iwl_rx_packet *pkt; | ||
| 372 | struct iwl_trans_pcie *trans_pcie = | ||
| 373 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
| 374 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; | 476 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; |
| 375 | struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue]; | ||
| 376 | struct iwl_device_cmd *cmd; | ||
| 377 | u32 r, i; | 477 | u32 r, i; |
| 378 | int reclaim; | ||
| 379 | unsigned long flags; | ||
| 380 | u8 fill_rx = 0; | 478 | u8 fill_rx = 0; |
| 381 | u32 count = 8; | 479 | u32 count = 8; |
| 382 | int total_empty; | 480 | int total_empty; |
| 383 | int index, cmd_index; | ||
| 384 | 481 | ||
| 385 | /* uCode's read index (stored in shared DRAM) indicates the last Rx | 482 | /* uCode's read index (stored in shared DRAM) indicates the last Rx |
| 386 | * buffer that the driver may process (last buffer filled by ucode). */ | 483 | * buffer that the driver may process (last buffer filled by ucode). */ |
| @@ -400,102 +497,14 @@ static void iwl_rx_handle(struct iwl_trans *trans) | |||
| 400 | fill_rx = 1; | 497 | fill_rx = 1; |
| 401 | 498 | ||
| 402 | while (i != r) { | 499 | while (i != r) { |
| 403 | int len, err; | 500 | struct iwl_rx_mem_buffer *rxb; |
| 404 | u16 sequence; | ||
| 405 | 501 | ||
| 406 | rxb = rxq->queue[i]; | 502 | rxb = rxq->queue[i]; |
| 407 | |||
| 408 | /* If an RXB doesn't have a Rx queue slot associated with it, | ||
| 409 | * then a bug has been introduced in the queue refilling | ||
| 410 | * routines -- catch it here */ | ||
| 411 | if (WARN_ON(rxb == NULL)) { | ||
| 412 | i = (i + 1) & RX_QUEUE_MASK; | ||
| 413 | continue; | ||
| 414 | } | ||
| 415 | |||
| 416 | rxq->queue[i] = NULL; | 503 | rxq->queue[i] = NULL; |
| 417 | 504 | ||
| 418 | dma_unmap_page(trans->dev, rxb->page_dma, | 505 | IWL_DEBUG_RX(trans, "rxbuf: r = %d, i = %d (%p)\n", rxb); |
| 419 | PAGE_SIZE << hw_params(trans).rx_page_order, | ||
| 420 | DMA_FROM_DEVICE); | ||
| 421 | pkt = rxb_addr(rxb); | ||
| 422 | |||
| 423 | IWL_DEBUG_RX(trans, "r = %d, i = %d, %s, 0x%02x\n", r, | ||
| 424 | i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); | ||
| 425 | |||
| 426 | len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | ||
| 427 | len += sizeof(u32); /* account for status word */ | ||
| 428 | trace_iwlwifi_dev_rx(priv(trans), pkt, len); | ||
| 429 | |||
| 430 | /* Reclaim a command buffer only if this packet is a response | ||
| 431 | * to a (driver-originated) command. | ||
| 432 | * If the packet (e.g. Rx frame) originated from uCode, | ||
| 433 | * there is no command buffer to reclaim. | ||
| 434 | * Ucode should set SEQ_RX_FRAME bit if ucode-originated, | ||
| 435 | * but apparently a few don't get set; catch them here. */ | ||
| 436 | reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) && | ||
| 437 | (pkt->hdr.cmd != REPLY_RX_PHY_CMD) && | ||
| 438 | (pkt->hdr.cmd != REPLY_RX) && | ||
| 439 | (pkt->hdr.cmd != REPLY_RX_MPDU_CMD) && | ||
| 440 | (pkt->hdr.cmd != REPLY_COMPRESSED_BA) && | ||
| 441 | (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && | ||
| 442 | (pkt->hdr.cmd != REPLY_TX); | ||
| 443 | |||
| 444 | sequence = le16_to_cpu(pkt->hdr.sequence); | ||
| 445 | index = SEQ_TO_INDEX(sequence); | ||
| 446 | cmd_index = get_cmd_index(&txq->q, index); | ||
| 447 | |||
| 448 | if (reclaim) | ||
| 449 | cmd = txq->cmd[cmd_index]; | ||
| 450 | else | ||
| 451 | cmd = NULL; | ||
| 452 | |||
| 453 | /* warn if this is cmd response / notification and the uCode | ||
| 454 | * didn't set the SEQ_RX_FRAME for a frame that is | ||
| 455 | * uCode-originated | ||
| 456 | * If you saw this code after the second half of 2012, then | ||
| 457 | * please remove it | ||
| 458 | */ | ||
| 459 | WARN(pkt->hdr.cmd != REPLY_TX && reclaim == false && | ||
| 460 | (!(pkt->hdr.sequence & SEQ_RX_FRAME)), | ||
| 461 | "reclaim is false, SEQ_RX_FRAME unset: %s\n", | ||
| 462 | get_cmd_string(pkt->hdr.cmd)); | ||
| 463 | |||
| 464 | err = iwl_op_mode_rx(trans->op_mode, rxb, cmd); | ||
| 465 | |||
| 466 | /* | ||
| 467 | * XXX: After here, we should always check rxb->page | ||
| 468 | * against NULL before touching it or its virtual | ||
| 469 | * memory (pkt). Because some rx_handler might have | ||
| 470 | * already taken or freed the pages. | ||
| 471 | */ | ||
| 472 | 506 | ||
| 473 | if (reclaim) { | 507 | iwl_rx_handle_rxbuf(trans, rxb); |
| 474 | /* Invoke any callbacks, transfer the buffer to caller, | ||
| 475 | * and fire off the (possibly) blocking | ||
| 476 | * iwl_trans_send_cmd() | ||
| 477 | * as we reclaim the driver command queue */ | ||
| 478 | if (rxb->page) | ||
| 479 | iwl_tx_cmd_complete(trans, rxb, err); | ||
| 480 | else | ||
| 481 | IWL_WARN(trans, "Claim null rxb?\n"); | ||
| 482 | } | ||
| 483 | |||
| 484 | /* Reuse the page if possible. For notification packets and | ||
| 485 | * SKBs that fail to Rx correctly, add them back into the | ||
| 486 | * rx_free list for reuse later. */ | ||
| 487 | spin_lock_irqsave(&rxq->lock, flags); | ||
| 488 | if (rxb->page != NULL) { | ||
| 489 | rxb->page_dma = dma_map_page(trans->dev, rxb->page, | ||
| 490 | 0, PAGE_SIZE << | ||
| 491 | hw_params(trans).rx_page_order, | ||
| 492 | DMA_FROM_DEVICE); | ||
| 493 | list_add_tail(&rxb->list, &rxq->rx_free); | ||
| 494 | rxq->free_count++; | ||
| 495 | } else | ||
| 496 | list_add_tail(&rxb->list, &rxq->rx_used); | ||
| 497 | |||
| 498 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
| 499 | 508 | ||
| 500 | i = (i + 1) & RX_QUEUE_MASK; | 509 | i = (i + 1) & RX_QUEUE_MASK; |
| 501 | /* If there are a lot of unused frames, | 510 | /* If there are a lot of unused frames, |
| @@ -591,17 +600,16 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans) | |||
| 591 | { | 600 | { |
| 592 | u32 base; | 601 | u32 base; |
| 593 | struct iwl_error_event_table table; | 602 | struct iwl_error_event_table table; |
| 594 | struct iwl_nic *nic = nic(trans); | ||
| 595 | struct iwl_trans_pcie *trans_pcie = | 603 | struct iwl_trans_pcie *trans_pcie = |
| 596 | IWL_TRANS_GET_PCIE_TRANS(trans); | 604 | IWL_TRANS_GET_PCIE_TRANS(trans); |
| 597 | 605 | ||
| 598 | base = trans->shrd->device_pointers.error_event_table; | 606 | base = trans->shrd->device_pointers.error_event_table; |
| 599 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) { | 607 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) { |
| 600 | if (!base) | 608 | if (!base) |
| 601 | base = nic->init_errlog_ptr; | 609 | base = trans->shrd->fw->init_errlog_ptr; |
| 602 | } else { | 610 | } else { |
| 603 | if (!base) | 611 | if (!base) |
| 604 | base = nic->inst_errlog_ptr; | 612 | base = trans->shrd->fw->inst_errlog_ptr; |
| 605 | } | 613 | } |
| 606 | 614 | ||
| 607 | if (!iwlagn_hw_valid_rtc_data_addr(base)) { | 615 | if (!iwlagn_hw_valid_rtc_data_addr(base)) { |
| @@ -623,7 +631,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans) | |||
| 623 | 631 | ||
| 624 | trans_pcie->isr_stats.err_code = table.error_id; | 632 | trans_pcie->isr_stats.err_code = table.error_id; |
| 625 | 633 | ||
| 626 | trace_iwlwifi_dev_ucode_error(priv(nic), table.error_id, table.tsf_low, | 634 | trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low, |
| 627 | table.data1, table.data2, table.line, | 635 | table.data1, table.data2, table.line, |
| 628 | table.blink1, table.blink2, table.ilink1, | 636 | table.blink1, table.blink2, table.ilink1, |
| 629 | table.ilink2, table.bcon_time, table.gp1, | 637 | table.ilink2, table.bcon_time, table.gp1, |
| @@ -689,7 +697,7 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) | |||
| 689 | } | 697 | } |
| 690 | 698 | ||
| 691 | IWL_ERR(trans, "Loaded firmware version: %s\n", | 699 | IWL_ERR(trans, "Loaded firmware version: %s\n", |
| 692 | nic(trans)->fw.fw_version); | 700 | trans->shrd->fw->fw_version); |
| 693 | 701 | ||
| 694 | iwl_dump_nic_error_log(trans); | 702 | iwl_dump_nic_error_log(trans); |
| 695 | iwl_dump_csr(trans); | 703 | iwl_dump_csr(trans); |
| @@ -715,7 +723,6 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
| 715 | u32 ptr; /* SRAM byte address of log data */ | 723 | u32 ptr; /* SRAM byte address of log data */ |
| 716 | u32 ev, time, data; /* event log data */ | 724 | u32 ev, time, data; /* event log data */ |
| 717 | unsigned long reg_flags; | 725 | unsigned long reg_flags; |
| 718 | struct iwl_nic *nic = nic(trans); | ||
| 719 | 726 | ||
| 720 | if (num_events == 0) | 727 | if (num_events == 0) |
| 721 | return pos; | 728 | return pos; |
| @@ -723,10 +730,10 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
| 723 | base = trans->shrd->device_pointers.log_event_table; | 730 | base = trans->shrd->device_pointers.log_event_table; |
| 724 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) { | 731 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) { |
| 725 | if (!base) | 732 | if (!base) |
| 726 | base = nic->init_evtlog_ptr; | 733 | base = trans->shrd->fw->init_evtlog_ptr; |
| 727 | } else { | 734 | } else { |
| 728 | if (!base) | 735 | if (!base) |
| 729 | base = nic->inst_evtlog_ptr; | 736 | base = trans->shrd->fw->inst_evtlog_ptr; |
| 730 | } | 737 | } |
| 731 | 738 | ||
| 732 | if (mode == 0) | 739 | if (mode == 0) |
| @@ -738,11 +745,11 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
| 738 | 745 | ||
| 739 | /* Make sure device is powered up for SRAM reads */ | 746 | /* Make sure device is powered up for SRAM reads */ |
| 740 | spin_lock_irqsave(&trans->reg_lock, reg_flags); | 747 | spin_lock_irqsave(&trans->reg_lock, reg_flags); |
| 741 | iwl_grab_nic_access(trans); | 748 | if (unlikely(!iwl_grab_nic_access(trans))) |
| 749 | goto out_unlock; | ||
| 742 | 750 | ||
| 743 | /* Set starting address; reads will auto-increment */ | 751 | /* Set starting address; reads will auto-increment */ |
| 744 | iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr); | 752 | iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr); |
| 745 | rmb(); | ||
| 746 | 753 | ||
| 747 | /* "time" is actually "data" for mode 0 (no timestamp). | 754 | /* "time" is actually "data" for mode 0 (no timestamp). |
| 748 | * place event id # at far right for easier visual parsing. */ | 755 | * place event id # at far right for easier visual parsing. */ |
| @@ -756,7 +763,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
| 756 | "EVT_LOG:0x%08x:%04u\n", | 763 | "EVT_LOG:0x%08x:%04u\n", |
| 757 | time, ev); | 764 | time, ev); |
| 758 | } else { | 765 | } else { |
| 759 | trace_iwlwifi_dev_ucode_event(priv(trans), 0, | 766 | trace_iwlwifi_dev_ucode_event(trans->dev, 0, |
| 760 | time, ev); | 767 | time, ev); |
| 761 | IWL_ERR(trans, "EVT_LOG:0x%08x:%04u\n", | 768 | IWL_ERR(trans, "EVT_LOG:0x%08x:%04u\n", |
| 762 | time, ev); | 769 | time, ev); |
| @@ -770,7 +777,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
| 770 | } else { | 777 | } else { |
| 771 | IWL_ERR(trans, "EVT_LOGT:%010u:0x%08x:%04u\n", | 778 | IWL_ERR(trans, "EVT_LOGT:%010u:0x%08x:%04u\n", |
| 772 | time, data, ev); | 779 | time, data, ev); |
| 773 | trace_iwlwifi_dev_ucode_event(priv(trans), time, | 780 | trace_iwlwifi_dev_ucode_event(trans->dev, time, |
| 774 | data, ev); | 781 | data, ev); |
| 775 | } | 782 | } |
| 776 | } | 783 | } |
| @@ -778,6 +785,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
| 778 | 785 | ||
| 779 | /* Allow device to power down */ | 786 | /* Allow device to power down */ |
| 780 | iwl_release_nic_access(trans); | 787 | iwl_release_nic_access(trans); |
| 788 | out_unlock: | ||
| 781 | spin_unlock_irqrestore(&trans->reg_lock, reg_flags); | 789 | spin_unlock_irqrestore(&trans->reg_lock, reg_flags); |
| 782 | return pos; | 790 | return pos; |
| 783 | } | 791 | } |
| @@ -832,17 +840,16 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, | |||
| 832 | u32 logsize; | 840 | u32 logsize; |
| 833 | int pos = 0; | 841 | int pos = 0; |
| 834 | size_t bufsz = 0; | 842 | size_t bufsz = 0; |
| 835 | struct iwl_nic *nic = nic(trans); | ||
| 836 | 843 | ||
| 837 | base = trans->shrd->device_pointers.log_event_table; | 844 | base = trans->shrd->device_pointers.log_event_table; |
| 838 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) { | 845 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) { |
| 839 | logsize = nic->init_evtlog_size; | 846 | logsize = trans->shrd->fw->init_evtlog_size; |
| 840 | if (!base) | 847 | if (!base) |
| 841 | base = nic->init_evtlog_ptr; | 848 | base = trans->shrd->fw->init_evtlog_ptr; |
| 842 | } else { | 849 | } else { |
| 843 | logsize = nic->inst_evtlog_size; | 850 | logsize = trans->shrd->fw->inst_evtlog_size; |
| 844 | if (!base) | 851 | if (!base) |
| 845 | base = nic->inst_evtlog_ptr; | 852 | base = trans->shrd->fw->inst_evtlog_ptr; |
| 846 | } | 853 | } |
| 847 | 854 | ||
| 848 | if (!iwlagn_hw_valid_rtc_data_addr(base)) { | 855 | if (!iwlagn_hw_valid_rtc_data_addr(base)) { |
| @@ -881,7 +888,7 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, | |||
| 881 | } | 888 | } |
| 882 | 889 | ||
| 883 | #ifdef CONFIG_IWLWIFI_DEBUG | 890 | #ifdef CONFIG_IWLWIFI_DEBUG |
| 884 | if (!(iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS) && !full_log) | 891 | if (!(iwl_have_debug_level(IWL_DL_FW_ERRORS)) && !full_log) |
| 885 | size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) | 892 | size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) |
| 886 | ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; | 893 | ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; |
| 887 | #else | 894 | #else |
| @@ -901,7 +908,7 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, | |||
| 901 | if (!*buf) | 908 | if (!*buf) |
| 902 | return -ENOMEM; | 909 | return -ENOMEM; |
| 903 | } | 910 | } |
| 904 | if ((iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS) || full_log) { | 911 | if (iwl_have_debug_level(IWL_DL_FW_ERRORS) || full_log) { |
| 905 | /* | 912 | /* |
| 906 | * if uCode has wrapped back to top of log, | 913 | * if uCode has wrapped back to top of log, |
| 907 | * start at the oldest entry, | 914 | * start at the oldest entry, |
| @@ -960,7 +967,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
| 960 | inta = trans_pcie->inta; | 967 | inta = trans_pcie->inta; |
| 961 | 968 | ||
| 962 | #ifdef CONFIG_IWLWIFI_DEBUG | 969 | #ifdef CONFIG_IWLWIFI_DEBUG |
| 963 | if (iwl_get_debug_level(trans->shrd) & IWL_DL_ISR) { | 970 | if (iwl_have_debug_level(IWL_DL_ISR)) { |
| 964 | /* just for debug */ | 971 | /* just for debug */ |
| 965 | inta_mask = iwl_read32(trans, CSR_INT_MASK); | 972 | inta_mask = iwl_read32(trans, CSR_INT_MASK); |
| 966 | IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n ", | 973 | IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n ", |
| @@ -989,7 +996,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
| 989 | } | 996 | } |
| 990 | 997 | ||
| 991 | #ifdef CONFIG_IWLWIFI_DEBUG | 998 | #ifdef CONFIG_IWLWIFI_DEBUG |
| 992 | if (iwl_get_debug_level(trans->shrd) & (IWL_DL_ISR)) { | 999 | if (iwl_have_debug_level(IWL_DL_ISR)) { |
| 993 | /* NIC fires this, but we don't use it, redundant with WAKEUP */ | 1000 | /* NIC fires this, but we don't use it, redundant with WAKEUP */ |
| 994 | if (inta & CSR_INT_BIT_SCD) { | 1001 | if (inta & CSR_INT_BIT_SCD) { |
| 995 | IWL_DEBUG_ISR(trans, "Scheduler finished to transmit " | 1002 | IWL_DEBUG_ISR(trans, "Scheduler finished to transmit " |
| @@ -1009,30 +1016,16 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
| 1009 | 1016 | ||
| 1010 | /* HW RF KILL switch toggled */ | 1017 | /* HW RF KILL switch toggled */ |
| 1011 | if (inta & CSR_INT_BIT_RF_KILL) { | 1018 | if (inta & CSR_INT_BIT_RF_KILL) { |
| 1012 | int hw_rf_kill = 0; | 1019 | bool hw_rfkill; |
| 1013 | if (!(iwl_read32(trans, CSR_GP_CNTRL) & | ||
| 1014 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) | ||
| 1015 | hw_rf_kill = 1; | ||
| 1016 | 1020 | ||
| 1021 | hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) & | ||
| 1022 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); | ||
| 1017 | IWL_WARN(trans, "RF_KILL bit toggled to %s.\n", | 1023 | IWL_WARN(trans, "RF_KILL bit toggled to %s.\n", |
| 1018 | hw_rf_kill ? "disable radio" : "enable radio"); | 1024 | hw_rfkill ? "disable radio" : "enable radio"); |
| 1019 | 1025 | ||
| 1020 | isr_stats->rfkill++; | 1026 | isr_stats->rfkill++; |
| 1021 | 1027 | ||
| 1022 | /* driver only loads ucode once setting the interface up. | 1028 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); |
| 1023 | * the driver allows loading the ucode even if the radio | ||
| 1024 | * is killed. Hence update the killswitch state here. The | ||
| 1025 | * rfkill handler will care about restarting if needed. | ||
| 1026 | */ | ||
| 1027 | if (!test_bit(STATUS_ALIVE, &trans->shrd->status)) { | ||
| 1028 | if (hw_rf_kill) | ||
| 1029 | set_bit(STATUS_RF_KILL_HW, | ||
| 1030 | &trans->shrd->status); | ||
| 1031 | else | ||
| 1032 | clear_bit(STATUS_RF_KILL_HW, | ||
| 1033 | &trans->shrd->status); | ||
| 1034 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rf_kill); | ||
| 1035 | } | ||
| 1036 | 1029 | ||
| 1037 | handled |= CSR_INT_BIT_RF_KILL; | 1030 | handled |= CSR_INT_BIT_RF_KILL; |
| 1038 | } | 1031 | } |
| @@ -1057,7 +1050,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
| 1057 | if (inta & CSR_INT_BIT_WAKEUP) { | 1050 | if (inta & CSR_INT_BIT_WAKEUP) { |
| 1058 | IWL_DEBUG_ISR(trans, "Wakeup interrupt\n"); | 1051 | IWL_DEBUG_ISR(trans, "Wakeup interrupt\n"); |
| 1059 | iwl_rx_queue_update_write_ptr(trans, &trans_pcie->rxq); | 1052 | iwl_rx_queue_update_write_ptr(trans, &trans_pcie->rxq); |
| 1060 | for (i = 0; i < hw_params(trans).max_txq_num; i++) | 1053 | for (i = 0; i < cfg(trans)->base_params->num_of_queues; i++) |
| 1061 | iwl_txq_update_write_ptr(trans, | 1054 | iwl_txq_update_write_ptr(trans, |
| 1062 | &trans_pcie->txq[i]); | 1055 | &trans_pcie->txq[i]); |
| 1063 | 1056 | ||
| @@ -1122,8 +1115,8 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
| 1122 | isr_stats->tx++; | 1115 | isr_stats->tx++; |
| 1123 | handled |= CSR_INT_BIT_FH_TX; | 1116 | handled |= CSR_INT_BIT_FH_TX; |
| 1124 | /* Wake up uCode load routine, now that load is complete */ | 1117 | /* Wake up uCode load routine, now that load is complete */ |
| 1125 | trans->ucode_write_complete = 1; | 1118 | trans_pcie->ucode_write_complete = true; |
| 1126 | wake_up(&trans->shrd->wait_command_queue); | 1119 | wake_up(&trans_pcie->ucode_write_waitq); |
| 1127 | } | 1120 | } |
| 1128 | 1121 | ||
| 1129 | if (inta & ~handled) { | 1122 | if (inta & ~handled) { |
| @@ -1138,13 +1131,11 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
| 1138 | 1131 | ||
| 1139 | /* Re-enable all interrupts */ | 1132 | /* Re-enable all interrupts */ |
| 1140 | /* only Re-enable if disabled by irq */ | 1133 | /* only Re-enable if disabled by irq */ |
| 1141 | if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status)) | 1134 | if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status)) |
| 1142 | iwl_enable_interrupts(trans); | 1135 | iwl_enable_interrupts(trans); |
| 1143 | /* Re-enable RF_KILL if it occurred */ | 1136 | /* Re-enable RF_KILL if it occurred */ |
| 1144 | else if (handled & CSR_INT_BIT_RF_KILL) { | 1137 | else if (handled & CSR_INT_BIT_RF_KILL) |
| 1145 | IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); | 1138 | iwl_enable_rfkill_int(trans); |
| 1146 | iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); | ||
| 1147 | } | ||
| 1148 | } | 1139 | } |
| 1149 | 1140 | ||
| 1150 | /****************************************************************************** | 1141 | /****************************************************************************** |
| @@ -1269,7 +1260,7 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
| 1269 | if (!trans) | 1260 | if (!trans) |
| 1270 | return IRQ_NONE; | 1261 | return IRQ_NONE; |
| 1271 | 1262 | ||
| 1272 | trace_iwlwifi_dev_irq(priv(trans)); | 1263 | trace_iwlwifi_dev_irq(trans->dev); |
| 1273 | 1264 | ||
| 1274 | trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1265 | trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
| 1275 | 1266 | ||
| @@ -1301,7 +1292,7 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
| 1301 | } | 1292 | } |
| 1302 | 1293 | ||
| 1303 | #ifdef CONFIG_IWLWIFI_DEBUG | 1294 | #ifdef CONFIG_IWLWIFI_DEBUG |
| 1304 | if (iwl_get_debug_level(trans->shrd) & (IWL_DL_ISR)) { | 1295 | if (iwl_have_debug_level(IWL_DL_ISR)) { |
| 1305 | inta_fh = iwl_read32(trans, CSR_FH_INT_STATUS); | 1296 | inta_fh = iwl_read32(trans, CSR_FH_INT_STATUS); |
| 1306 | IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled 0x%08x, " | 1297 | IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled 0x%08x, " |
| 1307 | "fh 0x%08x\n", inta, inta_mask, inta_fh); | 1298 | "fh 0x%08x\n", inta, inta_mask, inta_fh); |
| @@ -1312,7 +1303,7 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
| 1312 | /* iwl_irq_tasklet() will service interrupts and re-enable them */ | 1303 | /* iwl_irq_tasklet() will service interrupts and re-enable them */ |
| 1313 | if (likely(inta)) | 1304 | if (likely(inta)) |
| 1314 | tasklet_schedule(&trans_pcie->irq_tasklet); | 1305 | tasklet_schedule(&trans_pcie->irq_tasklet); |
| 1315 | else if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && | 1306 | else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && |
| 1316 | !trans_pcie->inta) | 1307 | !trans_pcie->inta) |
| 1317 | iwl_enable_interrupts(trans); | 1308 | iwl_enable_interrupts(trans); |
| 1318 | 1309 | ||
| @@ -1323,7 +1314,7 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
| 1323 | none: | 1314 | none: |
| 1324 | /* re-enable interrupts here since we don't have anything to service. */ | 1315 | /* re-enable interrupts here since we don't have anything to service. */ |
| 1325 | /* only Re-enable if disabled by irq and no schedules tasklet. */ | 1316 | /* only Re-enable if disabled by irq and no schedules tasklet. */ |
| 1326 | if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && | 1317 | if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && |
| 1327 | !trans_pcie->inta) | 1318 | !trans_pcie->inta) |
| 1328 | iwl_enable_interrupts(trans); | 1319 | iwl_enable_interrupts(trans); |
| 1329 | 1320 | ||
| @@ -1359,7 +1350,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
| 1359 | if (!trans_pcie->use_ict) | 1350 | if (!trans_pcie->use_ict) |
| 1360 | return iwl_isr(irq, data); | 1351 | return iwl_isr(irq, data); |
| 1361 | 1352 | ||
| 1362 | trace_iwlwifi_dev_irq(priv(trans)); | 1353 | trace_iwlwifi_dev_irq(trans->dev); |
| 1363 | 1354 | ||
| 1364 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 1355 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); |
| 1365 | 1356 | ||
| @@ -1376,7 +1367,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
| 1376 | * This may be due to IRQ shared with another device, | 1367 | * This may be due to IRQ shared with another device, |
| 1377 | * or due to sporadic interrupts thrown from our NIC. */ | 1368 | * or due to sporadic interrupts thrown from our NIC. */ |
| 1378 | read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); | 1369 | read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); |
| 1379 | trace_iwlwifi_dev_ict_read(priv(trans), trans_pcie->ict_index, read); | 1370 | trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index, read); |
| 1380 | if (!read) { | 1371 | if (!read) { |
| 1381 | IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n"); | 1372 | IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n"); |
| 1382 | goto none; | 1373 | goto none; |
| @@ -1395,7 +1386,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
| 1395 | iwl_queue_inc_wrap(trans_pcie->ict_index, ICT_COUNT); | 1386 | iwl_queue_inc_wrap(trans_pcie->ict_index, ICT_COUNT); |
| 1396 | 1387 | ||
| 1397 | read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); | 1388 | read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); |
| 1398 | trace_iwlwifi_dev_ict_read(priv(trans), trans_pcie->ict_index, | 1389 | trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index, |
| 1399 | read); | 1390 | read); |
| 1400 | } while (read); | 1391 | } while (read); |
| 1401 | 1392 | ||
| @@ -1423,7 +1414,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
| 1423 | /* iwl_irq_tasklet() will service interrupts and re-enable them */ | 1414 | /* iwl_irq_tasklet() will service interrupts and re-enable them */ |
| 1424 | if (likely(inta)) | 1415 | if (likely(inta)) |
| 1425 | tasklet_schedule(&trans_pcie->irq_tasklet); | 1416 | tasklet_schedule(&trans_pcie->irq_tasklet); |
| 1426 | else if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && | 1417 | else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && |
| 1427 | !trans_pcie->inta) { | 1418 | !trans_pcie->inta) { |
| 1428 | /* Allow interrupt if was disabled by this handler and | 1419 | /* Allow interrupt if was disabled by this handler and |
| 1429 | * no tasklet was schedules, We should not enable interrupt, | 1420 | * no tasklet was schedules, We should not enable interrupt, |
| @@ -1439,7 +1430,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
| 1439 | /* re-enable interrupts here since we don't have anything to service. | 1430 | /* re-enable interrupts here since we don't have anything to service. |
| 1440 | * only Re-enable if disabled by irq. | 1431 | * only Re-enable if disabled by irq. |
| 1441 | */ | 1432 | */ |
| 1442 | if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && | 1433 | if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && |
| 1443 | !trans_pcie->inta) | 1434 | !trans_pcie->inta) |
| 1444 | iwl_enable_interrupts(trans); | 1435 | iwl_enable_interrupts(trans); |
| 1445 | 1436 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 4e1e74e1b794..eb430b6e1cde 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | |||
| @@ -41,6 +41,43 @@ | |||
| 41 | #define IWL_TX_CRC_SIZE 4 | 41 | #define IWL_TX_CRC_SIZE 4 |
| 42 | #define IWL_TX_DELIMITER_SIZE 4 | 42 | #define IWL_TX_DELIMITER_SIZE 4 |
| 43 | 43 | ||
| 44 | /* | ||
| 45 | * mac80211 queues, ACs, hardware queues, FIFOs. | ||
| 46 | * | ||
| 47 | * Cf. http://wireless.kernel.org/en/developers/Documentation/mac80211/queues | ||
| 48 | * | ||
| 49 | * Mac80211 uses the following numbers, which we get as from it | ||
| 50 | * by way of skb_get_queue_mapping(skb): | ||
| 51 | * | ||
| 52 | * VO 0 | ||
| 53 | * VI 1 | ||
| 54 | * BE 2 | ||
| 55 | * BK 3 | ||
| 56 | * | ||
| 57 | * | ||
| 58 | * Regular (not A-MPDU) frames are put into hardware queues corresponding | ||
| 59 | * to the FIFOs, see comments in iwl-prph.h. Aggregated frames get their | ||
| 60 | * own queue per aggregation session (RA/TID combination), such queues are | ||
| 61 | * set up to map into FIFOs too, for which we need an AC->FIFO mapping. In | ||
| 62 | * order to map frames to the right queue, we also need an AC->hw queue | ||
| 63 | * mapping. This is implemented here. | ||
| 64 | * | ||
| 65 | * Due to the way hw queues are set up (by the hw specific code), the AC->hw | ||
| 66 | * queue mapping is the identity mapping. | ||
| 67 | */ | ||
| 68 | |||
| 69 | static const u8 tid_to_ac[] = { | ||
| 70 | IEEE80211_AC_BE, | ||
| 71 | IEEE80211_AC_BK, | ||
| 72 | IEEE80211_AC_BK, | ||
| 73 | IEEE80211_AC_BE, | ||
| 74 | IEEE80211_AC_VI, | ||
| 75 | IEEE80211_AC_VI, | ||
| 76 | IEEE80211_AC_VO, | ||
| 77 | IEEE80211_AC_VO | ||
| 78 | }; | ||
| 79 | |||
| 80 | |||
| 44 | /** | 81 | /** |
| 45 | * iwl_trans_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array | 82 | * iwl_trans_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array |
| 46 | */ | 83 | */ |
| @@ -99,7 +136,7 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) | |||
| 99 | if (txq->need_update == 0) | 136 | if (txq->need_update == 0) |
| 100 | return; | 137 | return; |
| 101 | 138 | ||
| 102 | if (hw_params(trans).shadow_reg_enable) { | 139 | if (cfg(trans)->base_params->shadow_reg_enable) { |
| 103 | /* shadow register enabled */ | 140 | /* shadow register enabled */ |
| 104 | iwl_write32(trans, HBUS_TARG_WRPTR, | 141 | iwl_write32(trans, HBUS_TARG_WRPTR, |
| 105 | txq->q.write_ptr | (txq_id << 8)); | 142 | txq->q.write_ptr | (txq_id << 8)); |
| @@ -217,6 +254,8 @@ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, | |||
| 217 | { | 254 | { |
| 218 | struct iwl_tfd *tfd_tmp = txq->tfds; | 255 | struct iwl_tfd *tfd_tmp = txq->tfds; |
| 219 | 256 | ||
| 257 | lockdep_assert_held(&txq->lock); | ||
| 258 | |||
| 220 | iwlagn_unmap_tfd(trans, &txq->meta[index], &tfd_tmp[index], dma_dir); | 259 | iwlagn_unmap_tfd(trans, &txq->meta[index], &tfd_tmp[index], dma_dir); |
| 221 | 260 | ||
| 222 | /* free SKB */ | 261 | /* free SKB */ |
| @@ -358,7 +397,7 @@ static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_trans *trans, | |||
| 358 | 397 | ||
| 359 | WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX); | 398 | WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX); |
| 360 | 399 | ||
| 361 | if (txq_id != trans->shrd->cmd_queue) | 400 | if (txq_id != trans_pcie->cmd_queue) |
| 362 | sta_id = tx_cmd->sta_id; | 401 | sta_id = tx_cmd->sta_id; |
| 363 | 402 | ||
| 364 | bc_ent = cpu_to_le16(1 | (sta_id << 12)); | 403 | bc_ent = cpu_to_le16(1 | (sta_id << 12)); |
| @@ -440,6 +479,15 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, | |||
| 440 | scd_retry ? "BA" : "AC/CMD", txq_id); | 479 | scd_retry ? "BA" : "AC/CMD", txq_id); |
| 441 | } | 480 | } |
| 442 | 481 | ||
| 482 | static inline int get_ac_from_tid(u16 tid) | ||
| 483 | { | ||
| 484 | if (likely(tid < ARRAY_SIZE(tid_to_ac))) | ||
| 485 | return tid_to_ac[tid]; | ||
| 486 | |||
| 487 | /* no support for TIDs 8-15 yet */ | ||
| 488 | return -EINVAL; | ||
| 489 | } | ||
| 490 | |||
| 443 | static inline int get_fifo_from_tid(struct iwl_trans_pcie *trans_pcie, | 491 | static inline int get_fifo_from_tid(struct iwl_trans_pcie *trans_pcie, |
| 444 | u8 ctx, u16 tid) | 492 | u8 ctx, u16 tid) |
| 445 | { | 493 | { |
| @@ -547,7 +595,8 @@ static int iwlagn_txq_ctx_activate_free(struct iwl_trans *trans) | |||
| 547 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 595 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
| 548 | int txq_id; | 596 | int txq_id; |
| 549 | 597 | ||
| 550 | for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) | 598 | for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues; |
| 599 | txq_id++) | ||
| 551 | if (!test_and_set_bit(txq_id, | 600 | if (!test_and_set_bit(txq_id, |
| 552 | &trans_pcie->txq_ctx_active_msk)) | 601 | &trans_pcie->txq_ctx_active_msk)) |
| 553 | return txq_id; | 602 | return txq_id; |
| @@ -616,15 +665,13 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid) | |||
| 616 | static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | 665 | static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) |
| 617 | { | 666 | { |
| 618 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 667 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
| 619 | struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue]; | 668 | struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; |
| 620 | struct iwl_queue *q = &txq->q; | 669 | struct iwl_queue *q = &txq->q; |
| 621 | struct iwl_device_cmd *out_cmd; | 670 | struct iwl_device_cmd *out_cmd; |
| 622 | struct iwl_cmd_meta *out_meta; | 671 | struct iwl_cmd_meta *out_meta; |
| 623 | dma_addr_t phys_addr; | 672 | dma_addr_t phys_addr; |
| 624 | unsigned long flags; | ||
| 625 | u32 idx; | 673 | u32 idx; |
| 626 | u16 copy_size, cmd_size; | 674 | u16 copy_size, cmd_size; |
| 627 | bool is_ct_kill = false; | ||
| 628 | bool had_nocopy = false; | 675 | bool had_nocopy = false; |
| 629 | int i; | 676 | int i; |
| 630 | u8 *cmd_dest; | 677 | u8 *cmd_dest; |
| @@ -639,12 +686,6 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
| 639 | return -EIO; | 686 | return -EIO; |
| 640 | } | 687 | } |
| 641 | 688 | ||
| 642 | if ((trans->shrd->ucode_owner == IWL_OWNERSHIP_TM) && | ||
| 643 | !(cmd->flags & CMD_ON_DEMAND)) { | ||
| 644 | IWL_DEBUG_HC(trans, "tm own the uCode, no regular hcmd send\n"); | ||
| 645 | return -EIO; | ||
| 646 | } | ||
| 647 | |||
| 648 | copy_size = sizeof(out_cmd->hdr); | 689 | copy_size = sizeof(out_cmd->hdr); |
| 649 | cmd_size = sizeof(out_cmd->hdr); | 690 | cmd_size = sizeof(out_cmd->hdr); |
| 650 | 691 | ||
| @@ -674,23 +715,13 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
| 674 | if (WARN_ON(copy_size > TFD_MAX_PAYLOAD_SIZE)) | 715 | if (WARN_ON(copy_size > TFD_MAX_PAYLOAD_SIZE)) |
| 675 | return -EINVAL; | 716 | return -EINVAL; |
| 676 | 717 | ||
| 677 | if (iwl_is_rfkill(trans->shrd) || iwl_is_ctkill(trans->shrd)) { | 718 | spin_lock_bh(&txq->lock); |
| 678 | IWL_WARN(trans, "Not sending command - %s KILL\n", | ||
| 679 | iwl_is_rfkill(trans->shrd) ? "RF" : "CT"); | ||
| 680 | return -EIO; | ||
| 681 | } | ||
| 682 | |||
| 683 | spin_lock_irqsave(&trans->hcmd_lock, flags); | ||
| 684 | 719 | ||
| 685 | if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { | 720 | if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { |
| 686 | spin_unlock_irqrestore(&trans->hcmd_lock, flags); | 721 | spin_unlock_bh(&txq->lock); |
| 687 | 722 | ||
| 688 | IWL_ERR(trans, "No space in command queue\n"); | 723 | IWL_ERR(trans, "No space in command queue\n"); |
| 689 | is_ct_kill = iwl_check_for_ct_kill(priv(trans)); | 724 | iwl_op_mode_cmd_queue_full(trans->op_mode); |
| 690 | if (!is_ct_kill) { | ||
| 691 | IWL_ERR(trans, "Restarting adapter queue is full\n"); | ||
| 692 | iwl_op_mode_nic_error(trans->op_mode); | ||
| 693 | } | ||
| 694 | return -ENOSPC; | 725 | return -ENOSPC; |
| 695 | } | 726 | } |
| 696 | 727 | ||
| @@ -707,7 +738,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
| 707 | out_cmd->hdr.cmd = cmd->id; | 738 | out_cmd->hdr.cmd = cmd->id; |
| 708 | out_cmd->hdr.flags = 0; | 739 | out_cmd->hdr.flags = 0; |
| 709 | out_cmd->hdr.sequence = | 740 | out_cmd->hdr.sequence = |
| 710 | cpu_to_le16(QUEUE_TO_SEQ(trans->shrd->cmd_queue) | | 741 | cpu_to_le16(QUEUE_TO_SEQ(trans_pcie->cmd_queue) | |
| 711 | INDEX_TO_SEQ(q->write_ptr)); | 742 | INDEX_TO_SEQ(q->write_ptr)); |
| 712 | 743 | ||
| 713 | /* and copy the data that needs to be copied */ | 744 | /* and copy the data that needs to be copied */ |
| @@ -727,7 +758,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
| 727 | get_cmd_string(out_cmd->hdr.cmd), | 758 | get_cmd_string(out_cmd->hdr.cmd), |
| 728 | out_cmd->hdr.cmd, | 759 | out_cmd->hdr.cmd, |
| 729 | le16_to_cpu(out_cmd->hdr.sequence), cmd_size, | 760 | le16_to_cpu(out_cmd->hdr.sequence), cmd_size, |
| 730 | q->write_ptr, idx, trans->shrd->cmd_queue); | 761 | q->write_ptr, idx, trans_pcie->cmd_queue); |
| 731 | 762 | ||
| 732 | phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, | 763 | phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, |
| 733 | DMA_BIDIRECTIONAL); | 764 | DMA_BIDIRECTIONAL); |
| @@ -779,7 +810,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
| 779 | /* check that tracing gets all possible blocks */ | 810 | /* check that tracing gets all possible blocks */ |
| 780 | BUILD_BUG_ON(IWL_MAX_CMD_TFDS + 1 != 3); | 811 | BUILD_BUG_ON(IWL_MAX_CMD_TFDS + 1 != 3); |
| 781 | #ifdef CONFIG_IWLWIFI_DEVICE_TRACING | 812 | #ifdef CONFIG_IWLWIFI_DEVICE_TRACING |
| 782 | trace_iwlwifi_dev_hcmd(priv(trans), cmd->flags, | 813 | trace_iwlwifi_dev_hcmd(trans->dev, cmd->flags, |
| 783 | trace_bufs[0], trace_lens[0], | 814 | trace_bufs[0], trace_lens[0], |
| 784 | trace_bufs[1], trace_lens[1], | 815 | trace_bufs[1], trace_lens[1], |
| 785 | trace_bufs[2], trace_lens[2]); | 816 | trace_bufs[2], trace_lens[2]); |
| @@ -790,7 +821,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
| 790 | iwl_txq_update_write_ptr(trans, txq); | 821 | iwl_txq_update_write_ptr(trans, txq); |
| 791 | 822 | ||
| 792 | out: | 823 | out: |
| 793 | spin_unlock_irqrestore(&trans->hcmd_lock, flags); | 824 | spin_unlock_bh(&txq->lock); |
| 794 | return idx; | 825 | return idx; |
| 795 | } | 826 | } |
| 796 | 827 | ||
| @@ -809,6 +840,8 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id, | |||
| 809 | struct iwl_queue *q = &txq->q; | 840 | struct iwl_queue *q = &txq->q; |
| 810 | int nfreed = 0; | 841 | int nfreed = 0; |
| 811 | 842 | ||
| 843 | lockdep_assert_held(&txq->lock); | ||
| 844 | |||
| 812 | if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) { | 845 | if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) { |
| 813 | IWL_ERR(trans, "%s: Read index for DMA queue txq id (%d), " | 846 | IWL_ERR(trans, "%s: Read index for DMA queue txq id (%d), " |
| 814 | "index %d is out of range [0-%d] %d %d.\n", __func__, | 847 | "index %d is out of range [0-%d] %d %d.\n", __func__, |
| @@ -838,7 +871,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id, | |||
| 838 | * will be executed. The attached skb (if present) will only be freed | 871 | * will be executed. The attached skb (if present) will only be freed |
| 839 | * if the callback returns 1 | 872 | * if the callback returns 1 |
| 840 | */ | 873 | */ |
| 841 | void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, | 874 | void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, |
| 842 | int handler_status) | 875 | int handler_status) |
| 843 | { | 876 | { |
| 844 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 877 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| @@ -849,21 +882,22 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, | |||
| 849 | struct iwl_device_cmd *cmd; | 882 | struct iwl_device_cmd *cmd; |
| 850 | struct iwl_cmd_meta *meta; | 883 | struct iwl_cmd_meta *meta; |
| 851 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 884 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
| 852 | struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue]; | 885 | struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; |
| 853 | unsigned long flags; | ||
| 854 | 886 | ||
| 855 | /* If a Tx command is being handled and it isn't in the actual | 887 | /* If a Tx command is being handled and it isn't in the actual |
| 856 | * command queue then there a command routing bug has been introduced | 888 | * command queue then there a command routing bug has been introduced |
| 857 | * in the queue management code. */ | 889 | * in the queue management code. */ |
| 858 | if (WARN(txq_id != trans->shrd->cmd_queue, | 890 | if (WARN(txq_id != trans_pcie->cmd_queue, |
| 859 | "wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n", | 891 | "wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n", |
| 860 | txq_id, trans->shrd->cmd_queue, sequence, | 892 | txq_id, trans_pcie->cmd_queue, sequence, |
| 861 | trans_pcie->txq[trans->shrd->cmd_queue].q.read_ptr, | 893 | trans_pcie->txq[trans_pcie->cmd_queue].q.read_ptr, |
| 862 | trans_pcie->txq[trans->shrd->cmd_queue].q.write_ptr)) { | 894 | trans_pcie->txq[trans_pcie->cmd_queue].q.write_ptr)) { |
| 863 | iwl_print_hex_error(trans, pkt, 32); | 895 | iwl_print_hex_error(trans, pkt, 32); |
| 864 | return; | 896 | return; |
| 865 | } | 897 | } |
| 866 | 898 | ||
| 899 | spin_lock(&txq->lock); | ||
| 900 | |||
| 867 | cmd_index = get_cmd_index(&txq->q, index); | 901 | cmd_index = get_cmd_index(&txq->q, index); |
| 868 | cmd = txq->cmd[cmd_index]; | 902 | cmd = txq->cmd[cmd_index]; |
| 869 | meta = &txq->meta[cmd_index]; | 903 | meta = &txq->meta[cmd_index]; |
| @@ -875,13 +909,14 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, | |||
| 875 | 909 | ||
| 876 | /* Input error checking is done when commands are added to queue. */ | 910 | /* Input error checking is done when commands are added to queue. */ |
| 877 | if (meta->flags & CMD_WANT_SKB) { | 911 | if (meta->flags & CMD_WANT_SKB) { |
| 878 | meta->source->reply_page = (unsigned long)rxb_addr(rxb); | 912 | struct page *p = rxb_steal_page(rxb); |
| 913 | |||
| 914 | meta->source->resp_pkt = pkt; | ||
| 915 | meta->source->_rx_page_addr = (unsigned long)page_address(p); | ||
| 916 | meta->source->_rx_page_order = hw_params(trans).rx_page_order; | ||
| 879 | meta->source->handler_status = handler_status; | 917 | meta->source->handler_status = handler_status; |
| 880 | rxb->page = NULL; | ||
| 881 | } | 918 | } |
| 882 | 919 | ||
| 883 | spin_lock_irqsave(&trans->hcmd_lock, flags); | ||
| 884 | |||
| 885 | iwl_hcmd_queue_reclaim(trans, txq_id, index); | 920 | iwl_hcmd_queue_reclaim(trans, txq_id, index); |
| 886 | 921 | ||
| 887 | if (!(meta->flags & CMD_ASYNC)) { | 922 | if (!(meta->flags & CMD_ASYNC)) { |
| @@ -898,7 +933,7 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, | |||
| 898 | 933 | ||
| 899 | meta->flags = 0; | 934 | meta->flags = 0; |
| 900 | 935 | ||
| 901 | spin_unlock_irqrestore(&trans->hcmd_lock, flags); | 936 | spin_unlock(&txq->lock); |
| 902 | } | 937 | } |
| 903 | 938 | ||
| 904 | #define HOST_COMPLETE_TIMEOUT (2 * HZ) | 939 | #define HOST_COMPLETE_TIMEOUT (2 * HZ) |
| @@ -912,12 +947,9 @@ static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
| 912 | return -EINVAL; | 947 | return -EINVAL; |
| 913 | 948 | ||
| 914 | 949 | ||
| 915 | if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status)) | ||
| 916 | return -EBUSY; | ||
| 917 | |||
| 918 | ret = iwl_enqueue_hcmd(trans, cmd); | 950 | ret = iwl_enqueue_hcmd(trans, cmd); |
| 919 | if (ret < 0) { | 951 | if (ret < 0) { |
| 920 | IWL_DEBUG_QUIET_RFKILL(trans, | 952 | IWL_ERR(trans, |
| 921 | "Error sending %s: enqueue_hcmd failed: %d\n", | 953 | "Error sending %s: enqueue_hcmd failed: %d\n", |
| 922 | get_cmd_string(cmd->id), ret); | 954 | get_cmd_string(cmd->id), ret); |
| 923 | return ret; | 955 | return ret; |
| @@ -931,26 +963,22 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
| 931 | int cmd_idx; | 963 | int cmd_idx; |
| 932 | int ret; | 964 | int ret; |
| 933 | 965 | ||
| 934 | lockdep_assert_held(&trans->shrd->mutex); | ||
| 935 | |||
| 936 | IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", | 966 | IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", |
| 937 | get_cmd_string(cmd->id)); | 967 | get_cmd_string(cmd->id)); |
| 938 | 968 | ||
| 939 | if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status)) | ||
| 940 | return -EBUSY; | ||
| 941 | |||
| 942 | |||
| 943 | if (test_bit(STATUS_RF_KILL_HW, &trans->shrd->status)) { | ||
| 944 | IWL_ERR(trans, "Command %s aborted: RF KILL Switch\n", | ||
| 945 | get_cmd_string(cmd->id)); | ||
| 946 | return -ECANCELED; | ||
| 947 | } | ||
| 948 | if (test_bit(STATUS_FW_ERROR, &trans->shrd->status)) { | 969 | if (test_bit(STATUS_FW_ERROR, &trans->shrd->status)) { |
| 949 | IWL_ERR(trans, "Command %s failed: FW Error\n", | 970 | IWL_ERR(trans, "Command %s failed: FW Error\n", |
| 950 | get_cmd_string(cmd->id)); | 971 | get_cmd_string(cmd->id)); |
| 951 | return -EIO; | 972 | return -EIO; |
| 952 | } | 973 | } |
| 953 | set_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); | 974 | |
| 975 | if (WARN_ON(test_and_set_bit(STATUS_HCMD_ACTIVE, | ||
| 976 | &trans->shrd->status))) { | ||
| 977 | IWL_ERR(trans, "Command %s: a command is already active!\n", | ||
| 978 | get_cmd_string(cmd->id)); | ||
| 979 | return -EIO; | ||
| 980 | } | ||
| 981 | |||
| 954 | IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", | 982 | IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", |
| 955 | get_cmd_string(cmd->id)); | 983 | get_cmd_string(cmd->id)); |
| 956 | 984 | ||
| @@ -958,7 +986,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
| 958 | if (cmd_idx < 0) { | 986 | if (cmd_idx < 0) { |
| 959 | ret = cmd_idx; | 987 | ret = cmd_idx; |
| 960 | clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); | 988 | clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); |
| 961 | IWL_DEBUG_QUIET_RFKILL(trans, | 989 | IWL_ERR(trans, |
| 962 | "Error sending %s: enqueue_hcmd failed: %d\n", | 990 | "Error sending %s: enqueue_hcmd failed: %d\n", |
| 963 | get_cmd_string(cmd->id), ret); | 991 | get_cmd_string(cmd->id), ret); |
| 964 | return ret; | 992 | return ret; |
| @@ -970,15 +998,15 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
| 970 | if (!ret) { | 998 | if (!ret) { |
| 971 | if (test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status)) { | 999 | if (test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status)) { |
| 972 | struct iwl_tx_queue *txq = | 1000 | struct iwl_tx_queue *txq = |
| 973 | &trans_pcie->txq[trans->shrd->cmd_queue]; | 1001 | &trans_pcie->txq[trans_pcie->cmd_queue]; |
| 974 | struct iwl_queue *q = &txq->q; | 1002 | struct iwl_queue *q = &txq->q; |
| 975 | 1003 | ||
| 976 | IWL_DEBUG_QUIET_RFKILL(trans, | 1004 | IWL_ERR(trans, |
| 977 | "Error sending %s: time out after %dms.\n", | 1005 | "Error sending %s: time out after %dms.\n", |
| 978 | get_cmd_string(cmd->id), | 1006 | get_cmd_string(cmd->id), |
| 979 | jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); | 1007 | jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); |
| 980 | 1008 | ||
| 981 | IWL_DEBUG_QUIET_RFKILL(trans, | 1009 | IWL_ERR(trans, |
| 982 | "Current CMD queue read_ptr %d write_ptr %d\n", | 1010 | "Current CMD queue read_ptr %d write_ptr %d\n", |
| 983 | q->read_ptr, q->write_ptr); | 1011 | q->read_ptr, q->write_ptr); |
| 984 | 1012 | ||
| @@ -990,7 +1018,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
| 990 | } | 1018 | } |
| 991 | } | 1019 | } |
| 992 | 1020 | ||
| 993 | if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) { | 1021 | if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) { |
| 994 | IWL_ERR(trans, "Error: Response NULL in '%s'\n", | 1022 | IWL_ERR(trans, "Error: Response NULL in '%s'\n", |
| 995 | get_cmd_string(cmd->id)); | 1023 | get_cmd_string(cmd->id)); |
| 996 | ret = -EIO; | 1024 | ret = -EIO; |
| @@ -1007,13 +1035,13 @@ cancel: | |||
| 1007 | * in later, it will possibly set an invalid | 1035 | * in later, it will possibly set an invalid |
| 1008 | * address (cmd->meta.source). | 1036 | * address (cmd->meta.source). |
| 1009 | */ | 1037 | */ |
| 1010 | trans_pcie->txq[trans->shrd->cmd_queue].meta[cmd_idx].flags &= | 1038 | trans_pcie->txq[trans_pcie->cmd_queue].meta[cmd_idx].flags &= |
| 1011 | ~CMD_WANT_SKB; | 1039 | ~CMD_WANT_SKB; |
| 1012 | } | 1040 | } |
| 1013 | 1041 | ||
| 1014 | if (cmd->reply_page) { | 1042 | if (cmd->resp_pkt) { |
| 1015 | iwl_free_pages(trans->shrd, cmd->reply_page); | 1043 | iwl_free_resp(cmd); |
| 1016 | cmd->reply_page = 0; | 1044 | cmd->resp_pkt = NULL; |
| 1017 | } | 1045 | } |
| 1018 | 1046 | ||
| 1019 | return ret; | 1047 | return ret; |
| @@ -1038,9 +1066,11 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, | |||
| 1038 | int freed = 0; | 1066 | int freed = 0; |
| 1039 | 1067 | ||
| 1040 | /* This function is not meant to release cmd queue*/ | 1068 | /* This function is not meant to release cmd queue*/ |
| 1041 | if (WARN_ON(txq_id == trans->shrd->cmd_queue)) | 1069 | if (WARN_ON(txq_id == trans_pcie->cmd_queue)) |
| 1042 | return 0; | 1070 | return 0; |
| 1043 | 1071 | ||
| 1072 | lockdep_assert_held(&txq->lock); | ||
| 1073 | |||
| 1044 | /*Since we free until index _not_ inclusive, the one before index is | 1074 | /*Since we free until index _not_ inclusive, the one before index is |
| 1045 | * the last we will free. This one must be used */ | 1075 | * the last we will free. This one must be used */ |
| 1046 | last_to_free = iwl_queue_dec_wrap(index, q->n_bd); | 1076 | last_to_free = iwl_queue_dec_wrap(index, q->n_bd); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 9f8b23909404..91628565409f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | |||
| @@ -75,8 +75,12 @@ | |||
| 75 | #include "iwl-shared.h" | 75 | #include "iwl-shared.h" |
| 76 | #include "iwl-eeprom.h" | 76 | #include "iwl-eeprom.h" |
| 77 | #include "iwl-agn-hw.h" | 77 | #include "iwl-agn-hw.h" |
| 78 | #include "iwl-core.h" | 78 | |
| 79 | #include "iwl-ucode.h" | 79 | #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) |
| 80 | |||
| 81 | #define SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie) \ | ||
| 82 | (((1<<cfg(trans)->base_params->num_of_queues) - 1) &\ | ||
| 83 | (~(1<<(trans_pcie)->cmd_queue))) | ||
| 80 | 84 | ||
| 81 | static int iwl_trans_rx_alloc(struct iwl_trans *trans) | 85 | static int iwl_trans_rx_alloc(struct iwl_trans *trans) |
| 82 | { | 86 | { |
| @@ -301,6 +305,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, | |||
| 301 | { | 305 | { |
| 302 | size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; | 306 | size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; |
| 303 | int i; | 307 | int i; |
| 308 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
| 304 | 309 | ||
| 305 | if (WARN_ON(txq->meta || txq->cmd || txq->skbs || txq->tfds)) | 310 | if (WARN_ON(txq->meta || txq->cmd || txq->skbs || txq->tfds)) |
| 306 | return -EINVAL; | 311 | return -EINVAL; |
| @@ -313,7 +318,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, | |||
| 313 | if (!txq->meta || !txq->cmd) | 318 | if (!txq->meta || !txq->cmd) |
| 314 | goto error; | 319 | goto error; |
| 315 | 320 | ||
| 316 | if (txq_id == trans->shrd->cmd_queue) | 321 | if (txq_id == trans_pcie->cmd_queue) |
| 317 | for (i = 0; i < slots_num; i++) { | 322 | for (i = 0; i < slots_num; i++) { |
| 318 | txq->cmd[i] = kmalloc(sizeof(struct iwl_device_cmd), | 323 | txq->cmd[i] = kmalloc(sizeof(struct iwl_device_cmd), |
| 319 | GFP_KERNEL); | 324 | GFP_KERNEL); |
| @@ -324,7 +329,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, | |||
| 324 | /* Alloc driver data array and TFD circular buffer */ | 329 | /* Alloc driver data array and TFD circular buffer */ |
| 325 | /* Driver private data, only for Tx (not command) queues, | 330 | /* Driver private data, only for Tx (not command) queues, |
| 326 | * not shared with device. */ | 331 | * not shared with device. */ |
| 327 | if (txq_id != trans->shrd->cmd_queue) { | 332 | if (txq_id != trans_pcie->cmd_queue) { |
| 328 | txq->skbs = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(txq->skbs[0]), | 333 | txq->skbs = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(txq->skbs[0]), |
| 329 | GFP_KERNEL); | 334 | GFP_KERNEL); |
| 330 | if (!txq->skbs) { | 335 | if (!txq->skbs) { |
| @@ -352,7 +357,7 @@ error: | |||
| 352 | txq->skbs = NULL; | 357 | txq->skbs = NULL; |
| 353 | /* since txq->cmd has been zeroed, | 358 | /* since txq->cmd has been zeroed, |
| 354 | * all non allocated cmd[i] will be NULL */ | 359 | * all non allocated cmd[i] will be NULL */ |
| 355 | if (txq->cmd && txq_id == trans->shrd->cmd_queue) | 360 | if (txq->cmd && txq_id == trans_pcie->cmd_queue) |
| 356 | for (i = 0; i < slots_num; i++) | 361 | for (i = 0; i < slots_num; i++) |
| 357 | kfree(txq->cmd[i]); | 362 | kfree(txq->cmd[i]); |
| 358 | kfree(txq->meta); | 363 | kfree(txq->meta); |
| @@ -390,6 +395,8 @@ static int iwl_trans_txq_init(struct iwl_trans *trans, struct iwl_tx_queue *txq, | |||
| 390 | if (ret) | 395 | if (ret) |
| 391 | return ret; | 396 | return ret; |
| 392 | 397 | ||
| 398 | spin_lock_init(&txq->lock); | ||
| 399 | |||
| 393 | /* | 400 | /* |
| 394 | * Tell nic where to find circular buffer of Tx Frame Descriptors for | 401 | * Tell nic where to find circular buffer of Tx Frame Descriptors for |
| 395 | * given Tx queue, and enable the DMA channel used for that queue. | 402 | * given Tx queue, and enable the DMA channel used for that queue. |
| @@ -409,8 +416,6 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) | |||
| 409 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; | 416 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; |
| 410 | struct iwl_queue *q = &txq->q; | 417 | struct iwl_queue *q = &txq->q; |
| 411 | enum dma_data_direction dma_dir; | 418 | enum dma_data_direction dma_dir; |
| 412 | unsigned long flags; | ||
| 413 | spinlock_t *lock; | ||
| 414 | 419 | ||
| 415 | if (!q->n_bd) | 420 | if (!q->n_bd) |
| 416 | return; | 421 | return; |
| @@ -418,22 +423,19 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) | |||
| 418 | /* In the command queue, all the TBs are mapped as BIDI | 423 | /* In the command queue, all the TBs are mapped as BIDI |
| 419 | * so unmap them as such. | 424 | * so unmap them as such. |
| 420 | */ | 425 | */ |
| 421 | if (txq_id == trans->shrd->cmd_queue) { | 426 | if (txq_id == trans_pcie->cmd_queue) |
| 422 | dma_dir = DMA_BIDIRECTIONAL; | 427 | dma_dir = DMA_BIDIRECTIONAL; |
| 423 | lock = &trans->hcmd_lock; | 428 | else |
| 424 | } else { | ||
| 425 | dma_dir = DMA_TO_DEVICE; | 429 | dma_dir = DMA_TO_DEVICE; |
| 426 | lock = &trans->shrd->sta_lock; | ||
| 427 | } | ||
| 428 | 430 | ||
| 429 | spin_lock_irqsave(lock, flags); | 431 | spin_lock_bh(&txq->lock); |
| 430 | while (q->write_ptr != q->read_ptr) { | 432 | while (q->write_ptr != q->read_ptr) { |
| 431 | /* The read_ptr needs to bound by q->n_window */ | 433 | /* The read_ptr needs to bound by q->n_window */ |
| 432 | iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr), | 434 | iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr), |
| 433 | dma_dir); | 435 | dma_dir); |
| 434 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); | 436 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); |
| 435 | } | 437 | } |
| 436 | spin_unlock_irqrestore(lock, flags); | 438 | spin_unlock_bh(&txq->lock); |
| 437 | } | 439 | } |
| 438 | 440 | ||
| 439 | /** | 441 | /** |
| @@ -457,7 +459,7 @@ static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id) | |||
| 457 | 459 | ||
| 458 | /* De-alloc array of command/tx buffers */ | 460 | /* De-alloc array of command/tx buffers */ |
| 459 | 461 | ||
| 460 | if (txq_id == trans->shrd->cmd_queue) | 462 | if (txq_id == trans_pcie->cmd_queue) |
| 461 | for (i = 0; i < txq->q.n_window; i++) | 463 | for (i = 0; i < txq->q.n_window; i++) |
| 462 | kfree(txq->cmd[i]); | 464 | kfree(txq->cmd[i]); |
| 463 | 465 | ||
| @@ -495,7 +497,7 @@ static void iwl_trans_pcie_tx_free(struct iwl_trans *trans) | |||
| 495 | /* Tx queues */ | 497 | /* Tx queues */ |
| 496 | if (trans_pcie->txq) { | 498 | if (trans_pcie->txq) { |
| 497 | for (txq_id = 0; | 499 | for (txq_id = 0; |
| 498 | txq_id < hw_params(trans).max_txq_num; txq_id++) | 500 | txq_id < cfg(trans)->base_params->num_of_queues; txq_id++) |
| 499 | iwl_tx_queue_free(trans, txq_id); | 501 | iwl_tx_queue_free(trans, txq_id); |
| 500 | } | 502 | } |
| 501 | 503 | ||
| @@ -520,7 +522,7 @@ static int iwl_trans_tx_alloc(struct iwl_trans *trans) | |||
| 520 | int txq_id, slots_num; | 522 | int txq_id, slots_num; |
| 521 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 523 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
| 522 | 524 | ||
| 523 | u16 scd_bc_tbls_size = hw_params(trans).max_txq_num * | 525 | u16 scd_bc_tbls_size = cfg(trans)->base_params->num_of_queues * |
| 524 | sizeof(struct iwlagn_scd_bc_tbl); | 526 | sizeof(struct iwlagn_scd_bc_tbl); |
| 525 | 527 | ||
| 526 | /*It is not allowed to alloc twice, so warn when this happens. | 528 | /*It is not allowed to alloc twice, so warn when this happens. |
| @@ -544,7 +546,7 @@ static int iwl_trans_tx_alloc(struct iwl_trans *trans) | |||
| 544 | goto error; | 546 | goto error; |
| 545 | } | 547 | } |
| 546 | 548 | ||
| 547 | trans_pcie->txq = kcalloc(hw_params(trans).max_txq_num, | 549 | trans_pcie->txq = kcalloc(cfg(trans)->base_params->num_of_queues, |
| 548 | sizeof(struct iwl_tx_queue), GFP_KERNEL); | 550 | sizeof(struct iwl_tx_queue), GFP_KERNEL); |
| 549 | if (!trans_pcie->txq) { | 551 | if (!trans_pcie->txq) { |
| 550 | IWL_ERR(trans, "Not enough memory for txq\n"); | 552 | IWL_ERR(trans, "Not enough memory for txq\n"); |
| @@ -553,8 +555,9 @@ static int iwl_trans_tx_alloc(struct iwl_trans *trans) | |||
| 553 | } | 555 | } |
| 554 | 556 | ||
| 555 | /* Alloc and init all Tx queues, including the command queue (#4/#9) */ | 557 | /* Alloc and init all Tx queues, including the command queue (#4/#9) */ |
| 556 | for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) { | 558 | for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues; |
| 557 | slots_num = (txq_id == trans->shrd->cmd_queue) ? | 559 | txq_id++) { |
| 560 | slots_num = (txq_id == trans_pcie->cmd_queue) ? | ||
| 558 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; | 561 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; |
| 559 | ret = iwl_trans_txq_alloc(trans, &trans_pcie->txq[txq_id], | 562 | ret = iwl_trans_txq_alloc(trans, &trans_pcie->txq[txq_id], |
| 560 | slots_num, txq_id); | 563 | slots_num, txq_id); |
| @@ -598,8 +601,9 @@ static int iwl_tx_init(struct iwl_trans *trans) | |||
| 598 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 601 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); |
| 599 | 602 | ||
| 600 | /* Alloc and init all Tx queues, including the command queue (#4/#9) */ | 603 | /* Alloc and init all Tx queues, including the command queue (#4/#9) */ |
| 601 | for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) { | 604 | for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues; |
| 602 | slots_num = (txq_id == trans->shrd->cmd_queue) ? | 605 | txq_id++) { |
| 606 | slots_num = (txq_id == trans_pcie->cmd_queue) ? | ||
| 603 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; | 607 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; |
| 604 | ret = iwl_trans_txq_init(trans, &trans_pcie->txq[txq_id], | 608 | ret = iwl_trans_txq_init(trans, &trans_pcie->txq[txq_id], |
| 605 | slots_num, txq_id); | 609 | slots_num, txq_id); |
| @@ -687,6 +691,7 @@ static void iwl_apm_config(struct iwl_trans *trans) | |||
| 687 | */ | 691 | */ |
| 688 | static int iwl_apm_init(struct iwl_trans *trans) | 692 | static int iwl_apm_init(struct iwl_trans *trans) |
| 689 | { | 693 | { |
| 694 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
| 690 | int ret = 0; | 695 | int ret = 0; |
| 691 | IWL_DEBUG_INFO(trans, "Init card's basic functions\n"); | 696 | IWL_DEBUG_INFO(trans, "Init card's basic functions\n"); |
| 692 | 697 | ||
| @@ -756,7 +761,7 @@ static int iwl_apm_init(struct iwl_trans *trans) | |||
| 756 | iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG, | 761 | iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG, |
| 757 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | 762 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); |
| 758 | 763 | ||
| 759 | set_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status); | 764 | set_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); |
| 760 | 765 | ||
| 761 | out: | 766 | out: |
| 762 | return ret; | 767 | return ret; |
| @@ -782,9 +787,10 @@ static int iwl_apm_stop_master(struct iwl_trans *trans) | |||
| 782 | 787 | ||
| 783 | static void iwl_apm_stop(struct iwl_trans *trans) | 788 | static void iwl_apm_stop(struct iwl_trans *trans) |
| 784 | { | 789 | { |
| 790 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
| 785 | IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n"); | 791 | IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n"); |
| 786 | 792 | ||
| 787 | clear_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status); | 793 | clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); |
| 788 | 794 | ||
| 789 | /* Stop device's DMA activity */ | 795 | /* Stop device's DMA activity */ |
| 790 | iwl_apm_stop_master(trans); | 796 | iwl_apm_stop_master(trans); |
| @@ -819,7 +825,7 @@ static int iwl_nic_init(struct iwl_trans *trans) | |||
| 819 | 825 | ||
| 820 | iwl_set_pwr_vmain(trans); | 826 | iwl_set_pwr_vmain(trans); |
| 821 | 827 | ||
| 822 | iwl_nic_config(priv(trans)); | 828 | iwl_op_mode_nic_config(trans->op_mode); |
| 823 | 829 | ||
| 824 | #ifndef CONFIG_IWLWIFI_IDI | 830 | #ifndef CONFIG_IWLWIFI_IDI |
| 825 | /* Allocate the RX queue, or reset if it is already allocated */ | 831 | /* Allocate the RX queue, or reset if it is already allocated */ |
| @@ -830,14 +836,12 @@ static int iwl_nic_init(struct iwl_trans *trans) | |||
| 830 | if (iwl_tx_init(trans)) | 836 | if (iwl_tx_init(trans)) |
| 831 | return -ENOMEM; | 837 | return -ENOMEM; |
| 832 | 838 | ||
| 833 | if (hw_params(trans).shadow_reg_enable) { | 839 | if (cfg(trans)->base_params->shadow_reg_enable) { |
| 834 | /* enable shadow regs in HW */ | 840 | /* enable shadow regs in HW */ |
| 835 | iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, | 841 | iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, |
| 836 | 0x800FFFFF); | 842 | 0x800FFFFF); |
| 837 | } | 843 | } |
| 838 | 844 | ||
| 839 | set_bit(STATUS_INIT, &trans->shrd->status); | ||
| 840 | |||
| 841 | return 0; | 845 | return 0; |
| 842 | } | 846 | } |
| 843 | 847 | ||
| @@ -948,13 +952,14 @@ static const u8 iwlagn_pan_ac_to_queue[] = { | |||
| 948 | * ucode | 952 | * ucode |
| 949 | */ | 953 | */ |
| 950 | static int iwl_load_section(struct iwl_trans *trans, const char *name, | 954 | static int iwl_load_section(struct iwl_trans *trans, const char *name, |
| 951 | struct fw_desc *image, u32 dst_addr) | 955 | const struct fw_desc *image, u32 dst_addr) |
| 952 | { | 956 | { |
| 957 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
| 953 | dma_addr_t phy_addr = image->p_addr; | 958 | dma_addr_t phy_addr = image->p_addr; |
| 954 | u32 byte_cnt = image->len; | 959 | u32 byte_cnt = image->len; |
| 955 | int ret; | 960 | int ret; |
| 956 | 961 | ||
| 957 | trans->ucode_write_complete = 0; | 962 | trans_pcie->ucode_write_complete = false; |
| 958 | 963 | ||
| 959 | iwl_write_direct32(trans, | 964 | iwl_write_direct32(trans, |
| 960 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), | 965 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), |
| @@ -985,8 +990,8 @@ static int iwl_load_section(struct iwl_trans *trans, const char *name, | |||
| 985 | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); | 990 | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); |
| 986 | 991 | ||
| 987 | IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name); | 992 | IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name); |
| 988 | ret = wait_event_timeout(trans->shrd->wait_command_queue, | 993 | ret = wait_event_timeout(trans_pcie->ucode_write_waitq, |
| 989 | trans->ucode_write_complete, 5 * HZ); | 994 | trans_pcie->ucode_write_complete, 5 * HZ); |
| 990 | if (!ret) { | 995 | if (!ret) { |
| 991 | IWL_ERR(trans, "Could not load the %s uCode section\n", | 996 | IWL_ERR(trans, "Could not load the %s uCode section\n", |
| 992 | name); | 997 | name); |
| @@ -996,7 +1001,8 @@ static int iwl_load_section(struct iwl_trans *trans, const char *name, | |||
| 996 | return 0; | 1001 | return 0; |
| 997 | } | 1002 | } |
| 998 | 1003 | ||
| 999 | static int iwl_load_given_ucode(struct iwl_trans *trans, struct fw_img *image) | 1004 | static int iwl_load_given_ucode(struct iwl_trans *trans, |
| 1005 | const struct fw_img *image) | ||
| 1000 | { | 1006 | { |
| 1001 | int ret = 0; | 1007 | int ret = 0; |
| 1002 | 1008 | ||
| @@ -1016,13 +1022,14 @@ static int iwl_load_given_ucode(struct iwl_trans *trans, struct fw_img *image) | |||
| 1016 | return 0; | 1022 | return 0; |
| 1017 | } | 1023 | } |
| 1018 | 1024 | ||
| 1019 | static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw) | 1025 | static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, |
| 1026 | const struct fw_img *fw) | ||
| 1020 | { | 1027 | { |
| 1021 | int ret; | 1028 | int ret; |
| 1022 | struct iwl_trans_pcie *trans_pcie = | 1029 | struct iwl_trans_pcie *trans_pcie = |
| 1023 | IWL_TRANS_GET_PCIE_TRANS(trans); | 1030 | IWL_TRANS_GET_PCIE_TRANS(trans); |
| 1031 | bool hw_rfkill; | ||
| 1024 | 1032 | ||
| 1025 | trans->shrd->ucode_owner = IWL_OWNERSHIP_DRIVER; | ||
| 1026 | trans_pcie->ac_to_queue[IWL_RXON_CTX_BSS] = iwlagn_bss_ac_to_queue; | 1033 | trans_pcie->ac_to_queue[IWL_RXON_CTX_BSS] = iwlagn_bss_ac_to_queue; |
| 1027 | trans_pcie->ac_to_queue[IWL_RXON_CTX_PAN] = iwlagn_pan_ac_to_queue; | 1034 | trans_pcie->ac_to_queue[IWL_RXON_CTX_PAN] = iwlagn_pan_ac_to_queue; |
| 1028 | 1035 | ||
| @@ -1032,22 +1039,19 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw) | |||
| 1032 | trans_pcie->mcast_queue[IWL_RXON_CTX_BSS] = 0; | 1039 | trans_pcie->mcast_queue[IWL_RXON_CTX_BSS] = 0; |
| 1033 | trans_pcie->mcast_queue[IWL_RXON_CTX_PAN] = IWL_IPAN_MCAST_QUEUE; | 1040 | trans_pcie->mcast_queue[IWL_RXON_CTX_PAN] = IWL_IPAN_MCAST_QUEUE; |
| 1034 | 1041 | ||
| 1035 | if ((hw_params(trans).sku & EEPROM_SKU_CAP_AMT_ENABLE) && | 1042 | /* This may fail if AMT took ownership of the device */ |
| 1036 | iwl_prepare_card_hw(trans)) { | 1043 | if (iwl_prepare_card_hw(trans)) { |
| 1037 | IWL_WARN(trans, "Exit HW not ready\n"); | 1044 | IWL_WARN(trans, "Exit HW not ready\n"); |
| 1038 | return -EIO; | 1045 | return -EIO; |
| 1039 | } | 1046 | } |
| 1040 | 1047 | ||
| 1041 | /* If platform's RF_KILL switch is NOT set to KILL */ | 1048 | /* If platform's RF_KILL switch is NOT set to KILL */ |
| 1042 | if (iwl_read32(trans, CSR_GP_CNTRL) & | 1049 | hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) & |
| 1043 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | 1050 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); |
| 1044 | clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); | 1051 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); |
| 1045 | else | ||
| 1046 | set_bit(STATUS_RF_KILL_HW, &trans->shrd->status); | ||
| 1047 | 1052 | ||
| 1048 | if (iwl_is_rfkill(trans->shrd)) { | 1053 | if (hw_rfkill) { |
| 1049 | iwl_op_mode_hw_rf_kill(trans->op_mode, true); | 1054 | iwl_enable_rfkill_int(trans); |
| 1050 | iwl_enable_interrupts(trans); | ||
| 1051 | return -ERFKILL; | 1055 | return -ERFKILL; |
| 1052 | } | 1056 | } |
| 1053 | 1057 | ||
| @@ -1073,9 +1077,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw) | |||
| 1073 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | 1077 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); |
| 1074 | 1078 | ||
| 1075 | /* Load the given image to the HW */ | 1079 | /* Load the given image to the HW */ |
| 1076 | iwl_load_given_ucode(trans, fw); | 1080 | return iwl_load_given_ucode(trans, fw); |
| 1077 | |||
| 1078 | return 0; | ||
| 1079 | } | 1081 | } |
| 1080 | 1082 | ||
| 1081 | /* | 1083 | /* |
| @@ -1116,7 +1118,8 @@ static void iwl_tx_start(struct iwl_trans *trans) | |||
| 1116 | a += 4) | 1118 | a += 4) |
| 1117 | iwl_write_targ_mem(trans, a, 0); | 1119 | iwl_write_targ_mem(trans, a, 0); |
| 1118 | for (; a < trans_pcie->scd_base_addr + | 1120 | for (; a < trans_pcie->scd_base_addr + |
| 1119 | SCD_TRANS_TBL_OFFSET_QUEUE(hw_params(trans).max_txq_num); | 1121 | SCD_TRANS_TBL_OFFSET_QUEUE( |
| 1122 | cfg(trans)->base_params->num_of_queues); | ||
| 1120 | a += 4) | 1123 | a += 4) |
| 1121 | iwl_write_targ_mem(trans, a, 0); | 1124 | iwl_write_targ_mem(trans, a, 0); |
| 1122 | 1125 | ||
| @@ -1135,11 +1138,11 @@ static void iwl_tx_start(struct iwl_trans *trans) | |||
| 1135 | reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); | 1138 | reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); |
| 1136 | 1139 | ||
| 1137 | iwl_write_prph(trans, SCD_QUEUECHAIN_SEL, | 1140 | iwl_write_prph(trans, SCD_QUEUECHAIN_SEL, |
| 1138 | SCD_QUEUECHAIN_SEL_ALL(trans)); | 1141 | SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie)); |
| 1139 | iwl_write_prph(trans, SCD_AGGR_SEL, 0); | 1142 | iwl_write_prph(trans, SCD_AGGR_SEL, 0); |
| 1140 | 1143 | ||
| 1141 | /* initiate the queues */ | 1144 | /* initiate the queues */ |
| 1142 | for (i = 0; i < hw_params(trans).max_txq_num; i++) { | 1145 | for (i = 0; i < cfg(trans)->base_params->num_of_queues; i++) { |
| 1143 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(i), 0); | 1146 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(i), 0); |
| 1144 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, 0 | (i << 8)); | 1147 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, 0 | (i << 8)); |
| 1145 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + | 1148 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + |
| @@ -1156,7 +1159,7 @@ static void iwl_tx_start(struct iwl_trans *trans) | |||
| 1156 | } | 1159 | } |
| 1157 | 1160 | ||
| 1158 | iwl_write_prph(trans, SCD_INTERRUPT_MASK, | 1161 | iwl_write_prph(trans, SCD_INTERRUPT_MASK, |
| 1159 | IWL_MASK(0, hw_params(trans).max_txq_num)); | 1162 | IWL_MASK(0, cfg(trans)->base_params->num_of_queues)); |
| 1160 | 1163 | ||
| 1161 | /* Activate all Tx DMA/FIFO channels */ | 1164 | /* Activate all Tx DMA/FIFO channels */ |
| 1162 | iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7)); | 1165 | iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7)); |
| @@ -1167,7 +1170,7 @@ static void iwl_tx_start(struct iwl_trans *trans) | |||
| 1167 | else | 1170 | else |
| 1168 | queue_to_fifo = iwlagn_default_queue_to_tx_fifo; | 1171 | queue_to_fifo = iwlagn_default_queue_to_tx_fifo; |
| 1169 | 1172 | ||
| 1170 | iwl_trans_set_wr_ptrs(trans, trans->shrd->cmd_queue, 0); | 1173 | iwl_trans_set_wr_ptrs(trans, trans_pcie->cmd_queue, 0); |
| 1171 | 1174 | ||
| 1172 | /* make sure all queue are not stopped */ | 1175 | /* make sure all queue are not stopped */ |
| 1173 | memset(&trans_pcie->queue_stopped[0], 0, | 1176 | memset(&trans_pcie->queue_stopped[0], 0, |
| @@ -1216,7 +1219,7 @@ static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans) | |||
| 1216 | */ | 1219 | */ |
| 1217 | static int iwl_trans_tx_stop(struct iwl_trans *trans) | 1220 | static int iwl_trans_tx_stop(struct iwl_trans *trans) |
| 1218 | { | 1221 | { |
| 1219 | int ch, txq_id; | 1222 | int ch, txq_id, ret; |
| 1220 | unsigned long flags; | 1223 | unsigned long flags; |
| 1221 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1224 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
| 1222 | 1225 | ||
| @@ -1229,9 +1232,10 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans) | |||
| 1229 | for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { | 1232 | for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { |
| 1230 | iwl_write_direct32(trans, | 1233 | iwl_write_direct32(trans, |
| 1231 | FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); | 1234 | FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); |
| 1232 | if (iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG, | 1235 | ret = iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG, |
| 1233 | FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), | 1236 | FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), |
| 1234 | 1000)) | 1237 | 1000); |
| 1238 | if (ret < 0) | ||
| 1235 | IWL_ERR(trans, "Failing on timeout while stopping" | 1239 | IWL_ERR(trans, "Failing on timeout while stopping" |
| 1236 | " DMA channel %d [0x%08x]", ch, | 1240 | " DMA channel %d [0x%08x]", ch, |
| 1237 | iwl_read_direct32(trans, | 1241 | iwl_read_direct32(trans, |
| @@ -1245,7 +1249,8 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans) | |||
| 1245 | } | 1249 | } |
| 1246 | 1250 | ||
| 1247 | /* Unmap DMA from host system and free skb's */ | 1251 | /* Unmap DMA from host system and free skb's */ |
| 1248 | for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) | 1252 | for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues; |
| 1253 | txq_id++) | ||
| 1249 | iwl_tx_queue_unmap(trans, txq_id); | 1254 | iwl_tx_queue_unmap(trans, txq_id); |
| 1250 | 1255 | ||
| 1251 | return 0; | 1256 | return 0; |
| @@ -1271,7 +1276,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
| 1271 | * restart. So don't process again if the device is | 1276 | * restart. So don't process again if the device is |
| 1272 | * already dead. | 1277 | * already dead. |
| 1273 | */ | 1278 | */ |
| 1274 | if (test_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status)) { | 1279 | if (test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status)) { |
| 1275 | iwl_trans_tx_stop(trans); | 1280 | iwl_trans_tx_stop(trans); |
| 1276 | #ifndef CONFIG_IWLWIFI_IDI | 1281 | #ifndef CONFIG_IWLWIFI_IDI |
| 1277 | iwl_trans_rx_stop(trans); | 1282 | iwl_trans_rx_stop(trans); |
| @@ -1297,7 +1302,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
| 1297 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 1302 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); |
| 1298 | 1303 | ||
| 1299 | /* wait to make sure we flush pending tasklet*/ | 1304 | /* wait to make sure we flush pending tasklet*/ |
| 1300 | synchronize_irq(trans->irq); | 1305 | synchronize_irq(trans_pcie->irq); |
| 1301 | tasklet_kill(&trans_pcie->irq_tasklet); | 1306 | tasklet_kill(&trans_pcie->irq_tasklet); |
| 1302 | 1307 | ||
| 1303 | cancel_work_sync(&trans_pcie->rx_replenish); | 1308 | cancel_work_sync(&trans_pcie->rx_replenish); |
| @@ -1306,6 +1311,17 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
| 1306 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | 1311 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); |
| 1307 | } | 1312 | } |
| 1308 | 1313 | ||
| 1314 | static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans) | ||
| 1315 | { | ||
| 1316 | /* let the ucode operate on its own */ | ||
| 1317 | iwl_write32(trans, CSR_UCODE_DRV_GP1_SET, | ||
| 1318 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | ||
| 1319 | |||
| 1320 | iwl_disable_interrupts(trans); | ||
| 1321 | iwl_clear_bit(trans, CSR_GP_CNTRL, | ||
| 1322 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
| 1323 | } | ||
| 1324 | |||
| 1309 | static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | 1325 | static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, |
| 1310 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, | 1326 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, |
| 1311 | u8 sta_id, u8 tid) | 1327 | u8 sta_id, u8 tid) |
| @@ -1358,6 +1374,8 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
| 1358 | txq = &trans_pcie->txq[txq_id]; | 1374 | txq = &trans_pcie->txq[txq_id]; |
| 1359 | q = &txq->q; | 1375 | q = &txq->q; |
| 1360 | 1376 | ||
| 1377 | spin_lock(&txq->lock); | ||
| 1378 | |||
| 1361 | /* In AGG mode, the index in the ring must correspond to the WiFi | 1379 | /* In AGG mode, the index in the ring must correspond to the WiFi |
| 1362 | * sequence number. This is a HW requirements to help the SCD to parse | 1380 | * sequence number. This is a HW requirements to help the SCD to parse |
| 1363 | * the BA. | 1381 | * the BA. |
| @@ -1404,7 +1422,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
| 1404 | &dev_cmd->hdr, firstlen, | 1422 | &dev_cmd->hdr, firstlen, |
| 1405 | DMA_BIDIRECTIONAL); | 1423 | DMA_BIDIRECTIONAL); |
| 1406 | if (unlikely(dma_mapping_error(trans->dev, txcmd_phys))) | 1424 | if (unlikely(dma_mapping_error(trans->dev, txcmd_phys))) |
| 1407 | return -1; | 1425 | goto out_err; |
| 1408 | dma_unmap_addr_set(out_meta, mapping, txcmd_phys); | 1426 | dma_unmap_addr_set(out_meta, mapping, txcmd_phys); |
| 1409 | dma_unmap_len_set(out_meta, len, firstlen); | 1427 | dma_unmap_len_set(out_meta, len, firstlen); |
| 1410 | 1428 | ||
| @@ -1426,7 +1444,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
| 1426 | dma_unmap_addr(out_meta, mapping), | 1444 | dma_unmap_addr(out_meta, mapping), |
| 1427 | dma_unmap_len(out_meta, len), | 1445 | dma_unmap_len(out_meta, len), |
| 1428 | DMA_BIDIRECTIONAL); | 1446 | DMA_BIDIRECTIONAL); |
| 1429 | return -1; | 1447 | goto out_err; |
| 1430 | } | 1448 | } |
| 1431 | } | 1449 | } |
| 1432 | 1450 | ||
| @@ -1457,7 +1475,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
| 1457 | dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, | 1475 | dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, |
| 1458 | DMA_BIDIRECTIONAL); | 1476 | DMA_BIDIRECTIONAL); |
| 1459 | 1477 | ||
| 1460 | trace_iwlwifi_dev_tx(priv(trans), | 1478 | trace_iwlwifi_dev_tx(trans->dev, |
| 1461 | &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr], | 1479 | &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr], |
| 1462 | sizeof(struct iwl_tfd), | 1480 | sizeof(struct iwl_tfd), |
| 1463 | &dev_cmd->hdr, firstlen, | 1481 | &dev_cmd->hdr, firstlen, |
| @@ -1478,10 +1496,14 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
| 1478 | txq->need_update = 1; | 1496 | txq->need_update = 1; |
| 1479 | iwl_txq_update_write_ptr(trans, txq); | 1497 | iwl_txq_update_write_ptr(trans, txq); |
| 1480 | } else { | 1498 | } else { |
| 1481 | iwl_stop_queue(trans, txq, "Queue is full"); | 1499 | iwl_stop_queue(trans, txq); |
| 1482 | } | 1500 | } |
| 1483 | } | 1501 | } |
| 1502 | spin_unlock(&txq->lock); | ||
| 1484 | return 0; | 1503 | return 0; |
| 1504 | out_err: | ||
| 1505 | spin_unlock(&txq->lock); | ||
| 1506 | return -1; | ||
| 1485 | } | 1507 | } |
| 1486 | 1508 | ||
| 1487 | static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | 1509 | static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) |
| @@ -1489,6 +1511,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | |||
| 1489 | struct iwl_trans_pcie *trans_pcie = | 1511 | struct iwl_trans_pcie *trans_pcie = |
| 1490 | IWL_TRANS_GET_PCIE_TRANS(trans); | 1512 | IWL_TRANS_GET_PCIE_TRANS(trans); |
| 1491 | int err; | 1513 | int err; |
| 1514 | bool hw_rfkill; | ||
| 1492 | 1515 | ||
| 1493 | trans_pcie->inta_mask = CSR_INI_SET_MASK; | 1516 | trans_pcie->inta_mask = CSR_INI_SET_MASK; |
| 1494 | 1517 | ||
| @@ -1498,11 +1521,11 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | |||
| 1498 | 1521 | ||
| 1499 | iwl_alloc_isr_ict(trans); | 1522 | iwl_alloc_isr_ict(trans); |
| 1500 | 1523 | ||
| 1501 | err = request_irq(trans->irq, iwl_isr_ict, IRQF_SHARED, | 1524 | err = request_irq(trans_pcie->irq, iwl_isr_ict, IRQF_SHARED, |
| 1502 | DRV_NAME, trans); | 1525 | DRV_NAME, trans); |
| 1503 | if (err) { | 1526 | if (err) { |
| 1504 | IWL_ERR(trans, "Error allocating IRQ %d\n", | 1527 | IWL_ERR(trans, "Error allocating IRQ %d\n", |
| 1505 | trans->irq); | 1528 | trans_pcie->irq); |
| 1506 | goto error; | 1529 | goto error; |
| 1507 | } | 1530 | } |
| 1508 | 1531 | ||
| @@ -1518,21 +1541,14 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | |||
| 1518 | 1541 | ||
| 1519 | iwl_apm_init(trans); | 1542 | iwl_apm_init(trans); |
| 1520 | 1543 | ||
| 1521 | /* If platform's RF_KILL switch is NOT set to KILL */ | 1544 | hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) & |
| 1522 | if (iwl_read32(trans, | 1545 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); |
| 1523 | CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | 1546 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); |
| 1524 | clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); | ||
| 1525 | else | ||
| 1526 | set_bit(STATUS_RF_KILL_HW, &trans->shrd->status); | ||
| 1527 | |||
| 1528 | iwl_op_mode_hw_rf_kill(trans->op_mode, | ||
| 1529 | test_bit(STATUS_RF_KILL_HW, | ||
| 1530 | &trans->shrd->status)); | ||
| 1531 | 1547 | ||
| 1532 | return err; | 1548 | return err; |
| 1533 | 1549 | ||
| 1534 | err_free_irq: | 1550 | err_free_irq: |
| 1535 | free_irq(trans->irq, trans); | 1551 | free_irq(trans_pcie->irq, trans); |
| 1536 | error: | 1552 | error: |
| 1537 | iwl_free_isr_ict(trans); | 1553 | iwl_free_isr_ict(trans); |
| 1538 | tasklet_kill(&trans_pcie->irq_tasklet); | 1554 | tasklet_kill(&trans_pcie->irq_tasklet); |
| @@ -1546,13 +1562,11 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans) | |||
| 1546 | iwl_write32(trans, CSR_INT, 0xFFFFFFFF); | 1562 | iwl_write32(trans, CSR_INT, 0xFFFFFFFF); |
| 1547 | 1563 | ||
| 1548 | /* Even if we stop the HW, we still want the RF kill interrupt */ | 1564 | /* Even if we stop the HW, we still want the RF kill interrupt */ |
| 1549 | IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); | 1565 | iwl_enable_rfkill_int(trans); |
| 1550 | iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); | ||
| 1551 | } | 1566 | } |
| 1552 | 1567 | ||
| 1553 | static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, | 1568 | static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, |
| 1554 | int txq_id, int ssn, u32 status, | 1569 | int txq_id, int ssn, struct sk_buff_head *skbs) |
| 1555 | struct sk_buff_head *skbs) | ||
| 1556 | { | 1570 | { |
| 1557 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1571 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
| 1558 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; | 1572 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; |
| @@ -1560,6 +1574,8 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, | |||
| 1560 | int tfd_num = ssn & (txq->q.n_bd - 1); | 1574 | int tfd_num = ssn & (txq->q.n_bd - 1); |
| 1561 | int freed = 0; | 1575 | int freed = 0; |
| 1562 | 1576 | ||
| 1577 | spin_lock(&txq->lock); | ||
| 1578 | |||
| 1563 | txq->time_stamp = jiffies; | 1579 | txq->time_stamp = jiffies; |
| 1564 | 1580 | ||
| 1565 | if (unlikely(txq_id >= IWLAGN_FIRST_AMPDU_QUEUE && | 1581 | if (unlikely(txq_id >= IWLAGN_FIRST_AMPDU_QUEUE && |
| @@ -1574,6 +1590,7 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, | |||
| 1574 | IWL_DEBUG_TX_QUEUES(trans, "Bad queue mapping txq_id %d, " | 1590 | IWL_DEBUG_TX_QUEUES(trans, "Bad queue mapping txq_id %d, " |
| 1575 | "agg_txq[sta_id[tid] %d", txq_id, | 1591 | "agg_txq[sta_id[tid] %d", txq_id, |
| 1576 | trans_pcie->agg_txq[sta_id][tid]); | 1592 | trans_pcie->agg_txq[sta_id][tid]); |
| 1593 | spin_unlock(&txq->lock); | ||
| 1577 | return 1; | 1594 | return 1; |
| 1578 | } | 1595 | } |
| 1579 | 1596 | ||
| @@ -1582,28 +1599,35 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, | |||
| 1582 | txq_id, iwl_get_queue_ac(txq), txq->q.read_ptr, | 1599 | txq_id, iwl_get_queue_ac(txq), txq->q.read_ptr, |
| 1583 | tfd_num, ssn); | 1600 | tfd_num, ssn); |
| 1584 | freed = iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs); | 1601 | freed = iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs); |
| 1585 | if (iwl_queue_space(&txq->q) > txq->q.low_mark && | 1602 | if (iwl_queue_space(&txq->q) > txq->q.low_mark) |
| 1586 | (!txq->sched_retry || | 1603 | iwl_wake_queue(trans, txq); |
| 1587 | status != TX_STATUS_FAIL_PASSIVE_NO_RX)) | ||
| 1588 | iwl_wake_queue(trans, txq, "Packets reclaimed"); | ||
| 1589 | } | 1604 | } |
| 1605 | |||
| 1606 | spin_unlock(&txq->lock); | ||
| 1590 | return 0; | 1607 | return 0; |
| 1591 | } | 1608 | } |
| 1592 | 1609 | ||
| 1593 | static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val) | 1610 | static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val) |
| 1594 | { | 1611 | { |
| 1595 | iowrite8(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); | 1612 | writeb(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); |
| 1596 | } | 1613 | } |
| 1597 | 1614 | ||
| 1598 | static void iwl_trans_pcie_write32(struct iwl_trans *trans, u32 ofs, u32 val) | 1615 | static void iwl_trans_pcie_write32(struct iwl_trans *trans, u32 ofs, u32 val) |
| 1599 | { | 1616 | { |
| 1600 | iowrite32(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); | 1617 | writel(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); |
| 1601 | } | 1618 | } |
| 1602 | 1619 | ||
| 1603 | static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs) | 1620 | static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs) |
| 1604 | { | 1621 | { |
| 1605 | u32 val = ioread32(IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); | 1622 | return readl(IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); |
| 1606 | return val; | 1623 | } |
| 1624 | |||
| 1625 | static void iwl_trans_pcie_configure(struct iwl_trans *trans, | ||
| 1626 | const struct iwl_trans_config *trans_cfg) | ||
| 1627 | { | ||
| 1628 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
| 1629 | |||
| 1630 | trans_pcie->cmd_queue = trans_cfg->cmd_queue; | ||
| 1607 | } | 1631 | } |
| 1608 | 1632 | ||
| 1609 | static void iwl_trans_pcie_free(struct iwl_trans *trans) | 1633 | static void iwl_trans_pcie_free(struct iwl_trans *trans) |
| @@ -1611,18 +1635,17 @@ static void iwl_trans_pcie_free(struct iwl_trans *trans) | |||
| 1611 | struct iwl_trans_pcie *trans_pcie = | 1635 | struct iwl_trans_pcie *trans_pcie = |
| 1612 | IWL_TRANS_GET_PCIE_TRANS(trans); | 1636 | IWL_TRANS_GET_PCIE_TRANS(trans); |
| 1613 | 1637 | ||
| 1614 | iwl_calib_free_results(trans); | ||
| 1615 | iwl_trans_pcie_tx_free(trans); | 1638 | iwl_trans_pcie_tx_free(trans); |
| 1616 | #ifndef CONFIG_IWLWIFI_IDI | 1639 | #ifndef CONFIG_IWLWIFI_IDI |
| 1617 | iwl_trans_pcie_rx_free(trans); | 1640 | iwl_trans_pcie_rx_free(trans); |
| 1618 | #endif | 1641 | #endif |
| 1619 | if (trans_pcie->irq_requested == true) { | 1642 | if (trans_pcie->irq_requested == true) { |
| 1620 | free_irq(trans->irq, trans); | 1643 | free_irq(trans_pcie->irq, trans); |
| 1621 | iwl_free_isr_ict(trans); | 1644 | iwl_free_isr_ict(trans); |
| 1622 | } | 1645 | } |
| 1623 | 1646 | ||
| 1624 | pci_disable_msi(trans_pcie->pci_dev); | 1647 | pci_disable_msi(trans_pcie->pci_dev); |
| 1625 | pci_iounmap(trans_pcie->pci_dev, trans_pcie->hw_base); | 1648 | iounmap(trans_pcie->hw_base); |
| 1626 | pci_release_regions(trans_pcie->pci_dev); | 1649 | pci_release_regions(trans_pcie->pci_dev); |
| 1627 | pci_disable_device(trans_pcie->pci_dev); | 1650 | pci_disable_device(trans_pcie->pci_dev); |
| 1628 | 1651 | ||
| @@ -1633,42 +1656,20 @@ static void iwl_trans_pcie_free(struct iwl_trans *trans) | |||
| 1633 | #ifdef CONFIG_PM_SLEEP | 1656 | #ifdef CONFIG_PM_SLEEP |
| 1634 | static int iwl_trans_pcie_suspend(struct iwl_trans *trans) | 1657 | static int iwl_trans_pcie_suspend(struct iwl_trans *trans) |
| 1635 | { | 1658 | { |
| 1636 | /* | ||
| 1637 | * This function is called when system goes into suspend state | ||
| 1638 | * mac80211 will call iwlagn_mac_stop() from the mac80211 suspend | ||
| 1639 | * function first but since iwlagn_mac_stop() has no knowledge of | ||
| 1640 | * who the caller is, | ||
| 1641 | * it will not call apm_ops.stop() to stop the DMA operation. | ||
| 1642 | * Calling apm_ops.stop here to make sure we stop the DMA. | ||
| 1643 | * | ||
| 1644 | * But of course ... if we have configured WoWLAN then we did other | ||
| 1645 | * things already :-) | ||
| 1646 | */ | ||
| 1647 | if (!trans->shrd->wowlan) { | ||
| 1648 | iwl_apm_stop(trans); | ||
| 1649 | } else { | ||
| 1650 | iwl_disable_interrupts(trans); | ||
| 1651 | iwl_clear_bit(trans, CSR_GP_CNTRL, | ||
| 1652 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
| 1653 | } | ||
| 1654 | |||
| 1655 | return 0; | 1659 | return 0; |
| 1656 | } | 1660 | } |
| 1657 | 1661 | ||
| 1658 | static int iwl_trans_pcie_resume(struct iwl_trans *trans) | 1662 | static int iwl_trans_pcie_resume(struct iwl_trans *trans) |
| 1659 | { | 1663 | { |
| 1660 | bool hw_rfkill = false; | 1664 | bool hw_rfkill; |
| 1661 | |||
| 1662 | iwl_enable_interrupts(trans); | ||
| 1663 | 1665 | ||
| 1664 | if (!(iwl_read32(trans, CSR_GP_CNTRL) & | 1666 | hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) & |
| 1665 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) | 1667 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); |
| 1666 | hw_rfkill = true; | ||
| 1667 | 1668 | ||
| 1668 | if (hw_rfkill) | 1669 | if (hw_rfkill) |
| 1669 | set_bit(STATUS_RF_KILL_HW, &trans->shrd->status); | 1670 | iwl_enable_rfkill_int(trans); |
| 1670 | else | 1671 | else |
| 1671 | clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); | 1672 | iwl_enable_interrupts(trans); |
| 1672 | 1673 | ||
| 1673 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); | 1674 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); |
| 1674 | 1675 | ||
| @@ -1676,32 +1677,6 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans) | |||
| 1676 | } | 1677 | } |
| 1677 | #endif /* CONFIG_PM_SLEEP */ | 1678 | #endif /* CONFIG_PM_SLEEP */ |
| 1678 | 1679 | ||
| 1679 | static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans, | ||
| 1680 | enum iwl_rxon_context_id ctx, | ||
| 1681 | const char *msg) | ||
| 1682 | { | ||
| 1683 | u8 ac, txq_id; | ||
| 1684 | struct iwl_trans_pcie *trans_pcie = | ||
| 1685 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
| 1686 | |||
| 1687 | for (ac = 0; ac < AC_NUM; ac++) { | ||
| 1688 | txq_id = trans_pcie->ac_to_queue[ctx][ac]; | ||
| 1689 | IWL_DEBUG_TX_QUEUES(trans, "Queue Status: Q[%d] %s\n", | ||
| 1690 | ac, | ||
| 1691 | (atomic_read(&trans_pcie->queue_stop_count[ac]) > 0) | ||
| 1692 | ? "stopped" : "awake"); | ||
| 1693 | iwl_wake_queue(trans, &trans_pcie->txq[txq_id], msg); | ||
| 1694 | } | ||
| 1695 | } | ||
| 1696 | |||
| 1697 | static void iwl_trans_pcie_stop_queue(struct iwl_trans *trans, int txq_id, | ||
| 1698 | const char *msg) | ||
| 1699 | { | ||
| 1700 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
| 1701 | |||
| 1702 | iwl_stop_queue(trans, &trans_pcie->txq[txq_id], msg); | ||
| 1703 | } | ||
| 1704 | |||
| 1705 | #define IWL_FLUSH_WAIT_MS 2000 | 1680 | #define IWL_FLUSH_WAIT_MS 2000 |
| 1706 | 1681 | ||
| 1707 | static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans) | 1682 | static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans) |
| @@ -1714,8 +1689,8 @@ static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans) | |||
| 1714 | int ret = 0; | 1689 | int ret = 0; |
| 1715 | 1690 | ||
| 1716 | /* waiting for all the tx frames complete might take a while */ | 1691 | /* waiting for all the tx frames complete might take a while */ |
| 1717 | for (cnt = 0; cnt < hw_params(trans).max_txq_num; cnt++) { | 1692 | for (cnt = 0; cnt < cfg(trans)->base_params->num_of_queues; cnt++) { |
| 1718 | if (cnt == trans->shrd->cmd_queue) | 1693 | if (cnt == trans_pcie->cmd_queue) |
| 1719 | continue; | 1694 | continue; |
| 1720 | txq = &trans_pcie->txq[cnt]; | 1695 | txq = &trans_pcie->txq[cnt]; |
| 1721 | q = &txq->q; | 1696 | q = &txq->q; |
| @@ -1960,7 +1935,9 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, | |||
| 1960 | int pos = 0; | 1935 | int pos = 0; |
| 1961 | int cnt; | 1936 | int cnt; |
| 1962 | int ret; | 1937 | int ret; |
| 1963 | const size_t bufsz = sizeof(char) * 64 * hw_params(trans).max_txq_num; | 1938 | size_t bufsz; |
| 1939 | |||
| 1940 | bufsz = sizeof(char) * 64 * cfg(trans)->base_params->num_of_queues; | ||
| 1964 | 1941 | ||
| 1965 | if (!trans_pcie->txq) { | 1942 | if (!trans_pcie->txq) { |
| 1966 | IWL_ERR(trans, "txq not ready\n"); | 1943 | IWL_ERR(trans, "txq not ready\n"); |
| @@ -1970,7 +1947,7 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, | |||
| 1970 | if (!buf) | 1947 | if (!buf) |
| 1971 | return -ENOMEM; | 1948 | return -ENOMEM; |
| 1972 | 1949 | ||
| 1973 | for (cnt = 0; cnt < hw_params(trans).max_txq_num; cnt++) { | 1950 | for (cnt = 0; cnt < cfg(trans)->base_params->num_of_queues; cnt++) { |
| 1974 | txq = &trans_pcie->txq[cnt]; | 1951 | txq = &trans_pcie->txq[cnt]; |
| 1975 | q = &txq->q; | 1952 | q = &txq->q; |
| 1976 | pos += scnprintf(buf + pos, bufsz - pos, | 1953 | pos += scnprintf(buf + pos, bufsz - pos, |
| @@ -2219,7 +2196,7 @@ const struct iwl_trans_ops trans_ops_pcie = { | |||
| 2219 | .start_fw = iwl_trans_pcie_start_fw, | 2196 | .start_fw = iwl_trans_pcie_start_fw, |
| 2220 | .stop_device = iwl_trans_pcie_stop_device, | 2197 | .stop_device = iwl_trans_pcie_stop_device, |
| 2221 | 2198 | ||
| 2222 | .wake_any_queue = iwl_trans_pcie_wake_any_queue, | 2199 | .wowlan_suspend = iwl_trans_pcie_wowlan_suspend, |
| 2223 | 2200 | ||
| 2224 | .send_cmd = iwl_trans_pcie_send_cmd, | 2201 | .send_cmd = iwl_trans_pcie_send_cmd, |
| 2225 | 2202 | ||
| @@ -2231,7 +2208,6 @@ const struct iwl_trans_ops trans_ops_pcie = { | |||
| 2231 | .tx_agg_setup = iwl_trans_pcie_tx_agg_setup, | 2208 | .tx_agg_setup = iwl_trans_pcie_tx_agg_setup, |
| 2232 | 2209 | ||
| 2233 | .free = iwl_trans_pcie_free, | 2210 | .free = iwl_trans_pcie_free, |
| 2234 | .stop_queue = iwl_trans_pcie_stop_queue, | ||
| 2235 | 2211 | ||
| 2236 | .dbgfs_register = iwl_trans_pcie_dbgfs_register, | 2212 | .dbgfs_register = iwl_trans_pcie_dbgfs_register, |
| 2237 | 2213 | ||
| @@ -2245,6 +2221,7 @@ const struct iwl_trans_ops trans_ops_pcie = { | |||
| 2245 | .write8 = iwl_trans_pcie_write8, | 2221 | .write8 = iwl_trans_pcie_write8, |
| 2246 | .write32 = iwl_trans_pcie_write32, | 2222 | .write32 = iwl_trans_pcie_write32, |
| 2247 | .read32 = iwl_trans_pcie_read32, | 2223 | .read32 = iwl_trans_pcie_read32, |
| 2224 | .configure = iwl_trans_pcie_configure, | ||
| 2248 | }; | 2225 | }; |
| 2249 | 2226 | ||
| 2250 | struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, | 2227 | struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, |
| @@ -2267,8 +2244,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, | |||
| 2267 | trans->ops = &trans_ops_pcie; | 2244 | trans->ops = &trans_ops_pcie; |
| 2268 | trans->shrd = shrd; | 2245 | trans->shrd = shrd; |
| 2269 | trans_pcie->trans = trans; | 2246 | trans_pcie->trans = trans; |
| 2270 | spin_lock_init(&trans->hcmd_lock); | ||
| 2271 | spin_lock_init(&trans_pcie->irq_lock); | 2247 | spin_lock_init(&trans_pcie->irq_lock); |
| 2248 | init_waitqueue_head(&trans_pcie->ucode_write_waitq); | ||
| 2272 | 2249 | ||
| 2273 | /* W/A - seems to solve weird behavior. We need to remove this if we | 2250 | /* W/A - seems to solve weird behavior. We need to remove this if we |
| 2274 | * don't want to stay in L1 all the time. This wastes a lot of power */ | 2251 | * don't want to stay in L1 all the time. This wastes a lot of power */ |
| @@ -2304,9 +2281,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, | |||
| 2304 | goto out_pci_disable_device; | 2281 | goto out_pci_disable_device; |
| 2305 | } | 2282 | } |
| 2306 | 2283 | ||
| 2307 | trans_pcie->hw_base = pci_iomap(pdev, 0, 0); | 2284 | trans_pcie->hw_base = pci_ioremap_bar(pdev, 0); |
| 2308 | if (!trans_pcie->hw_base) { | 2285 | if (!trans_pcie->hw_base) { |
| 2309 | dev_printk(KERN_ERR, &pdev->dev, "pci_iomap failed"); | 2286 | dev_printk(KERN_ERR, &pdev->dev, "pci_ioremap_bar failed"); |
| 2310 | err = -ENODEV; | 2287 | err = -ENODEV; |
| 2311 | goto out_pci_release_regions; | 2288 | goto out_pci_release_regions; |
| 2312 | } | 2289 | } |
| @@ -2330,7 +2307,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, | |||
| 2330 | "pci_enable_msi failed(0X%x)", err); | 2307 | "pci_enable_msi failed(0X%x)", err); |
| 2331 | 2308 | ||
| 2332 | trans->dev = &pdev->dev; | 2309 | trans->dev = &pdev->dev; |
| 2333 | trans->irq = pdev->irq; | 2310 | trans_pcie->irq = pdev->irq; |
| 2334 | trans_pcie->pci_dev = pdev; | 2311 | trans_pcie->pci_dev = pdev; |
| 2335 | trans->hw_rev = iwl_read32(trans, CSR_HW_REV); | 2312 | trans->hw_rev = iwl_read32(trans, CSR_HW_REV); |
| 2336 | trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; | 2313 | trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 4e7e6c0eede9..7d1990c7f658 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
| @@ -64,6 +64,7 @@ | |||
| 64 | #define __iwl_trans_h__ | 64 | #define __iwl_trans_h__ |
| 65 | 65 | ||
| 66 | #include <linux/ieee80211.h> | 66 | #include <linux/ieee80211.h> |
| 67 | #include <linux/mm.h> /* for page_address */ | ||
| 67 | 68 | ||
| 68 | #include "iwl-shared.h" | 69 | #include "iwl-shared.h" |
| 69 | #include "iwl-debug.h" | 70 | #include "iwl-debug.h" |
| @@ -121,6 +122,62 @@ struct dentry; | |||
| 121 | #define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) | 122 | #define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) |
| 122 | #define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) | 123 | #define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) |
| 123 | #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) | 124 | #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) |
| 125 | #define SEQ_TO_QUEUE(s) (((s) >> 8) & 0x1f) | ||
| 126 | #define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8) | ||
| 127 | #define SEQ_TO_INDEX(s) ((s) & 0xff) | ||
| 128 | #define INDEX_TO_SEQ(i) ((i) & 0xff) | ||
| 129 | #define SEQ_RX_FRAME cpu_to_le16(0x8000) | ||
| 130 | |||
| 131 | /** | ||
| 132 | * struct iwl_cmd_header | ||
| 133 | * | ||
| 134 | * This header format appears in the beginning of each command sent from the | ||
| 135 | * driver, and each response/notification received from uCode. | ||
| 136 | */ | ||
| 137 | struct iwl_cmd_header { | ||
| 138 | u8 cmd; /* Command ID: REPLY_RXON, etc. */ | ||
| 139 | u8 flags; /* 0:5 reserved, 6 abort, 7 internal */ | ||
| 140 | /* | ||
| 141 | * The driver sets up the sequence number to values of its choosing. | ||
| 142 | * uCode does not use this value, but passes it back to the driver | ||
| 143 | * when sending the response to each driver-originated command, so | ||
| 144 | * the driver can match the response to the command. Since the values | ||
| 145 | * don't get used by uCode, the driver may set up an arbitrary format. | ||
| 146 | * | ||
| 147 | * There is one exception: uCode sets bit 15 when it originates | ||
| 148 | * the response/notification, i.e. when the response/notification | ||
| 149 | * is not a direct response to a command sent by the driver. For | ||
| 150 | * example, uCode issues REPLY_RX when it sends a received frame | ||
| 151 | * to the driver; it is not a direct response to any driver command. | ||
| 152 | * | ||
| 153 | * The Linux driver uses the following format: | ||
| 154 | * | ||
| 155 | * 0:7 tfd index - position within TX queue | ||
| 156 | * 8:12 TX queue id | ||
| 157 | * 13:14 reserved | ||
| 158 | * 15 unsolicited RX or uCode-originated notification | ||
| 159 | */ | ||
| 160 | __le16 sequence; | ||
| 161 | } __packed; | ||
| 162 | |||
| 163 | |||
| 164 | #define FH_RSCSR_FRAME_SIZE_MSK 0x00003FFF /* bits 0-13 */ | ||
| 165 | |||
| 166 | struct iwl_rx_packet { | ||
| 167 | /* | ||
| 168 | * The first 4 bytes of the RX frame header contain both the RX frame | ||
| 169 | * size and some flags. | ||
| 170 | * Bit fields: | ||
| 171 | * 31: flag flush RB request | ||
| 172 | * 30: flag ignore TC (terminal counter) request | ||
| 173 | * 29: flag fast IRQ request | ||
| 174 | * 28-14: Reserved | ||
| 175 | * 13-00: RX frame size | ||
| 176 | */ | ||
| 177 | __le32 len_n_flags; | ||
| 178 | struct iwl_cmd_header hdr; | ||
| 179 | u8 data[]; | ||
| 180 | } __packed; | ||
| 124 | 181 | ||
| 125 | /** | 182 | /** |
| 126 | * enum CMD_MODE - how to send the host commands ? | 183 | * enum CMD_MODE - how to send the host commands ? |
| @@ -173,7 +230,9 @@ enum iwl_hcmd_dataflag { | |||
| 173 | * struct iwl_host_cmd - Host command to the uCode | 230 | * struct iwl_host_cmd - Host command to the uCode |
| 174 | * | 231 | * |
| 175 | * @data: array of chunks that composes the data of the host command | 232 | * @data: array of chunks that composes the data of the host command |
| 176 | * @reply_page: pointer to the page that holds the response to the host command | 233 | * @resp_pkt: response packet, if %CMD_WANT_SKB was set |
| 234 | * @_rx_page_order: (internally used to free response packet) | ||
| 235 | * @_rx_page_addr: (internally used to free response packet) | ||
| 177 | * @handler_status: return value of the handler of the command | 236 | * @handler_status: return value of the handler of the command |
| 178 | * (put in setup_rx_handlers) - valid for SYNC mode only | 237 | * (put in setup_rx_handlers) - valid for SYNC mode only |
| 179 | * @flags: can be CMD_* | 238 | * @flags: can be CMD_* |
| @@ -183,7 +242,9 @@ enum iwl_hcmd_dataflag { | |||
| 183 | */ | 242 | */ |
| 184 | struct iwl_host_cmd { | 243 | struct iwl_host_cmd { |
| 185 | const void *data[IWL_MAX_CMD_TFDS]; | 244 | const void *data[IWL_MAX_CMD_TFDS]; |
| 186 | unsigned long reply_page; | 245 | struct iwl_rx_packet *resp_pkt; |
| 246 | unsigned long _rx_page_addr; | ||
| 247 | u32 _rx_page_order; | ||
| 187 | int handler_status; | 248 | int handler_status; |
| 188 | 249 | ||
| 189 | u32 flags; | 250 | u32 flags; |
| @@ -192,6 +253,40 @@ struct iwl_host_cmd { | |||
| 192 | u8 id; | 253 | u8 id; |
| 193 | }; | 254 | }; |
| 194 | 255 | ||
| 256 | static inline void iwl_free_resp(struct iwl_host_cmd *cmd) | ||
| 257 | { | ||
| 258 | free_pages(cmd->_rx_page_addr, cmd->_rx_page_order); | ||
| 259 | } | ||
| 260 | |||
| 261 | struct iwl_rx_cmd_buffer { | ||
| 262 | struct page *_page; | ||
| 263 | }; | ||
| 264 | |||
| 265 | static inline void *rxb_addr(struct iwl_rx_cmd_buffer *r) | ||
| 266 | { | ||
| 267 | return page_address(r->_page); | ||
| 268 | } | ||
| 269 | |||
| 270 | static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) | ||
| 271 | { | ||
| 272 | struct page *p = r->_page; | ||
| 273 | r->_page = NULL; | ||
| 274 | return p; | ||
| 275 | } | ||
| 276 | |||
| 277 | /** | ||
| 278 | * struct iwl_trans_config - transport configuration | ||
| 279 | * | ||
| 280 | * @op_mode: pointer to the upper layer. | ||
| 281 | * Must be set before any other call. | ||
| 282 | * @cmd_queue: the index of the command queue. | ||
| 283 | * Must be set before start_fw. | ||
| 284 | */ | ||
| 285 | struct iwl_trans_config { | ||
| 286 | struct iwl_op_mode *op_mode; | ||
| 287 | u8 cmd_queue; | ||
| 288 | }; | ||
| 289 | |||
| 195 | /** | 290 | /** |
| 196 | * struct iwl_trans_ops - transport specific operations | 291 | * struct iwl_trans_ops - transport specific operations |
| 197 | * | 292 | * |
| @@ -207,9 +302,11 @@ struct iwl_host_cmd { | |||
| 207 | * May sleep | 302 | * May sleep |
| 208 | * @fw_alive: called when the fw sends alive notification | 303 | * @fw_alive: called when the fw sends alive notification |
| 209 | * May sleep | 304 | * May sleep |
| 210 | * @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_* | ||
| 211 | * @stop_device:stops the whole device (embedded CPU put to reset) | 305 | * @stop_device:stops the whole device (embedded CPU put to reset) |
| 212 | * May sleep | 306 | * May sleep |
| 307 | * @wowlan_suspend: put the device into the correct mode for WoWLAN during | ||
| 308 | * suspend. This is optional, if not implemented WoWLAN will not be | ||
| 309 | * supported. This callback may sleep. | ||
| 213 | * @send_cmd:send a host command | 310 | * @send_cmd:send a host command |
| 214 | * May sleep only if CMD_SYNC is set | 311 | * May sleep only if CMD_SYNC is set |
| 215 | * @tx: send an skb | 312 | * @tx: send an skb |
| @@ -217,17 +314,16 @@ struct iwl_host_cmd { | |||
| 217 | * @reclaim: free packet until ssn. Returns a list of freed packets. | 314 | * @reclaim: free packet until ssn. Returns a list of freed packets. |
| 218 | * Must be atomic | 315 | * Must be atomic |
| 219 | * @tx_agg_alloc: allocate resources for a TX BA session | 316 | * @tx_agg_alloc: allocate resources for a TX BA session |
| 220 | * May sleep | 317 | * Must be atomic |
| 221 | * @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is | 318 | * @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is |
| 222 | * ready and a successful ADDBA response has been received. | 319 | * ready and a successful ADDBA response has been received. |
| 223 | * May sleep | 320 | * May sleep |
| 224 | * @tx_agg_disable: de-configure a Tx queue to send AMPDUs | 321 | * @tx_agg_disable: de-configure a Tx queue to send AMPDUs |
| 225 | * May sleep | 322 | * Must be atomic |
| 226 | * @free: release all the ressource for the transport layer itself such as | 323 | * @free: release all the ressource for the transport layer itself such as |
| 227 | * irq, tasklet etc... From this point on, the device may not issue | 324 | * irq, tasklet etc... From this point on, the device may not issue |
| 228 | * any interrupt (incl. RFKILL). | 325 | * any interrupt (incl. RFKILL). |
| 229 | * May sleep | 326 | * May sleep |
| 230 | * @stop_queue: stop a specific queue | ||
| 231 | * @check_stuck_queue: check if a specific queue is stuck | 327 | * @check_stuck_queue: check if a specific queue is stuck |
| 232 | * @wait_tx_queue_empty: wait until all tx queues are empty | 328 | * @wait_tx_queue_empty: wait until all tx queues are empty |
| 233 | * May sleep | 329 | * May sleep |
| @@ -238,18 +334,19 @@ struct iwl_host_cmd { | |||
| 238 | * @write8: write a u8 to a register at offset ofs from the BAR | 334 | * @write8: write a u8 to a register at offset ofs from the BAR |
| 239 | * @write32: write a u32 to a register at offset ofs from the BAR | 335 | * @write32: write a u32 to a register at offset ofs from the BAR |
| 240 | * @read32: read a u32 register at offset ofs from the BAR | 336 | * @read32: read a u32 register at offset ofs from the BAR |
| 337 | * @configure: configure parameters required by the transport layer from | ||
| 338 | * the op_mode. May be called several times before start_fw, can't be | ||
| 339 | * called after that. | ||
| 241 | */ | 340 | */ |
| 242 | struct iwl_trans_ops { | 341 | struct iwl_trans_ops { |
| 243 | 342 | ||
| 244 | int (*start_hw)(struct iwl_trans *iwl_trans); | 343 | int (*start_hw)(struct iwl_trans *iwl_trans); |
| 245 | void (*stop_hw)(struct iwl_trans *iwl_trans); | 344 | void (*stop_hw)(struct iwl_trans *iwl_trans); |
| 246 | int (*start_fw)(struct iwl_trans *trans, struct fw_img *fw); | 345 | int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw); |
| 247 | void (*fw_alive)(struct iwl_trans *trans); | 346 | void (*fw_alive)(struct iwl_trans *trans); |
| 248 | void (*stop_device)(struct iwl_trans *trans); | 347 | void (*stop_device)(struct iwl_trans *trans); |
| 249 | 348 | ||
| 250 | void (*wake_any_queue)(struct iwl_trans *trans, | 349 | void (*wowlan_suspend)(struct iwl_trans *trans); |
| 251 | enum iwl_rxon_context_id ctx, | ||
| 252 | const char *msg); | ||
| 253 | 350 | ||
| 254 | int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); | 351 | int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); |
| 255 | 352 | ||
| @@ -257,8 +354,7 @@ struct iwl_trans_ops { | |||
| 257 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, | 354 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, |
| 258 | u8 sta_id, u8 tid); | 355 | u8 sta_id, u8 tid); |
| 259 | int (*reclaim)(struct iwl_trans *trans, int sta_id, int tid, | 356 | int (*reclaim)(struct iwl_trans *trans, int sta_id, int tid, |
| 260 | int txq_id, int ssn, u32 status, | 357 | int txq_id, int ssn, struct sk_buff_head *skbs); |
| 261 | struct sk_buff_head *skbs); | ||
| 262 | 358 | ||
| 263 | int (*tx_agg_disable)(struct iwl_trans *trans, | 359 | int (*tx_agg_disable)(struct iwl_trans *trans, |
| 264 | int sta_id, int tid); | 360 | int sta_id, int tid); |
| @@ -270,8 +366,6 @@ struct iwl_trans_ops { | |||
| 270 | 366 | ||
| 271 | void (*free)(struct iwl_trans *trans); | 367 | void (*free)(struct iwl_trans *trans); |
| 272 | 368 | ||
| 273 | void (*stop_queue)(struct iwl_trans *trans, int q, const char *msg); | ||
| 274 | |||
| 275 | int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); | 369 | int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); |
| 276 | int (*check_stuck_queue)(struct iwl_trans *trans, int q); | 370 | int (*check_stuck_queue)(struct iwl_trans *trans, int q); |
| 277 | int (*wait_tx_queue_empty)(struct iwl_trans *trans); | 371 | int (*wait_tx_queue_empty)(struct iwl_trans *trans); |
| @@ -282,14 +376,8 @@ struct iwl_trans_ops { | |||
| 282 | void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val); | 376 | void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val); |
| 283 | void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val); | 377 | void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val); |
| 284 | u32 (*read32)(struct iwl_trans *trans, u32 ofs); | 378 | u32 (*read32)(struct iwl_trans *trans, u32 ofs); |
| 285 | }; | 379 | void (*configure)(struct iwl_trans *trans, |
| 286 | 380 | const struct iwl_trans_config *trans_cfg); | |
| 287 | /* Opaque calibration results */ | ||
| 288 | struct iwl_calib_result { | ||
| 289 | struct list_head list; | ||
| 290 | size_t cmd_len; | ||
| 291 | struct iwl_calib_hdr hdr; | ||
| 292 | /* data follows */ | ||
| 293 | }; | 381 | }; |
| 294 | 382 | ||
| 295 | /** | 383 | /** |
| @@ -309,52 +397,44 @@ enum iwl_trans_state { | |||
| 309 | * @ops - pointer to iwl_trans_ops | 397 | * @ops - pointer to iwl_trans_ops |
| 310 | * @op_mode - pointer to the op_mode | 398 | * @op_mode - pointer to the op_mode |
| 311 | * @shrd - pointer to iwl_shared which holds shared data from the upper layer | 399 | * @shrd - pointer to iwl_shared which holds shared data from the upper layer |
| 312 | * @hcmd_lock: protects HCMD | ||
| 313 | * @reg_lock - protect hw register access | 400 | * @reg_lock - protect hw register access |
| 314 | * @dev - pointer to struct device * that represents the device | 401 | * @dev - pointer to struct device * that represents the device |
| 315 | * @irq - the irq number for the device | ||
| 316 | * @hw_id: a u32 with the ID of the device / subdevice. | 402 | * @hw_id: a u32 with the ID of the device / subdevice. |
| 317 | * Set during transport allocation. | 403 | * Set during transport allocation. |
| 318 | * @hw_id_str: a string with info about HW ID. Set during transport allocation. | 404 | * @hw_id_str: a string with info about HW ID. Set during transport allocation. |
| 319 | * @ucode_write_complete: indicates that the ucode has been copied. | ||
| 320 | * @nvm_device_type: indicates OTP or eeprom | 405 | * @nvm_device_type: indicates OTP or eeprom |
| 321 | * @pm_support: set to true in start_hw if link pm is supported | 406 | * @pm_support: set to true in start_hw if link pm is supported |
| 322 | * @calib_results: list head for init calibration results | ||
| 323 | */ | 407 | */ |
| 324 | struct iwl_trans { | 408 | struct iwl_trans { |
| 325 | const struct iwl_trans_ops *ops; | 409 | const struct iwl_trans_ops *ops; |
| 326 | struct iwl_op_mode *op_mode; | 410 | struct iwl_op_mode *op_mode; |
| 327 | struct iwl_shared *shrd; | 411 | struct iwl_shared *shrd; |
| 328 | enum iwl_trans_state state; | 412 | enum iwl_trans_state state; |
| 329 | spinlock_t hcmd_lock; | ||
| 330 | spinlock_t reg_lock; | 413 | spinlock_t reg_lock; |
| 331 | 414 | ||
| 332 | struct device *dev; | 415 | struct device *dev; |
| 333 | unsigned int irq; | ||
| 334 | u32 hw_rev; | 416 | u32 hw_rev; |
| 335 | u32 hw_id; | 417 | u32 hw_id; |
| 336 | char hw_id_str[52]; | 418 | char hw_id_str[52]; |
| 337 | 419 | ||
| 338 | u8 ucode_write_complete; | ||
| 339 | |||
| 340 | int nvm_device_type; | 420 | int nvm_device_type; |
| 341 | bool pm_support; | 421 | bool pm_support; |
| 342 | 422 | ||
| 343 | struct list_head calib_results; | ||
| 344 | |||
| 345 | /* pointer to trans specific struct */ | 423 | /* pointer to trans specific struct */ |
| 346 | /*Ensure that this pointer will always be aligned to sizeof pointer */ | 424 | /*Ensure that this pointer will always be aligned to sizeof pointer */ |
| 347 | char trans_specific[0] __aligned(sizeof(void *)); | 425 | char trans_specific[0] __aligned(sizeof(void *)); |
| 348 | }; | 426 | }; |
| 349 | 427 | ||
| 350 | static inline void iwl_trans_configure(struct iwl_trans *trans, | 428 | static inline void iwl_trans_configure(struct iwl_trans *trans, |
| 351 | struct iwl_op_mode *op_mode) | 429 | const struct iwl_trans_config *trans_cfg) |
| 352 | { | 430 | { |
| 353 | /* | 431 | /* |
| 354 | * only set the op_mode for the moment. Later on, this function will do | 432 | * only set the op_mode for the moment. Later on, this function will do |
| 355 | * more | 433 | * more |
| 356 | */ | 434 | */ |
| 357 | trans->op_mode = op_mode; | 435 | trans->op_mode = trans_cfg->op_mode; |
| 436 | |||
| 437 | trans->ops->configure(trans, trans_cfg); | ||
| 358 | } | 438 | } |
| 359 | 439 | ||
| 360 | static inline int iwl_trans_start_hw(struct iwl_trans *trans) | 440 | static inline int iwl_trans_start_hw(struct iwl_trans *trans) |
| @@ -382,7 +462,8 @@ static inline void iwl_trans_fw_alive(struct iwl_trans *trans) | |||
| 382 | trans->state = IWL_TRANS_FW_ALIVE; | 462 | trans->state = IWL_TRANS_FW_ALIVE; |
| 383 | } | 463 | } |
| 384 | 464 | ||
| 385 | static inline int iwl_trans_start_fw(struct iwl_trans *trans, struct fw_img *fw) | 465 | static inline int iwl_trans_start_fw(struct iwl_trans *trans, |
| 466 | const struct fw_img *fw) | ||
| 386 | { | 467 | { |
| 387 | might_sleep(); | 468 | might_sleep(); |
| 388 | 469 | ||
| @@ -398,17 +479,12 @@ static inline void iwl_trans_stop_device(struct iwl_trans *trans) | |||
| 398 | trans->state = IWL_TRANS_NO_FW; | 479 | trans->state = IWL_TRANS_NO_FW; |
| 399 | } | 480 | } |
| 400 | 481 | ||
| 401 | static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans, | 482 | static inline void iwl_trans_wowlan_suspend(struct iwl_trans *trans) |
| 402 | enum iwl_rxon_context_id ctx, | ||
| 403 | const char *msg) | ||
| 404 | { | 483 | { |
| 405 | if (trans->state != IWL_TRANS_FW_ALIVE) | 484 | might_sleep(); |
| 406 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | 485 | trans->ops->wowlan_suspend(trans); |
| 407 | |||
| 408 | trans->ops->wake_any_queue(trans, ctx, msg); | ||
| 409 | } | 486 | } |
| 410 | 487 | ||
| 411 | |||
| 412 | static inline int iwl_trans_send_cmd(struct iwl_trans *trans, | 488 | static inline int iwl_trans_send_cmd(struct iwl_trans *trans, |
| 413 | struct iwl_host_cmd *cmd) | 489 | struct iwl_host_cmd *cmd) |
| 414 | { | 490 | { |
| @@ -418,9 +494,6 @@ static inline int iwl_trans_send_cmd(struct iwl_trans *trans, | |||
| 418 | return trans->ops->send_cmd(trans, cmd); | 494 | return trans->ops->send_cmd(trans, cmd); |
| 419 | } | 495 | } |
| 420 | 496 | ||
| 421 | int iwl_trans_send_cmd_pdu(struct iwl_trans *trans, u8 id, | ||
| 422 | u32 flags, u16 len, const void *data); | ||
| 423 | |||
| 424 | static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, | 497 | static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, |
| 425 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, | 498 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, |
| 426 | u8 sta_id, u8 tid) | 499 | u8 sta_id, u8 tid) |
| @@ -432,21 +505,18 @@ static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
| 432 | } | 505 | } |
| 433 | 506 | ||
| 434 | static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id, | 507 | static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id, |
| 435 | int tid, int txq_id, int ssn, u32 status, | 508 | int tid, int txq_id, int ssn, |
| 436 | struct sk_buff_head *skbs) | 509 | struct sk_buff_head *skbs) |
| 437 | { | 510 | { |
| 438 | if (trans->state != IWL_TRANS_FW_ALIVE) | 511 | if (trans->state != IWL_TRANS_FW_ALIVE) |
| 439 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | 512 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); |
| 440 | 513 | ||
| 441 | return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn, | 514 | return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn, skbs); |
| 442 | status, skbs); | ||
| 443 | } | 515 | } |
| 444 | 516 | ||
| 445 | static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans, | 517 | static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans, |
| 446 | int sta_id, int tid) | 518 | int sta_id, int tid) |
| 447 | { | 519 | { |
| 448 | might_sleep(); | ||
| 449 | |||
| 450 | if (trans->state != IWL_TRANS_FW_ALIVE) | 520 | if (trans->state != IWL_TRANS_FW_ALIVE) |
| 451 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | 521 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); |
| 452 | 522 | ||
| @@ -456,8 +526,6 @@ static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans, | |||
| 456 | static inline int iwl_trans_tx_agg_alloc(struct iwl_trans *trans, | 526 | static inline int iwl_trans_tx_agg_alloc(struct iwl_trans *trans, |
| 457 | int sta_id, int tid) | 527 | int sta_id, int tid) |
| 458 | { | 528 | { |
| 459 | might_sleep(); | ||
| 460 | |||
| 461 | if (trans->state != IWL_TRANS_FW_ALIVE) | 529 | if (trans->state != IWL_TRANS_FW_ALIVE) |
| 462 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | 530 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); |
| 463 | 531 | ||
| @@ -483,15 +551,6 @@ static inline void iwl_trans_free(struct iwl_trans *trans) | |||
| 483 | trans->ops->free(trans); | 551 | trans->ops->free(trans); |
| 484 | } | 552 | } |
| 485 | 553 | ||
| 486 | static inline void iwl_trans_stop_queue(struct iwl_trans *trans, int q, | ||
| 487 | const char *msg) | ||
| 488 | { | ||
| 489 | if (trans->state != IWL_TRANS_FW_ALIVE) | ||
| 490 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | ||
| 491 | |||
| 492 | trans->ops->stop_queue(trans, q, msg); | ||
| 493 | } | ||
| 494 | |||
| 495 | static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) | 554 | static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) |
| 496 | { | 555 | { |
| 497 | if (trans->state != IWL_TRANS_FW_ALIVE) | 556 | if (trans->state != IWL_TRANS_FW_ALIVE) |
| @@ -541,14 +600,6 @@ static inline u32 iwl_trans_read32(struct iwl_trans *trans, u32 ofs) | |||
| 541 | } | 600 | } |
| 542 | 601 | ||
| 543 | /***************************************************** | 602 | /***************************************************** |
| 544 | * Utils functions | ||
| 545 | ******************************************************/ | ||
| 546 | int iwl_send_calib_results(struct iwl_trans *trans); | ||
| 547 | int iwl_calib_set(struct iwl_trans *trans, | ||
| 548 | const struct iwl_calib_hdr *cmd, int len); | ||
| 549 | void iwl_calib_free_results(struct iwl_trans *trans); | ||
| 550 | |||
| 551 | /***************************************************** | ||
| 552 | * Transport layers implementations + their allocation function | 603 | * Transport layers implementations + their allocation function |
| 553 | ******************************************************/ | 604 | ******************************************************/ |
| 554 | struct pci_dev; | 605 | struct pci_dev; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index b16efc00ba6e..d97cf44b75ba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c | |||
| @@ -28,14 +28,8 @@ | |||
| 28 | *****************************************************************************/ | 28 | *****************************************************************************/ |
| 29 | 29 | ||
| 30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
| 31 | #include <linux/module.h> | ||
| 32 | #include <linux/init.h> | 31 | #include <linux/init.h> |
| 33 | #include <linux/sched.h> | ||
| 34 | #include <linux/dma-mapping.h> | ||
| 35 | #include <linux/firmware.h> | ||
| 36 | 32 | ||
| 37 | #include "iwl-ucode.h" | ||
| 38 | #include "iwl-wifi.h" | ||
| 39 | #include "iwl-dev.h" | 33 | #include "iwl-dev.h" |
| 40 | #include "iwl-core.h" | 34 | #include "iwl-core.h" |
| 41 | #include "iwl-io.h" | 35 | #include "iwl-io.h" |
| @@ -83,56 +77,16 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { | |||
| 83 | * | 77 | * |
| 84 | ******************************************************************************/ | 78 | ******************************************************************************/ |
| 85 | 79 | ||
| 86 | static void iwl_free_fw_desc(struct iwl_nic *nic, struct fw_desc *desc) | 80 | static inline const struct fw_img * |
| 87 | { | 81 | iwl_get_ucode_image(struct iwl_priv *priv, enum iwl_ucode_type ucode_type) |
| 88 | if (desc->v_addr) | ||
| 89 | dma_free_coherent(trans(nic)->dev, desc->len, | ||
| 90 | desc->v_addr, desc->p_addr); | ||
| 91 | desc->v_addr = NULL; | ||
| 92 | desc->len = 0; | ||
| 93 | } | ||
| 94 | |||
| 95 | static void iwl_free_fw_img(struct iwl_nic *nic, struct fw_img *img) | ||
| 96 | { | ||
| 97 | iwl_free_fw_desc(nic, &img->code); | ||
| 98 | iwl_free_fw_desc(nic, &img->data); | ||
| 99 | } | ||
| 100 | |||
| 101 | void iwl_dealloc_ucode(struct iwl_nic *nic) | ||
| 102 | { | ||
| 103 | iwl_free_fw_img(nic, &nic->fw.ucode_rt); | ||
| 104 | iwl_free_fw_img(nic, &nic->fw.ucode_init); | ||
| 105 | iwl_free_fw_img(nic, &nic->fw.ucode_wowlan); | ||
| 106 | } | ||
| 107 | |||
| 108 | static int iwl_alloc_fw_desc(struct iwl_nic *nic, struct fw_desc *desc, | ||
| 109 | const void *data, size_t len) | ||
| 110 | { | ||
| 111 | if (!len) { | ||
| 112 | desc->v_addr = NULL; | ||
| 113 | return -EINVAL; | ||
| 114 | } | ||
| 115 | |||
| 116 | desc->v_addr = dma_alloc_coherent(trans(nic)->dev, len, | ||
| 117 | &desc->p_addr, GFP_KERNEL); | ||
| 118 | if (!desc->v_addr) | ||
| 119 | return -ENOMEM; | ||
| 120 | |||
| 121 | desc->len = len; | ||
| 122 | memcpy(desc->v_addr, data, len); | ||
| 123 | return 0; | ||
| 124 | } | ||
| 125 | |||
| 126 | static inline struct fw_img *iwl_get_ucode_image(struct iwl_nic *nic, | ||
| 127 | enum iwl_ucode_type ucode_type) | ||
| 128 | { | 82 | { |
| 129 | switch (ucode_type) { | 83 | switch (ucode_type) { |
| 130 | case IWL_UCODE_INIT: | 84 | case IWL_UCODE_INIT: |
| 131 | return &nic->fw.ucode_init; | 85 | return &priv->fw->ucode_init; |
| 132 | case IWL_UCODE_WOWLAN: | 86 | case IWL_UCODE_WOWLAN: |
| 133 | return &nic->fw.ucode_wowlan; | 87 | return &priv->fw->ucode_wowlan; |
| 134 | case IWL_UCODE_REGULAR: | 88 | case IWL_UCODE_REGULAR: |
| 135 | return &nic->fw.ucode_rt; | 89 | return &priv->fw->ucode_rt; |
| 136 | case IWL_UCODE_NONE: | 90 | case IWL_UCODE_NONE: |
| 137 | break; | 91 | break; |
| 138 | } | 92 | } |
| @@ -142,23 +96,23 @@ static inline struct fw_img *iwl_get_ucode_image(struct iwl_nic *nic, | |||
| 142 | /* | 96 | /* |
| 143 | * Calibration | 97 | * Calibration |
| 144 | */ | 98 | */ |
| 145 | static int iwl_set_Xtal_calib(struct iwl_trans *trans) | 99 | static int iwl_set_Xtal_calib(struct iwl_priv *priv) |
| 146 | { | 100 | { |
| 147 | struct iwl_calib_xtal_freq_cmd cmd; | 101 | struct iwl_calib_xtal_freq_cmd cmd; |
| 148 | __le16 *xtal_calib = | 102 | __le16 *xtal_calib = |
| 149 | (__le16 *)iwl_eeprom_query_addr(trans->shrd, EEPROM_XTAL); | 103 | (__le16 *)iwl_eeprom_query_addr(priv->shrd, EEPROM_XTAL); |
| 150 | 104 | ||
| 151 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); | 105 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); |
| 152 | cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); | 106 | cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); |
| 153 | cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]); | 107 | cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]); |
| 154 | return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd)); | 108 | return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); |
| 155 | } | 109 | } |
| 156 | 110 | ||
| 157 | static int iwl_set_temperature_offset_calib(struct iwl_trans *trans) | 111 | static int iwl_set_temperature_offset_calib(struct iwl_priv *priv) |
| 158 | { | 112 | { |
| 159 | struct iwl_calib_temperature_offset_cmd cmd; | 113 | struct iwl_calib_temperature_offset_cmd cmd; |
| 160 | __le16 *offset_calib = | 114 | __le16 *offset_calib = |
| 161 | (__le16 *)iwl_eeprom_query_addr(trans->shrd, | 115 | (__le16 *)iwl_eeprom_query_addr(priv->shrd, |
| 162 | EEPROM_RAW_TEMPERATURE); | 116 | EEPROM_RAW_TEMPERATURE); |
| 163 | 117 | ||
| 164 | memset(&cmd, 0, sizeof(cmd)); | 118 | memset(&cmd, 0, sizeof(cmd)); |
| @@ -167,48 +121,48 @@ static int iwl_set_temperature_offset_calib(struct iwl_trans *trans) | |||
| 167 | if (!(cmd.radio_sensor_offset)) | 121 | if (!(cmd.radio_sensor_offset)) |
| 168 | cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; | 122 | cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; |
| 169 | 123 | ||
| 170 | IWL_DEBUG_CALIB(trans, "Radio sensor offset: %d\n", | 124 | IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n", |
| 171 | le16_to_cpu(cmd.radio_sensor_offset)); | 125 | le16_to_cpu(cmd.radio_sensor_offset)); |
| 172 | return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd)); | 126 | return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); |
| 173 | } | 127 | } |
| 174 | 128 | ||
| 175 | static int iwl_set_temperature_offset_calib_v2(struct iwl_trans *trans) | 129 | static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv) |
| 176 | { | 130 | { |
| 177 | struct iwl_calib_temperature_offset_v2_cmd cmd; | 131 | struct iwl_calib_temperature_offset_v2_cmd cmd; |
| 178 | __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(trans->shrd, | 132 | __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(priv->shrd, |
| 179 | EEPROM_KELVIN_TEMPERATURE); | 133 | EEPROM_KELVIN_TEMPERATURE); |
| 180 | __le16 *offset_calib_low = | 134 | __le16 *offset_calib_low = |
| 181 | (__le16 *)iwl_eeprom_query_addr(trans->shrd, | 135 | (__le16 *)iwl_eeprom_query_addr(priv->shrd, |
| 182 | EEPROM_RAW_TEMPERATURE); | 136 | EEPROM_RAW_TEMPERATURE); |
| 183 | struct iwl_eeprom_calib_hdr *hdr; | 137 | struct iwl_eeprom_calib_hdr *hdr; |
| 184 | 138 | ||
| 185 | memset(&cmd, 0, sizeof(cmd)); | 139 | memset(&cmd, 0, sizeof(cmd)); |
| 186 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); | 140 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); |
| 187 | hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(trans->shrd, | 141 | hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv->shrd, |
| 188 | EEPROM_CALIB_ALL); | 142 | EEPROM_CALIB_ALL); |
| 189 | memcpy(&cmd.radio_sensor_offset_high, offset_calib_high, | 143 | memcpy(&cmd.radio_sensor_offset_high, offset_calib_high, |
| 190 | sizeof(*offset_calib_high)); | 144 | sizeof(*offset_calib_high)); |
| 191 | memcpy(&cmd.radio_sensor_offset_low, offset_calib_low, | 145 | memcpy(&cmd.radio_sensor_offset_low, offset_calib_low, |
| 192 | sizeof(*offset_calib_low)); | 146 | sizeof(*offset_calib_low)); |
| 193 | if (!(cmd.radio_sensor_offset_low)) { | 147 | if (!(cmd.radio_sensor_offset_low)) { |
| 194 | IWL_DEBUG_CALIB(trans, "no info in EEPROM, use default\n"); | 148 | IWL_DEBUG_CALIB(priv, "no info in EEPROM, use default\n"); |
| 195 | cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET; | 149 | cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET; |
| 196 | cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET; | 150 | cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET; |
| 197 | } | 151 | } |
| 198 | memcpy(&cmd.burntVoltageRef, &hdr->voltage, | 152 | memcpy(&cmd.burntVoltageRef, &hdr->voltage, |
| 199 | sizeof(hdr->voltage)); | 153 | sizeof(hdr->voltage)); |
| 200 | 154 | ||
| 201 | IWL_DEBUG_CALIB(trans, "Radio sensor offset high: %d\n", | 155 | IWL_DEBUG_CALIB(priv, "Radio sensor offset high: %d\n", |
| 202 | le16_to_cpu(cmd.radio_sensor_offset_high)); | 156 | le16_to_cpu(cmd.radio_sensor_offset_high)); |
| 203 | IWL_DEBUG_CALIB(trans, "Radio sensor offset low: %d\n", | 157 | IWL_DEBUG_CALIB(priv, "Radio sensor offset low: %d\n", |
| 204 | le16_to_cpu(cmd.radio_sensor_offset_low)); | 158 | le16_to_cpu(cmd.radio_sensor_offset_low)); |
| 205 | IWL_DEBUG_CALIB(trans, "Voltage Ref: %d\n", | 159 | IWL_DEBUG_CALIB(priv, "Voltage Ref: %d\n", |
| 206 | le16_to_cpu(cmd.burntVoltageRef)); | 160 | le16_to_cpu(cmd.burntVoltageRef)); |
| 207 | 161 | ||
| 208 | return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd)); | 162 | return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); |
| 209 | } | 163 | } |
| 210 | 164 | ||
| 211 | static int iwl_send_calib_cfg(struct iwl_trans *trans) | 165 | static int iwl_send_calib_cfg(struct iwl_priv *priv) |
| 212 | { | 166 | { |
| 213 | struct iwl_calib_cfg_cmd calib_cfg_cmd; | 167 | struct iwl_calib_cfg_cmd calib_cfg_cmd; |
| 214 | struct iwl_host_cmd cmd = { | 168 | struct iwl_host_cmd cmd = { |
| @@ -224,47 +178,47 @@ static int iwl_send_calib_cfg(struct iwl_trans *trans) | |||
| 224 | calib_cfg_cmd.ucd_calib_cfg.flags = | 178 | calib_cfg_cmd.ucd_calib_cfg.flags = |
| 225 | IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK; | 179 | IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK; |
| 226 | 180 | ||
| 227 | return iwl_trans_send_cmd(trans, &cmd); | 181 | return iwl_dvm_send_cmd(priv, &cmd); |
| 228 | } | 182 | } |
| 229 | 183 | ||
| 230 | int iwlagn_rx_calib_result(struct iwl_priv *priv, | 184 | int iwlagn_rx_calib_result(struct iwl_priv *priv, |
| 231 | struct iwl_rx_mem_buffer *rxb, | 185 | struct iwl_rx_cmd_buffer *rxb, |
| 232 | struct iwl_device_cmd *cmd) | 186 | struct iwl_device_cmd *cmd) |
| 233 | { | 187 | { |
| 234 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 188 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 235 | struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw; | 189 | struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->data; |
| 236 | int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | 190 | int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; |
| 237 | 191 | ||
| 238 | /* reduce the size of the length field itself */ | 192 | /* reduce the size of the length field itself */ |
| 239 | len -= 4; | 193 | len -= 4; |
| 240 | 194 | ||
| 241 | if (iwl_calib_set(trans(priv), hdr, len)) | 195 | if (iwl_calib_set(priv, hdr, len)) |
| 242 | IWL_ERR(priv, "Failed to record calibration data %d\n", | 196 | IWL_ERR(priv, "Failed to record calibration data %d\n", |
| 243 | hdr->op_code); | 197 | hdr->op_code); |
| 244 | 198 | ||
| 245 | return 0; | 199 | return 0; |
| 246 | } | 200 | } |
| 247 | 201 | ||
| 248 | int iwl_init_alive_start(struct iwl_trans *trans) | 202 | int iwl_init_alive_start(struct iwl_priv *priv) |
| 249 | { | 203 | { |
| 250 | int ret; | 204 | int ret; |
| 251 | 205 | ||
| 252 | if (cfg(trans)->bt_params && | 206 | if (cfg(priv)->bt_params && |
| 253 | cfg(trans)->bt_params->advanced_bt_coexist) { | 207 | cfg(priv)->bt_params->advanced_bt_coexist) { |
| 254 | /* | 208 | /* |
| 255 | * Tell uCode we are ready to perform calibration | 209 | * Tell uCode we are ready to perform calibration |
| 256 | * need to perform this before any calibration | 210 | * need to perform this before any calibration |
| 257 | * no need to close the envlope since we are going | 211 | * no need to close the envlope since we are going |
| 258 | * to load the runtime uCode later. | 212 | * to load the runtime uCode later. |
| 259 | */ | 213 | */ |
| 260 | ret = iwl_send_bt_env(trans, IWL_BT_COEX_ENV_OPEN, | 214 | ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, |
| 261 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | 215 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); |
| 262 | if (ret) | 216 | if (ret) |
| 263 | return ret; | 217 | return ret; |
| 264 | 218 | ||
| 265 | } | 219 | } |
| 266 | 220 | ||
| 267 | ret = iwl_send_calib_cfg(trans); | 221 | ret = iwl_send_calib_cfg(priv); |
| 268 | if (ret) | 222 | if (ret) |
| 269 | return ret; | 223 | return ret; |
| 270 | 224 | ||
| @@ -272,21 +226,21 @@ int iwl_init_alive_start(struct iwl_trans *trans) | |||
| 272 | * temperature offset calibration is only needed for runtime ucode, | 226 | * temperature offset calibration is only needed for runtime ucode, |
| 273 | * so prepare the value now. | 227 | * so prepare the value now. |
| 274 | */ | 228 | */ |
| 275 | if (cfg(trans)->need_temp_offset_calib) { | 229 | if (cfg(priv)->need_temp_offset_calib) { |
| 276 | if (cfg(trans)->temp_offset_v2) | 230 | if (cfg(priv)->temp_offset_v2) |
| 277 | return iwl_set_temperature_offset_calib_v2(trans); | 231 | return iwl_set_temperature_offset_calib_v2(priv); |
| 278 | else | 232 | else |
| 279 | return iwl_set_temperature_offset_calib(trans); | 233 | return iwl_set_temperature_offset_calib(priv); |
| 280 | } | 234 | } |
| 281 | 235 | ||
| 282 | return 0; | 236 | return 0; |
| 283 | } | 237 | } |
| 284 | 238 | ||
| 285 | static int iwl_send_wimax_coex(struct iwl_trans *trans) | 239 | static int iwl_send_wimax_coex(struct iwl_priv *priv) |
| 286 | { | 240 | { |
| 287 | struct iwl_wimax_coex_cmd coex_cmd; | 241 | struct iwl_wimax_coex_cmd coex_cmd; |
| 288 | 242 | ||
| 289 | if (cfg(trans)->base_params->support_wimax_coexist) { | 243 | if (cfg(priv)->base_params->support_wimax_coexist) { |
| 290 | /* UnMask wake up src at associated sleep */ | 244 | /* UnMask wake up src at associated sleep */ |
| 291 | coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK; | 245 | coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK; |
| 292 | 246 | ||
| @@ -305,7 +259,7 @@ static int iwl_send_wimax_coex(struct iwl_trans *trans) | |||
| 305 | /* coexistence is disabled */ | 259 | /* coexistence is disabled */ |
| 306 | memset(&coex_cmd, 0, sizeof(coex_cmd)); | 260 | memset(&coex_cmd, 0, sizeof(coex_cmd)); |
| 307 | } | 261 | } |
| 308 | return iwl_trans_send_cmd_pdu(trans, | 262 | return iwl_dvm_send_cmd_pdu(priv, |
| 309 | COEX_PRIORITY_TABLE_CMD, CMD_SYNC, | 263 | COEX_PRIORITY_TABLE_CMD, CMD_SYNC, |
| 310 | sizeof(coex_cmd), &coex_cmd); | 264 | sizeof(coex_cmd), &coex_cmd); |
| 311 | } | 265 | } |
| @@ -332,64 +286,54 @@ static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = { | |||
| 332 | 0, 0, 0, 0, 0, 0, 0 | 286 | 0, 0, 0, 0, 0, 0, 0 |
| 333 | }; | 287 | }; |
| 334 | 288 | ||
| 335 | void iwl_send_prio_tbl(struct iwl_trans *trans) | 289 | void iwl_send_prio_tbl(struct iwl_priv *priv) |
| 336 | { | 290 | { |
| 337 | struct iwl_bt_coex_prio_table_cmd prio_tbl_cmd; | 291 | struct iwl_bt_coex_prio_table_cmd prio_tbl_cmd; |
| 338 | 292 | ||
| 339 | memcpy(prio_tbl_cmd.prio_tbl, iwl_bt_prio_tbl, | 293 | memcpy(prio_tbl_cmd.prio_tbl, iwl_bt_prio_tbl, |
| 340 | sizeof(iwl_bt_prio_tbl)); | 294 | sizeof(iwl_bt_prio_tbl)); |
| 341 | if (iwl_trans_send_cmd_pdu(trans, | 295 | if (iwl_dvm_send_cmd_pdu(priv, |
| 342 | REPLY_BT_COEX_PRIO_TABLE, CMD_SYNC, | 296 | REPLY_BT_COEX_PRIO_TABLE, CMD_SYNC, |
| 343 | sizeof(prio_tbl_cmd), &prio_tbl_cmd)) | 297 | sizeof(prio_tbl_cmd), &prio_tbl_cmd)) |
| 344 | IWL_ERR(trans, "failed to send BT prio tbl command\n"); | 298 | IWL_ERR(priv, "failed to send BT prio tbl command\n"); |
| 345 | } | 299 | } |
| 346 | 300 | ||
| 347 | int iwl_send_bt_env(struct iwl_trans *trans, u8 action, u8 type) | 301 | int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) |
| 348 | { | 302 | { |
| 349 | struct iwl_bt_coex_prot_env_cmd env_cmd; | 303 | struct iwl_bt_coex_prot_env_cmd env_cmd; |
| 350 | int ret; | 304 | int ret; |
| 351 | 305 | ||
| 352 | env_cmd.action = action; | 306 | env_cmd.action = action; |
| 353 | env_cmd.type = type; | 307 | env_cmd.type = type; |
| 354 | ret = iwl_trans_send_cmd_pdu(trans, | 308 | ret = iwl_dvm_send_cmd_pdu(priv, |
| 355 | REPLY_BT_COEX_PROT_ENV, CMD_SYNC, | 309 | REPLY_BT_COEX_PROT_ENV, CMD_SYNC, |
| 356 | sizeof(env_cmd), &env_cmd); | 310 | sizeof(env_cmd), &env_cmd); |
| 357 | if (ret) | 311 | if (ret) |
| 358 | IWL_ERR(trans, "failed to send BT env command\n"); | 312 | IWL_ERR(priv, "failed to send BT env command\n"); |
| 359 | return ret; | 313 | return ret; |
| 360 | } | 314 | } |
| 361 | 315 | ||
| 362 | 316 | ||
| 363 | static int iwl_alive_notify(struct iwl_trans *trans) | 317 | static int iwl_alive_notify(struct iwl_priv *priv) |
| 364 | { | 318 | { |
| 365 | struct iwl_priv *priv = priv(trans); | ||
| 366 | struct iwl_rxon_context *ctx; | ||
| 367 | int ret; | 319 | int ret; |
| 368 | 320 | ||
| 369 | if (!priv->tx_cmd_pool) | 321 | iwl_trans_fw_alive(trans(priv)); |
| 370 | priv->tx_cmd_pool = | ||
| 371 | kmem_cache_create("iwl_dev_cmd", | ||
| 372 | sizeof(struct iwl_device_cmd), | ||
| 373 | sizeof(void *), 0, NULL); | ||
| 374 | |||
| 375 | if (!priv->tx_cmd_pool) | ||
| 376 | return -ENOMEM; | ||
| 377 | 322 | ||
| 378 | iwl_trans_fw_alive(trans); | 323 | priv->passive_no_rx = false; |
| 379 | for_each_context(priv, ctx) | 324 | priv->transport_queue_stop = 0; |
| 380 | ctx->last_tx_rejected = false; | ||
| 381 | 325 | ||
| 382 | ret = iwl_send_wimax_coex(trans); | 326 | ret = iwl_send_wimax_coex(priv); |
| 383 | if (ret) | 327 | if (ret) |
| 384 | return ret; | 328 | return ret; |
| 385 | 329 | ||
| 386 | if (!cfg(priv)->no_xtal_calib) { | 330 | if (!cfg(priv)->no_xtal_calib) { |
| 387 | ret = iwl_set_Xtal_calib(trans); | 331 | ret = iwl_set_Xtal_calib(priv); |
| 388 | if (ret) | 332 | if (ret) |
| 389 | return ret; | 333 | return ret; |
| 390 | } | 334 | } |
| 391 | 335 | ||
| 392 | return iwl_send_calib_results(trans); | 336 | return iwl_send_calib_results(priv); |
| 393 | } | 337 | } |
| 394 | 338 | ||
| 395 | 339 | ||
| @@ -398,24 +342,23 @@ static int iwl_alive_notify(struct iwl_trans *trans) | |||
| 398 | * using sample data 100 bytes apart. If these sample points are good, | 342 | * using sample data 100 bytes apart. If these sample points are good, |
| 399 | * it's a pretty good bet that everything between them is good, too. | 343 | * it's a pretty good bet that everything between them is good, too. |
| 400 | */ | 344 | */ |
| 401 | static int iwl_verify_inst_sparse(struct iwl_nic *nic, | 345 | static int iwl_verify_inst_sparse(struct iwl_priv *priv, |
| 402 | struct fw_desc *fw_desc) | 346 | const struct fw_desc *fw_desc) |
| 403 | { | 347 | { |
| 404 | struct iwl_trans *trans = trans(nic); | ||
| 405 | __le32 *image = (__le32 *)fw_desc->v_addr; | 348 | __le32 *image = (__le32 *)fw_desc->v_addr; |
| 406 | u32 len = fw_desc->len; | 349 | u32 len = fw_desc->len; |
| 407 | u32 val; | 350 | u32 val; |
| 408 | u32 i; | 351 | u32 i; |
| 409 | 352 | ||
| 410 | IWL_DEBUG_FW(nic, "ucode inst image size is %u\n", len); | 353 | IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); |
| 411 | 354 | ||
| 412 | for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { | 355 | for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { |
| 413 | /* read data comes through single port, auto-incr addr */ | 356 | /* read data comes through single port, auto-incr addr */ |
| 414 | /* NOTE: Use the debugless read so we don't flood kernel log | 357 | /* NOTE: Use the debugless read so we don't flood kernel log |
| 415 | * if IWL_DL_IO is set */ | 358 | * if IWL_DL_IO is set */ |
| 416 | iwl_write_direct32(trans, HBUS_TARG_MEM_RADDR, | 359 | iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR, |
| 417 | i + IWLAGN_RTC_INST_LOWER_BOUND); | 360 | i + IWLAGN_RTC_INST_LOWER_BOUND); |
| 418 | val = iwl_read32(trans, HBUS_TARG_MEM_RDAT); | 361 | val = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
| 419 | if (val != le32_to_cpu(*image)) | 362 | if (val != le32_to_cpu(*image)) |
| 420 | return -EIO; | 363 | return -EIO; |
| 421 | } | 364 | } |
| @@ -423,28 +366,27 @@ static int iwl_verify_inst_sparse(struct iwl_nic *nic, | |||
| 423 | return 0; | 366 | return 0; |
| 424 | } | 367 | } |
| 425 | 368 | ||
| 426 | static void iwl_print_mismatch_inst(struct iwl_nic *nic, | 369 | static void iwl_print_mismatch_inst(struct iwl_priv *priv, |
| 427 | struct fw_desc *fw_desc) | 370 | const struct fw_desc *fw_desc) |
| 428 | { | 371 | { |
| 429 | struct iwl_trans *trans = trans(nic); | ||
| 430 | __le32 *image = (__le32 *)fw_desc->v_addr; | 372 | __le32 *image = (__le32 *)fw_desc->v_addr; |
| 431 | u32 len = fw_desc->len; | 373 | u32 len = fw_desc->len; |
| 432 | u32 val; | 374 | u32 val; |
| 433 | u32 offs; | 375 | u32 offs; |
| 434 | int errors = 0; | 376 | int errors = 0; |
| 435 | 377 | ||
| 436 | IWL_DEBUG_FW(nic, "ucode inst image size is %u\n", len); | 378 | IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); |
| 437 | 379 | ||
| 438 | iwl_write_direct32(trans, HBUS_TARG_MEM_RADDR, | 380 | iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR, |
| 439 | IWLAGN_RTC_INST_LOWER_BOUND); | 381 | IWLAGN_RTC_INST_LOWER_BOUND); |
| 440 | 382 | ||
| 441 | for (offs = 0; | 383 | for (offs = 0; |
| 442 | offs < len && errors < 20; | 384 | offs < len && errors < 20; |
| 443 | offs += sizeof(u32), image++) { | 385 | offs += sizeof(u32), image++) { |
| 444 | /* read data comes through single port, auto-incr addr */ | 386 | /* read data comes through single port, auto-incr addr */ |
| 445 | val = iwl_read32(trans, HBUS_TARG_MEM_RDAT); | 387 | val = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
| 446 | if (val != le32_to_cpu(*image)) { | 388 | if (val != le32_to_cpu(*image)) { |
| 447 | IWL_ERR(nic, "uCode INST section at " | 389 | IWL_ERR(priv, "uCode INST section at " |
| 448 | "offset 0x%x, is 0x%x, s/b 0x%x\n", | 390 | "offset 0x%x, is 0x%x, s/b 0x%x\n", |
| 449 | offs, val, le32_to_cpu(*image)); | 391 | offs, val, le32_to_cpu(*image)); |
| 450 | errors++; | 392 | errors++; |
| @@ -456,24 +398,24 @@ static void iwl_print_mismatch_inst(struct iwl_nic *nic, | |||
| 456 | * iwl_verify_ucode - determine which instruction image is in SRAM, | 398 | * iwl_verify_ucode - determine which instruction image is in SRAM, |
| 457 | * and verify its contents | 399 | * and verify its contents |
| 458 | */ | 400 | */ |
| 459 | static int iwl_verify_ucode(struct iwl_nic *nic, | 401 | static int iwl_verify_ucode(struct iwl_priv *priv, |
| 460 | enum iwl_ucode_type ucode_type) | 402 | enum iwl_ucode_type ucode_type) |
| 461 | { | 403 | { |
| 462 | struct fw_img *img = iwl_get_ucode_image(nic, ucode_type); | 404 | const struct fw_img *img = iwl_get_ucode_image(priv, ucode_type); |
| 463 | 405 | ||
| 464 | if (!img) { | 406 | if (!img) { |
| 465 | IWL_ERR(nic, "Invalid ucode requested (%d)\n", ucode_type); | 407 | IWL_ERR(priv, "Invalid ucode requested (%d)\n", ucode_type); |
| 466 | return -EINVAL; | 408 | return -EINVAL; |
| 467 | } | 409 | } |
| 468 | 410 | ||
| 469 | if (!iwl_verify_inst_sparse(nic, &img->code)) { | 411 | if (!iwl_verify_inst_sparse(priv, &img->code)) { |
| 470 | IWL_DEBUG_FW(nic, "uCode is good in inst SRAM\n"); | 412 | IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n"); |
| 471 | return 0; | 413 | return 0; |
| 472 | } | 414 | } |
| 473 | 415 | ||
| 474 | IWL_ERR(nic, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); | 416 | IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); |
| 475 | 417 | ||
| 476 | iwl_print_mismatch_inst(nic, &img->code); | 418 | iwl_print_mismatch_inst(priv, &img->code); |
| 477 | return -EIO; | 419 | return -EIO; |
| 478 | } | 420 | } |
| 479 | 421 | ||
| @@ -482,119 +424,57 @@ struct iwl_alive_data { | |||
| 482 | u8 subtype; | 424 | u8 subtype; |
| 483 | }; | 425 | }; |
| 484 | 426 | ||
| 485 | static void iwl_alive_fn(struct iwl_trans *trans, | 427 | static void iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, |
| 486 | struct iwl_rx_packet *pkt, | 428 | struct iwl_rx_packet *pkt, |
| 487 | void *data) | 429 | void *data) |
| 488 | { | 430 | { |
| 431 | struct iwl_priv *priv = | ||
| 432 | container_of(notif_wait, struct iwl_priv, notif_wait); | ||
| 489 | struct iwl_alive_data *alive_data = data; | 433 | struct iwl_alive_data *alive_data = data; |
| 490 | struct iwl_alive_resp *palive; | 434 | struct iwl_alive_resp *palive; |
| 491 | 435 | ||
| 492 | palive = &pkt->u.alive_frame; | 436 | palive = (void *)pkt->data; |
| 493 | 437 | ||
| 494 | IWL_DEBUG_FW(trans, "Alive ucode status 0x%08X revision " | 438 | IWL_DEBUG_FW(priv, "Alive ucode status 0x%08X revision " |
| 495 | "0x%01X 0x%01X\n", | 439 | "0x%01X 0x%01X\n", |
| 496 | palive->is_valid, palive->ver_type, | 440 | palive->is_valid, palive->ver_type, |
| 497 | palive->ver_subtype); | 441 | palive->ver_subtype); |
| 498 | 442 | ||
| 499 | trans->shrd->device_pointers.error_event_table = | 443 | priv->shrd->device_pointers.error_event_table = |
| 500 | le32_to_cpu(palive->error_event_table_ptr); | 444 | le32_to_cpu(palive->error_event_table_ptr); |
| 501 | trans->shrd->device_pointers.log_event_table = | 445 | priv->shrd->device_pointers.log_event_table = |
| 502 | le32_to_cpu(palive->log_event_table_ptr); | 446 | le32_to_cpu(palive->log_event_table_ptr); |
| 503 | 447 | ||
| 504 | alive_data->subtype = palive->ver_subtype; | 448 | alive_data->subtype = palive->ver_subtype; |
| 505 | alive_data->valid = palive->is_valid == UCODE_VALID_OK; | 449 | alive_data->valid = palive->is_valid == UCODE_VALID_OK; |
| 506 | } | 450 | } |
| 507 | 451 | ||
| 508 | /* notification wait support */ | ||
| 509 | void iwl_init_notification_wait(struct iwl_shared *shrd, | ||
| 510 | struct iwl_notification_wait *wait_entry, | ||
| 511 | u8 cmd, | ||
| 512 | void (*fn)(struct iwl_trans *trans, | ||
| 513 | struct iwl_rx_packet *pkt, | ||
| 514 | void *data), | ||
| 515 | void *fn_data) | ||
| 516 | { | ||
| 517 | wait_entry->fn = fn; | ||
| 518 | wait_entry->fn_data = fn_data; | ||
| 519 | wait_entry->cmd = cmd; | ||
| 520 | wait_entry->triggered = false; | ||
| 521 | wait_entry->aborted = false; | ||
| 522 | |||
| 523 | spin_lock_bh(&shrd->notif_wait_lock); | ||
| 524 | list_add(&wait_entry->list, &shrd->notif_waits); | ||
| 525 | spin_unlock_bh(&shrd->notif_wait_lock); | ||
| 526 | } | ||
| 527 | |||
| 528 | int iwl_wait_notification(struct iwl_shared *shrd, | ||
| 529 | struct iwl_notification_wait *wait_entry, | ||
| 530 | unsigned long timeout) | ||
| 531 | { | ||
| 532 | int ret; | ||
| 533 | |||
| 534 | ret = wait_event_timeout(shrd->notif_waitq, | ||
| 535 | wait_entry->triggered || wait_entry->aborted, | ||
| 536 | timeout); | ||
| 537 | |||
| 538 | spin_lock_bh(&shrd->notif_wait_lock); | ||
| 539 | list_del(&wait_entry->list); | ||
| 540 | spin_unlock_bh(&shrd->notif_wait_lock); | ||
| 541 | |||
| 542 | if (wait_entry->aborted) | ||
| 543 | return -EIO; | ||
| 544 | |||
| 545 | /* return value is always >= 0 */ | ||
| 546 | if (ret <= 0) | ||
| 547 | return -ETIMEDOUT; | ||
| 548 | return 0; | ||
| 549 | } | ||
| 550 | |||
| 551 | void iwl_remove_notification(struct iwl_shared *shrd, | ||
| 552 | struct iwl_notification_wait *wait_entry) | ||
| 553 | { | ||
| 554 | spin_lock_bh(&shrd->notif_wait_lock); | ||
| 555 | list_del(&wait_entry->list); | ||
| 556 | spin_unlock_bh(&shrd->notif_wait_lock); | ||
| 557 | } | ||
| 558 | |||
| 559 | void iwl_abort_notification_waits(struct iwl_shared *shrd) | ||
| 560 | { | ||
| 561 | unsigned long flags; | ||
| 562 | struct iwl_notification_wait *wait_entry; | ||
| 563 | |||
| 564 | spin_lock_irqsave(&shrd->notif_wait_lock, flags); | ||
| 565 | list_for_each_entry(wait_entry, &shrd->notif_waits, list) | ||
| 566 | wait_entry->aborted = true; | ||
| 567 | spin_unlock_irqrestore(&shrd->notif_wait_lock, flags); | ||
| 568 | |||
| 569 | wake_up_all(&shrd->notif_waitq); | ||
| 570 | } | ||
| 571 | |||
| 572 | #define UCODE_ALIVE_TIMEOUT HZ | 452 | #define UCODE_ALIVE_TIMEOUT HZ |
| 573 | #define UCODE_CALIB_TIMEOUT (2*HZ) | 453 | #define UCODE_CALIB_TIMEOUT (2*HZ) |
| 574 | 454 | ||
| 575 | int iwl_load_ucode_wait_alive(struct iwl_trans *trans, | 455 | int iwl_load_ucode_wait_alive(struct iwl_priv *priv, |
| 576 | enum iwl_ucode_type ucode_type) | 456 | enum iwl_ucode_type ucode_type) |
| 577 | { | 457 | { |
| 578 | struct iwl_notification_wait alive_wait; | 458 | struct iwl_notification_wait alive_wait; |
| 579 | struct iwl_alive_data alive_data; | 459 | struct iwl_alive_data alive_data; |
| 580 | struct fw_img *fw; | 460 | const struct fw_img *fw; |
| 581 | int ret; | 461 | int ret; |
| 582 | enum iwl_ucode_type old_type; | 462 | enum iwl_ucode_type old_type; |
| 583 | 463 | ||
| 584 | iwl_init_notification_wait(trans->shrd, &alive_wait, REPLY_ALIVE, | 464 | old_type = priv->shrd->ucode_type; |
| 585 | iwl_alive_fn, &alive_data); | 465 | priv->shrd->ucode_type = ucode_type; |
| 586 | 466 | fw = iwl_get_ucode_image(priv, ucode_type); | |
| 587 | old_type = trans->shrd->ucode_type; | ||
| 588 | trans->shrd->ucode_type = ucode_type; | ||
| 589 | fw = iwl_get_ucode_image(nic(trans), ucode_type); | ||
| 590 | 467 | ||
| 591 | if (!fw) | 468 | if (!fw) |
| 592 | return -EINVAL; | 469 | return -EINVAL; |
| 593 | 470 | ||
| 594 | ret = iwl_trans_start_fw(trans, fw); | 471 | iwl_init_notification_wait(&priv->notif_wait, &alive_wait, REPLY_ALIVE, |
| 472 | iwl_alive_fn, &alive_data); | ||
| 473 | |||
| 474 | ret = iwl_trans_start_fw(trans(priv), fw); | ||
| 595 | if (ret) { | 475 | if (ret) { |
| 596 | trans->shrd->ucode_type = old_type; | 476 | priv->shrd->ucode_type = old_type; |
| 597 | iwl_remove_notification(trans->shrd, &alive_wait); | 477 | iwl_remove_notification(&priv->notif_wait, &alive_wait); |
| 598 | return ret; | 478 | return ret; |
| 599 | } | 479 | } |
| 600 | 480 | ||
| @@ -602,16 +482,16 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans, | |||
| 602 | * Some things may run in the background now, but we | 482 | * Some things may run in the background now, but we |
| 603 | * just wait for the ALIVE notification here. | 483 | * just wait for the ALIVE notification here. |
| 604 | */ | 484 | */ |
| 605 | ret = iwl_wait_notification(trans->shrd, &alive_wait, | 485 | ret = iwl_wait_notification(&priv->notif_wait, &alive_wait, |
| 606 | UCODE_ALIVE_TIMEOUT); | 486 | UCODE_ALIVE_TIMEOUT); |
| 607 | if (ret) { | 487 | if (ret) { |
| 608 | trans->shrd->ucode_type = old_type; | 488 | priv->shrd->ucode_type = old_type; |
| 609 | return ret; | 489 | return ret; |
| 610 | } | 490 | } |
| 611 | 491 | ||
| 612 | if (!alive_data.valid) { | 492 | if (!alive_data.valid) { |
| 613 | IWL_ERR(trans, "Loaded ucode is not valid!\n"); | 493 | IWL_ERR(priv, "Loaded ucode is not valid!\n"); |
| 614 | trans->shrd->ucode_type = old_type; | 494 | priv->shrd->ucode_type = old_type; |
| 615 | return -EIO; | 495 | return -EIO; |
| 616 | } | 496 | } |
| 617 | 497 | ||
| @@ -621,9 +501,9 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans, | |||
| 621 | * skip it for WoWLAN. | 501 | * skip it for WoWLAN. |
| 622 | */ | 502 | */ |
| 623 | if (ucode_type != IWL_UCODE_WOWLAN) { | 503 | if (ucode_type != IWL_UCODE_WOWLAN) { |
| 624 | ret = iwl_verify_ucode(nic(trans), ucode_type); | 504 | ret = iwl_verify_ucode(priv, ucode_type); |
| 625 | if (ret) { | 505 | if (ret) { |
| 626 | trans->shrd->ucode_type = old_type; | 506 | priv->shrd->ucode_type = old_type; |
| 627 | return ret; | 507 | return ret; |
| 628 | } | 508 | } |
| 629 | 509 | ||
| @@ -631,41 +511,41 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans, | |||
| 631 | msleep(5); | 511 | msleep(5); |
| 632 | } | 512 | } |
| 633 | 513 | ||
| 634 | ret = iwl_alive_notify(trans); | 514 | ret = iwl_alive_notify(priv); |
| 635 | if (ret) { | 515 | if (ret) { |
| 636 | IWL_WARN(trans, | 516 | IWL_WARN(priv, |
| 637 | "Could not complete ALIVE transition: %d\n", ret); | 517 | "Could not complete ALIVE transition: %d\n", ret); |
| 638 | trans->shrd->ucode_type = old_type; | 518 | priv->shrd->ucode_type = old_type; |
| 639 | return ret; | 519 | return ret; |
| 640 | } | 520 | } |
| 641 | 521 | ||
| 642 | return 0; | 522 | return 0; |
| 643 | } | 523 | } |
| 644 | 524 | ||
| 645 | int iwl_run_init_ucode(struct iwl_trans *trans) | 525 | int iwl_run_init_ucode(struct iwl_priv *priv) |
| 646 | { | 526 | { |
| 647 | struct iwl_notification_wait calib_wait; | 527 | struct iwl_notification_wait calib_wait; |
| 648 | int ret; | 528 | int ret; |
| 649 | 529 | ||
| 650 | lockdep_assert_held(&trans->shrd->mutex); | 530 | lockdep_assert_held(&priv->mutex); |
| 651 | 531 | ||
| 652 | /* No init ucode required? Curious, but maybe ok */ | 532 | /* No init ucode required? Curious, but maybe ok */ |
| 653 | if (!nic(trans)->fw.ucode_init.code.len) | 533 | if (!priv->fw->ucode_init.code.len) |
| 654 | return 0; | 534 | return 0; |
| 655 | 535 | ||
| 656 | if (trans->shrd->ucode_type != IWL_UCODE_NONE) | 536 | if (priv->shrd->ucode_type != IWL_UCODE_NONE) |
| 657 | return 0; | 537 | return 0; |
| 658 | 538 | ||
| 659 | iwl_init_notification_wait(trans->shrd, &calib_wait, | 539 | iwl_init_notification_wait(&priv->notif_wait, &calib_wait, |
| 660 | CALIBRATION_COMPLETE_NOTIFICATION, | 540 | CALIBRATION_COMPLETE_NOTIFICATION, |
| 661 | NULL, NULL); | 541 | NULL, NULL); |
| 662 | 542 | ||
| 663 | /* Will also start the device */ | 543 | /* Will also start the device */ |
| 664 | ret = iwl_load_ucode_wait_alive(trans, IWL_UCODE_INIT); | 544 | ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT); |
| 665 | if (ret) | 545 | if (ret) |
| 666 | goto error; | 546 | goto error; |
| 667 | 547 | ||
| 668 | ret = iwl_init_alive_start(trans); | 548 | ret = iwl_init_alive_start(priv); |
| 669 | if (ret) | 549 | if (ret) |
| 670 | goto error; | 550 | goto error; |
| 671 | 551 | ||
| @@ -673,594 +553,15 @@ int iwl_run_init_ucode(struct iwl_trans *trans) | |||
| 673 | * Some things may run in the background now, but we | 553 | * Some things may run in the background now, but we |
| 674 | * just wait for the calibration complete notification. | 554 | * just wait for the calibration complete notification. |
| 675 | */ | 555 | */ |
| 676 | ret = iwl_wait_notification(trans->shrd, &calib_wait, | 556 | ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, |
| 677 | UCODE_CALIB_TIMEOUT); | 557 | UCODE_CALIB_TIMEOUT); |
| 678 | 558 | ||
| 679 | goto out; | 559 | goto out; |
| 680 | 560 | ||
| 681 | error: | 561 | error: |
| 682 | iwl_remove_notification(trans->shrd, &calib_wait); | 562 | iwl_remove_notification(&priv->notif_wait, &calib_wait); |
| 683 | out: | 563 | out: |
| 684 | /* Whatever happened, stop the device */ | 564 | /* Whatever happened, stop the device */ |
| 685 | iwl_trans_stop_device(trans); | 565 | iwl_trans_stop_device(trans(priv)); |
| 686 | return ret; | 566 | return ret; |
| 687 | } | 567 | } |
| 688 | |||
| 689 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); | ||
| 690 | |||
| 691 | #define UCODE_EXPERIMENTAL_TAG "exp" | ||
| 692 | |||
| 693 | int __must_check iwl_request_firmware(struct iwl_nic *nic, bool first) | ||
| 694 | { | ||
| 695 | struct iwl_cfg *cfg = cfg(nic); | ||
| 696 | const char *name_pre = cfg->fw_name_pre; | ||
| 697 | char tag[8]; | ||
| 698 | |||
| 699 | if (first) { | ||
| 700 | #ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE | ||
| 701 | nic->fw_index = UCODE_EXPERIMENTAL_INDEX; | ||
| 702 | strcpy(tag, UCODE_EXPERIMENTAL_TAG); | ||
| 703 | } else if (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) { | ||
| 704 | #endif | ||
| 705 | nic->fw_index = cfg->ucode_api_max; | ||
| 706 | sprintf(tag, "%d", nic->fw_index); | ||
| 707 | } else { | ||
| 708 | nic->fw_index--; | ||
| 709 | sprintf(tag, "%d", nic->fw_index); | ||
| 710 | } | ||
| 711 | |||
| 712 | if (nic->fw_index < cfg->ucode_api_min) { | ||
| 713 | IWL_ERR(nic, "no suitable firmware found!\n"); | ||
| 714 | return -ENOENT; | ||
| 715 | } | ||
| 716 | |||
| 717 | sprintf(nic->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); | ||
| 718 | |||
| 719 | IWL_DEBUG_INFO(nic, "attempting to load firmware %s'%s'\n", | ||
| 720 | (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) | ||
| 721 | ? "EXPERIMENTAL " : "", | ||
| 722 | nic->firmware_name); | ||
| 723 | |||
| 724 | return request_firmware_nowait(THIS_MODULE, 1, nic->firmware_name, | ||
| 725 | trans(nic)->dev, | ||
| 726 | GFP_KERNEL, nic, iwl_ucode_callback); | ||
| 727 | } | ||
| 728 | |||
| 729 | struct iwlagn_firmware_pieces { | ||
| 730 | const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data; | ||
| 731 | size_t inst_size, data_size, init_size, init_data_size, | ||
| 732 | wowlan_inst_size, wowlan_data_size; | ||
| 733 | |||
| 734 | u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; | ||
| 735 | u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; | ||
| 736 | }; | ||
| 737 | |||
| 738 | static int iwl_parse_v1_v2_firmware(struct iwl_nic *nic, | ||
| 739 | const struct firmware *ucode_raw, | ||
| 740 | struct iwlagn_firmware_pieces *pieces) | ||
| 741 | { | ||
| 742 | struct iwl_ucode_header *ucode = (void *)ucode_raw->data; | ||
| 743 | u32 api_ver, hdr_size, build; | ||
| 744 | char buildstr[25]; | ||
| 745 | const u8 *src; | ||
| 746 | |||
| 747 | nic->fw.ucode_ver = le32_to_cpu(ucode->ver); | ||
| 748 | api_ver = IWL_UCODE_API(nic->fw.ucode_ver); | ||
| 749 | |||
| 750 | switch (api_ver) { | ||
| 751 | default: | ||
| 752 | hdr_size = 28; | ||
| 753 | if (ucode_raw->size < hdr_size) { | ||
| 754 | IWL_ERR(nic, "File size too small!\n"); | ||
| 755 | return -EINVAL; | ||
| 756 | } | ||
| 757 | build = le32_to_cpu(ucode->u.v2.build); | ||
| 758 | pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); | ||
| 759 | pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); | ||
| 760 | pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); | ||
| 761 | pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size); | ||
| 762 | src = ucode->u.v2.data; | ||
| 763 | break; | ||
| 764 | case 0: | ||
| 765 | case 1: | ||
| 766 | case 2: | ||
| 767 | hdr_size = 24; | ||
| 768 | if (ucode_raw->size < hdr_size) { | ||
| 769 | IWL_ERR(nic, "File size too small!\n"); | ||
| 770 | return -EINVAL; | ||
| 771 | } | ||
| 772 | build = 0; | ||
| 773 | pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size); | ||
| 774 | pieces->data_size = le32_to_cpu(ucode->u.v1.data_size); | ||
| 775 | pieces->init_size = le32_to_cpu(ucode->u.v1.init_size); | ||
| 776 | pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size); | ||
| 777 | src = ucode->u.v1.data; | ||
| 778 | break; | ||
| 779 | } | ||
| 780 | |||
| 781 | if (build) | ||
| 782 | sprintf(buildstr, " build %u%s", build, | ||
| 783 | (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) | ||
| 784 | ? " (EXP)" : ""); | ||
| 785 | else | ||
| 786 | buildstr[0] = '\0'; | ||
| 787 | |||
| 788 | snprintf(nic->fw.fw_version, | ||
| 789 | sizeof(nic->fw.fw_version), | ||
| 790 | "%u.%u.%u.%u%s", | ||
| 791 | IWL_UCODE_MAJOR(nic->fw.ucode_ver), | ||
| 792 | IWL_UCODE_MINOR(nic->fw.ucode_ver), | ||
| 793 | IWL_UCODE_API(nic->fw.ucode_ver), | ||
| 794 | IWL_UCODE_SERIAL(nic->fw.ucode_ver), | ||
| 795 | buildstr); | ||
| 796 | |||
| 797 | /* Verify size of file vs. image size info in file's header */ | ||
| 798 | if (ucode_raw->size != hdr_size + pieces->inst_size + | ||
| 799 | pieces->data_size + pieces->init_size + | ||
| 800 | pieces->init_data_size) { | ||
| 801 | |||
| 802 | IWL_ERR(nic, | ||
| 803 | "uCode file size %d does not match expected size\n", | ||
| 804 | (int)ucode_raw->size); | ||
| 805 | return -EINVAL; | ||
| 806 | } | ||
| 807 | |||
| 808 | pieces->inst = src; | ||
| 809 | src += pieces->inst_size; | ||
| 810 | pieces->data = src; | ||
| 811 | src += pieces->data_size; | ||
| 812 | pieces->init = src; | ||
| 813 | src += pieces->init_size; | ||
| 814 | pieces->init_data = src; | ||
| 815 | src += pieces->init_data_size; | ||
| 816 | |||
| 817 | return 0; | ||
| 818 | } | ||
| 819 | |||
| 820 | static int iwl_parse_tlv_firmware(struct iwl_nic *nic, | ||
| 821 | const struct firmware *ucode_raw, | ||
| 822 | struct iwlagn_firmware_pieces *pieces, | ||
| 823 | struct iwl_ucode_capabilities *capa) | ||
| 824 | { | ||
| 825 | struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data; | ||
| 826 | struct iwl_ucode_tlv *tlv; | ||
| 827 | size_t len = ucode_raw->size; | ||
| 828 | const u8 *data; | ||
| 829 | int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative; | ||
| 830 | int tmp; | ||
| 831 | u64 alternatives; | ||
| 832 | u32 tlv_len; | ||
| 833 | enum iwl_ucode_tlv_type tlv_type; | ||
| 834 | const u8 *tlv_data; | ||
| 835 | char buildstr[25]; | ||
| 836 | u32 build; | ||
| 837 | |||
| 838 | if (len < sizeof(*ucode)) { | ||
| 839 | IWL_ERR(nic, "uCode has invalid length: %zd\n", len); | ||
| 840 | return -EINVAL; | ||
| 841 | } | ||
| 842 | |||
| 843 | if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { | ||
| 844 | IWL_ERR(nic, "invalid uCode magic: 0X%x\n", | ||
| 845 | le32_to_cpu(ucode->magic)); | ||
| 846 | return -EINVAL; | ||
| 847 | } | ||
| 848 | |||
| 849 | /* | ||
| 850 | * Check which alternatives are present, and "downgrade" | ||
| 851 | * when the chosen alternative is not present, warning | ||
| 852 | * the user when that happens. Some files may not have | ||
| 853 | * any alternatives, so don't warn in that case. | ||
| 854 | */ | ||
| 855 | alternatives = le64_to_cpu(ucode->alternatives); | ||
| 856 | tmp = wanted_alternative; | ||
| 857 | if (wanted_alternative > 63) | ||
| 858 | wanted_alternative = 63; | ||
| 859 | while (wanted_alternative && !(alternatives & BIT(wanted_alternative))) | ||
| 860 | wanted_alternative--; | ||
| 861 | if (wanted_alternative && wanted_alternative != tmp) | ||
| 862 | IWL_WARN(nic, | ||
| 863 | "uCode alternative %d not available, choosing %d\n", | ||
| 864 | tmp, wanted_alternative); | ||
| 865 | |||
| 866 | nic->fw.ucode_ver = le32_to_cpu(ucode->ver); | ||
| 867 | build = le32_to_cpu(ucode->build); | ||
| 868 | |||
| 869 | if (build) | ||
| 870 | sprintf(buildstr, " build %u%s", build, | ||
| 871 | (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) | ||
| 872 | ? " (EXP)" : ""); | ||
| 873 | else | ||
| 874 | buildstr[0] = '\0'; | ||
| 875 | |||
| 876 | snprintf(nic->fw.fw_version, | ||
| 877 | sizeof(nic->fw.fw_version), | ||
| 878 | "%u.%u.%u.%u%s", | ||
| 879 | IWL_UCODE_MAJOR(nic->fw.ucode_ver), | ||
| 880 | IWL_UCODE_MINOR(nic->fw.ucode_ver), | ||
| 881 | IWL_UCODE_API(nic->fw.ucode_ver), | ||
| 882 | IWL_UCODE_SERIAL(nic->fw.ucode_ver), | ||
| 883 | buildstr); | ||
| 884 | |||
| 885 | data = ucode->data; | ||
| 886 | |||
| 887 | len -= sizeof(*ucode); | ||
| 888 | |||
| 889 | while (len >= sizeof(*tlv)) { | ||
| 890 | u16 tlv_alt; | ||
| 891 | |||
| 892 | len -= sizeof(*tlv); | ||
| 893 | tlv = (void *)data; | ||
| 894 | |||
| 895 | tlv_len = le32_to_cpu(tlv->length); | ||
| 896 | tlv_type = le16_to_cpu(tlv->type); | ||
| 897 | tlv_alt = le16_to_cpu(tlv->alternative); | ||
| 898 | tlv_data = tlv->data; | ||
| 899 | |||
| 900 | if (len < tlv_len) { | ||
| 901 | IWL_ERR(nic, "invalid TLV len: %zd/%u\n", | ||
| 902 | len, tlv_len); | ||
| 903 | return -EINVAL; | ||
| 904 | } | ||
| 905 | len -= ALIGN(tlv_len, 4); | ||
| 906 | data += sizeof(*tlv) + ALIGN(tlv_len, 4); | ||
| 907 | |||
| 908 | /* | ||
| 909 | * Alternative 0 is always valid. | ||
| 910 | * | ||
| 911 | * Skip alternative TLVs that are not selected. | ||
| 912 | */ | ||
| 913 | if (tlv_alt != 0 && tlv_alt != wanted_alternative) | ||
| 914 | continue; | ||
| 915 | |||
| 916 | switch (tlv_type) { | ||
| 917 | case IWL_UCODE_TLV_INST: | ||
| 918 | pieces->inst = tlv_data; | ||
| 919 | pieces->inst_size = tlv_len; | ||
| 920 | break; | ||
| 921 | case IWL_UCODE_TLV_DATA: | ||
| 922 | pieces->data = tlv_data; | ||
| 923 | pieces->data_size = tlv_len; | ||
| 924 | break; | ||
| 925 | case IWL_UCODE_TLV_INIT: | ||
| 926 | pieces->init = tlv_data; | ||
| 927 | pieces->init_size = tlv_len; | ||
| 928 | break; | ||
| 929 | case IWL_UCODE_TLV_INIT_DATA: | ||
| 930 | pieces->init_data = tlv_data; | ||
| 931 | pieces->init_data_size = tlv_len; | ||
| 932 | break; | ||
| 933 | case IWL_UCODE_TLV_BOOT: | ||
| 934 | IWL_ERR(nic, "Found unexpected BOOT ucode\n"); | ||
| 935 | break; | ||
| 936 | case IWL_UCODE_TLV_PROBE_MAX_LEN: | ||
| 937 | if (tlv_len != sizeof(u32)) | ||
| 938 | goto invalid_tlv_len; | ||
| 939 | capa->max_probe_length = | ||
| 940 | le32_to_cpup((__le32 *)tlv_data); | ||
| 941 | break; | ||
| 942 | case IWL_UCODE_TLV_PAN: | ||
| 943 | if (tlv_len) | ||
| 944 | goto invalid_tlv_len; | ||
| 945 | capa->flags |= IWL_UCODE_TLV_FLAGS_PAN; | ||
| 946 | break; | ||
| 947 | case IWL_UCODE_TLV_FLAGS: | ||
| 948 | /* must be at least one u32 */ | ||
| 949 | if (tlv_len < sizeof(u32)) | ||
| 950 | goto invalid_tlv_len; | ||
| 951 | /* and a proper number of u32s */ | ||
| 952 | if (tlv_len % sizeof(u32)) | ||
| 953 | goto invalid_tlv_len; | ||
| 954 | /* | ||
| 955 | * This driver only reads the first u32 as | ||
| 956 | * right now no more features are defined, | ||
| 957 | * if that changes then either the driver | ||
| 958 | * will not work with the new firmware, or | ||
| 959 | * it'll not take advantage of new features. | ||
| 960 | */ | ||
| 961 | capa->flags = le32_to_cpup((__le32 *)tlv_data); | ||
| 962 | break; | ||
| 963 | case IWL_UCODE_TLV_INIT_EVTLOG_PTR: | ||
| 964 | if (tlv_len != sizeof(u32)) | ||
| 965 | goto invalid_tlv_len; | ||
| 966 | pieces->init_evtlog_ptr = | ||
| 967 | le32_to_cpup((__le32 *)tlv_data); | ||
| 968 | break; | ||
| 969 | case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: | ||
| 970 | if (tlv_len != sizeof(u32)) | ||
| 971 | goto invalid_tlv_len; | ||
| 972 | pieces->init_evtlog_size = | ||
| 973 | le32_to_cpup((__le32 *)tlv_data); | ||
| 974 | break; | ||
| 975 | case IWL_UCODE_TLV_INIT_ERRLOG_PTR: | ||
| 976 | if (tlv_len != sizeof(u32)) | ||
| 977 | goto invalid_tlv_len; | ||
| 978 | pieces->init_errlog_ptr = | ||
| 979 | le32_to_cpup((__le32 *)tlv_data); | ||
| 980 | break; | ||
| 981 | case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: | ||
| 982 | if (tlv_len != sizeof(u32)) | ||
| 983 | goto invalid_tlv_len; | ||
| 984 | pieces->inst_evtlog_ptr = | ||
| 985 | le32_to_cpup((__le32 *)tlv_data); | ||
| 986 | break; | ||
| 987 | case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: | ||
| 988 | if (tlv_len != sizeof(u32)) | ||
| 989 | goto invalid_tlv_len; | ||
| 990 | pieces->inst_evtlog_size = | ||
| 991 | le32_to_cpup((__le32 *)tlv_data); | ||
| 992 | break; | ||
| 993 | case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: | ||
| 994 | if (tlv_len != sizeof(u32)) | ||
| 995 | goto invalid_tlv_len; | ||
| 996 | pieces->inst_errlog_ptr = | ||
| 997 | le32_to_cpup((__le32 *)tlv_data); | ||
| 998 | break; | ||
| 999 | case IWL_UCODE_TLV_ENHANCE_SENS_TBL: | ||
| 1000 | if (tlv_len) | ||
| 1001 | goto invalid_tlv_len; | ||
| 1002 | nic->fw.enhance_sensitivity_table = true; | ||
| 1003 | break; | ||
| 1004 | case IWL_UCODE_TLV_WOWLAN_INST: | ||
| 1005 | pieces->wowlan_inst = tlv_data; | ||
| 1006 | pieces->wowlan_inst_size = tlv_len; | ||
| 1007 | break; | ||
| 1008 | case IWL_UCODE_TLV_WOWLAN_DATA: | ||
| 1009 | pieces->wowlan_data = tlv_data; | ||
| 1010 | pieces->wowlan_data_size = tlv_len; | ||
| 1011 | break; | ||
| 1012 | case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: | ||
| 1013 | if (tlv_len != sizeof(u32)) | ||
| 1014 | goto invalid_tlv_len; | ||
| 1015 | capa->standard_phy_calibration_size = | ||
| 1016 | le32_to_cpup((__le32 *)tlv_data); | ||
| 1017 | break; | ||
| 1018 | default: | ||
| 1019 | IWL_DEBUG_INFO(nic, "unknown TLV: %d\n", tlv_type); | ||
| 1020 | break; | ||
| 1021 | } | ||
| 1022 | } | ||
| 1023 | |||
| 1024 | if (len) { | ||
| 1025 | IWL_ERR(nic, "invalid TLV after parsing: %zd\n", len); | ||
| 1026 | iwl_print_hex_dump(nic, IWL_DL_FW, (u8 *)data, len); | ||
| 1027 | return -EINVAL; | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | return 0; | ||
| 1031 | |||
| 1032 | invalid_tlv_len: | ||
| 1033 | IWL_ERR(nic, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); | ||
| 1034 | iwl_print_hex_dump(nic, IWL_DL_FW, tlv_data, tlv_len); | ||
| 1035 | |||
| 1036 | return -EINVAL; | ||
| 1037 | } | ||
| 1038 | |||
| 1039 | /** | ||
| 1040 | * iwl_ucode_callback - callback when firmware was loaded | ||
| 1041 | * | ||
| 1042 | * If loaded successfully, copies the firmware into buffers | ||
| 1043 | * for the card to fetch (via DMA). | ||
| 1044 | */ | ||
| 1045 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | ||
| 1046 | { | ||
| 1047 | struct iwl_nic *nic = context; | ||
| 1048 | struct iwl_cfg *cfg = cfg(nic); | ||
| 1049 | struct iwl_fw *fw = &nic->fw; | ||
| 1050 | struct iwl_ucode_header *ucode; | ||
| 1051 | int err; | ||
| 1052 | struct iwlagn_firmware_pieces pieces; | ||
| 1053 | const unsigned int api_max = cfg->ucode_api_max; | ||
| 1054 | unsigned int api_ok = cfg->ucode_api_ok; | ||
| 1055 | const unsigned int api_min = cfg->ucode_api_min; | ||
| 1056 | u32 api_ver; | ||
| 1057 | |||
| 1058 | fw->ucode_capa.max_probe_length = 200; | ||
| 1059 | fw->ucode_capa.standard_phy_calibration_size = | ||
| 1060 | IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE; | ||
| 1061 | |||
| 1062 | if (!api_ok) | ||
| 1063 | api_ok = api_max; | ||
| 1064 | |||
| 1065 | memset(&pieces, 0, sizeof(pieces)); | ||
| 1066 | |||
| 1067 | if (!ucode_raw) { | ||
| 1068 | if (nic->fw_index <= api_ok) | ||
| 1069 | IWL_ERR(nic, | ||
| 1070 | "request for firmware file '%s' failed.\n", | ||
| 1071 | nic->firmware_name); | ||
| 1072 | goto try_again; | ||
| 1073 | } | ||
| 1074 | |||
| 1075 | IWL_DEBUG_INFO(nic, "Loaded firmware file '%s' (%zd bytes).\n", | ||
| 1076 | nic->firmware_name, ucode_raw->size); | ||
| 1077 | |||
| 1078 | /* Make sure that we got at least the API version number */ | ||
| 1079 | if (ucode_raw->size < 4) { | ||
| 1080 | IWL_ERR(nic, "File size way too small!\n"); | ||
| 1081 | goto try_again; | ||
| 1082 | } | ||
| 1083 | |||
| 1084 | /* Data from ucode file: header followed by uCode images */ | ||
| 1085 | ucode = (struct iwl_ucode_header *)ucode_raw->data; | ||
| 1086 | |||
| 1087 | if (ucode->ver) | ||
| 1088 | err = iwl_parse_v1_v2_firmware(nic, ucode_raw, &pieces); | ||
| 1089 | else | ||
| 1090 | err = iwl_parse_tlv_firmware(nic, ucode_raw, &pieces, | ||
| 1091 | &fw->ucode_capa); | ||
| 1092 | |||
| 1093 | if (err) | ||
| 1094 | goto try_again; | ||
| 1095 | |||
| 1096 | api_ver = IWL_UCODE_API(nic->fw.ucode_ver); | ||
| 1097 | |||
| 1098 | /* | ||
| 1099 | * api_ver should match the api version forming part of the | ||
| 1100 | * firmware filename ... but we don't check for that and only rely | ||
| 1101 | * on the API version read from firmware header from here on forward | ||
| 1102 | */ | ||
| 1103 | /* no api version check required for experimental uCode */ | ||
| 1104 | if (nic->fw_index != UCODE_EXPERIMENTAL_INDEX) { | ||
| 1105 | if (api_ver < api_min || api_ver > api_max) { | ||
| 1106 | IWL_ERR(nic, | ||
| 1107 | "Driver unable to support your firmware API. " | ||
| 1108 | "Driver supports v%u, firmware is v%u.\n", | ||
| 1109 | api_max, api_ver); | ||
| 1110 | goto try_again; | ||
| 1111 | } | ||
| 1112 | |||
| 1113 | if (api_ver < api_ok) { | ||
| 1114 | if (api_ok != api_max) | ||
| 1115 | IWL_ERR(nic, "Firmware has old API version, " | ||
| 1116 | "expected v%u through v%u, got v%u.\n", | ||
| 1117 | api_ok, api_max, api_ver); | ||
| 1118 | else | ||
| 1119 | IWL_ERR(nic, "Firmware has old API version, " | ||
| 1120 | "expected v%u, got v%u.\n", | ||
| 1121 | api_max, api_ver); | ||
| 1122 | IWL_ERR(nic, "New firmware can be obtained from " | ||
| 1123 | "http://www.intellinuxwireless.org/.\n"); | ||
| 1124 | } | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | IWL_INFO(nic, "loaded firmware version %s", nic->fw.fw_version); | ||
| 1128 | |||
| 1129 | /* | ||
| 1130 | * For any of the failures below (before allocating pci memory) | ||
| 1131 | * we will try to load a version with a smaller API -- maybe the | ||
| 1132 | * user just got a corrupted version of the latest API. | ||
| 1133 | */ | ||
| 1134 | |||
| 1135 | IWL_DEBUG_INFO(nic, "f/w package hdr ucode version raw = 0x%x\n", | ||
| 1136 | nic->fw.ucode_ver); | ||
| 1137 | IWL_DEBUG_INFO(nic, "f/w package hdr runtime inst size = %Zd\n", | ||
| 1138 | pieces.inst_size); | ||
| 1139 | IWL_DEBUG_INFO(nic, "f/w package hdr runtime data size = %Zd\n", | ||
| 1140 | pieces.data_size); | ||
| 1141 | IWL_DEBUG_INFO(nic, "f/w package hdr init inst size = %Zd\n", | ||
| 1142 | pieces.init_size); | ||
| 1143 | IWL_DEBUG_INFO(nic, "f/w package hdr init data size = %Zd\n", | ||
| 1144 | pieces.init_data_size); | ||
| 1145 | |||
| 1146 | /* Verify that uCode images will fit in card's SRAM */ | ||
| 1147 | if (pieces.inst_size > cfg->max_inst_size) { | ||
| 1148 | IWL_ERR(nic, "uCode instr len %Zd too large to fit in\n", | ||
| 1149 | pieces.inst_size); | ||
| 1150 | goto try_again; | ||
| 1151 | } | ||
| 1152 | |||
| 1153 | if (pieces.data_size > cfg->max_data_size) { | ||
| 1154 | IWL_ERR(nic, "uCode data len %Zd too large to fit in\n", | ||
| 1155 | pieces.data_size); | ||
| 1156 | goto try_again; | ||
| 1157 | } | ||
| 1158 | |||
| 1159 | if (pieces.init_size > cfg->max_inst_size) { | ||
| 1160 | IWL_ERR(nic, "uCode init instr len %Zd too large to fit in\n", | ||
| 1161 | pieces.init_size); | ||
| 1162 | goto try_again; | ||
| 1163 | } | ||
| 1164 | |||
| 1165 | if (pieces.init_data_size > cfg->max_data_size) { | ||
| 1166 | IWL_ERR(nic, "uCode init data len %Zd too large to fit in\n", | ||
| 1167 | pieces.init_data_size); | ||
| 1168 | goto try_again; | ||
| 1169 | } | ||
| 1170 | |||
| 1171 | /* Allocate ucode buffers for card's bus-master loading ... */ | ||
| 1172 | |||
| 1173 | /* Runtime instructions and 2 copies of data: | ||
| 1174 | * 1) unmodified from disk | ||
| 1175 | * 2) backup cache for save/restore during power-downs */ | ||
| 1176 | if (iwl_alloc_fw_desc(nic, &nic->fw.ucode_rt.code, | ||
| 1177 | pieces.inst, pieces.inst_size)) | ||
| 1178 | goto err_pci_alloc; | ||
| 1179 | if (iwl_alloc_fw_desc(nic, &nic->fw.ucode_rt.data, | ||
| 1180 | pieces.data, pieces.data_size)) | ||
| 1181 | goto err_pci_alloc; | ||
| 1182 | |||
| 1183 | /* Initialization instructions and data */ | ||
| 1184 | if (pieces.init_size && pieces.init_data_size) { | ||
| 1185 | if (iwl_alloc_fw_desc(nic, | ||
| 1186 | &nic->fw.ucode_init.code, | ||
| 1187 | pieces.init, pieces.init_size)) | ||
| 1188 | goto err_pci_alloc; | ||
| 1189 | if (iwl_alloc_fw_desc(nic, | ||
| 1190 | &nic->fw.ucode_init.data, | ||
| 1191 | pieces.init_data, pieces.init_data_size)) | ||
| 1192 | goto err_pci_alloc; | ||
| 1193 | } | ||
| 1194 | |||
| 1195 | /* WoWLAN instructions and data */ | ||
| 1196 | if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { | ||
| 1197 | if (iwl_alloc_fw_desc(nic, | ||
| 1198 | &nic->fw.ucode_wowlan.code, | ||
| 1199 | pieces.wowlan_inst, | ||
| 1200 | pieces.wowlan_inst_size)) | ||
| 1201 | goto err_pci_alloc; | ||
| 1202 | if (iwl_alloc_fw_desc(nic, | ||
| 1203 | &nic->fw.ucode_wowlan.data, | ||
| 1204 | pieces.wowlan_data, | ||
| 1205 | pieces.wowlan_data_size)) | ||
| 1206 | goto err_pci_alloc; | ||
| 1207 | } | ||
| 1208 | |||
| 1209 | /* Now that we can no longer fail, copy information */ | ||
| 1210 | |||
| 1211 | /* | ||
| 1212 | * The (size - 16) / 12 formula is based on the information recorded | ||
| 1213 | * for each event, which is of mode 1 (including timestamp) for all | ||
| 1214 | * new microcodes that include this information. | ||
| 1215 | */ | ||
| 1216 | nic->init_evtlog_ptr = pieces.init_evtlog_ptr; | ||
| 1217 | if (pieces.init_evtlog_size) | ||
| 1218 | nic->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; | ||
| 1219 | else | ||
| 1220 | nic->init_evtlog_size = | ||
| 1221 | cfg->base_params->max_event_log_size; | ||
| 1222 | nic->init_errlog_ptr = pieces.init_errlog_ptr; | ||
| 1223 | nic->inst_evtlog_ptr = pieces.inst_evtlog_ptr; | ||
| 1224 | if (pieces.inst_evtlog_size) | ||
| 1225 | nic->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; | ||
| 1226 | else | ||
| 1227 | nic->inst_evtlog_size = | ||
| 1228 | cfg->base_params->max_event_log_size; | ||
| 1229 | nic->inst_errlog_ptr = pieces.inst_errlog_ptr; | ||
| 1230 | |||
| 1231 | /* | ||
| 1232 | * figure out the offset of chain noise reset and gain commands | ||
| 1233 | * base on the size of standard phy calibration commands table size | ||
| 1234 | */ | ||
| 1235 | if (fw->ucode_capa.standard_phy_calibration_size > | ||
| 1236 | IWL_MAX_PHY_CALIBRATE_TBL_SIZE) | ||
| 1237 | fw->ucode_capa.standard_phy_calibration_size = | ||
| 1238 | IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; | ||
| 1239 | |||
| 1240 | /* We have our copies now, allow OS release its copies */ | ||
| 1241 | release_firmware(ucode_raw); | ||
| 1242 | complete(&nic->request_firmware_complete); | ||
| 1243 | |||
| 1244 | nic->op_mode = iwl_dvm_ops.start(nic->shrd->trans); | ||
| 1245 | |||
| 1246 | if (!nic->op_mode) | ||
| 1247 | goto out_unbind; | ||
| 1248 | |||
| 1249 | return; | ||
| 1250 | |||
| 1251 | try_again: | ||
| 1252 | /* try next, if any */ | ||
| 1253 | release_firmware(ucode_raw); | ||
| 1254 | if (iwl_request_firmware(nic, false)) | ||
| 1255 | goto out_unbind; | ||
| 1256 | return; | ||
| 1257 | |||
| 1258 | err_pci_alloc: | ||
| 1259 | IWL_ERR(nic, "failed to allocate pci memory\n"); | ||
| 1260 | iwl_dealloc_ucode(nic); | ||
| 1261 | release_firmware(ucode_raw); | ||
| 1262 | out_unbind: | ||
| 1263 | complete(&nic->request_firmware_complete); | ||
| 1264 | device_release_driver(trans(nic)->dev); | ||
| 1265 | } | ||
| 1266 | |||
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index ba16f05df0fc..b4f6cb3298a4 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/etherdevice.h> | 27 | #include <linux/etherdevice.h> |
| 28 | #include <linux/debugfs.h> | 28 | #include <linux/debugfs.h> |
| 29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
| 30 | #include <linux/ktime.h> | ||
| 30 | #include <net/genetlink.h> | 31 | #include <net/genetlink.h> |
| 31 | #include "mac80211_hwsim.h" | 32 | #include "mac80211_hwsim.h" |
| 32 | 33 | ||
| @@ -321,11 +322,15 @@ struct mac80211_hwsim_data { | |||
| 321 | struct dentry *debugfs_group; | 322 | struct dentry *debugfs_group; |
| 322 | 323 | ||
| 323 | int power_level; | 324 | int power_level; |
| 325 | |||
| 326 | /* difference between this hw's clock and the real clock, in usecs */ | ||
| 327 | u64 tsf_offset; | ||
| 324 | }; | 328 | }; |
| 325 | 329 | ||
| 326 | 330 | ||
| 327 | struct hwsim_radiotap_hdr { | 331 | struct hwsim_radiotap_hdr { |
| 328 | struct ieee80211_radiotap_header hdr; | 332 | struct ieee80211_radiotap_header hdr; |
| 333 | __le64 rt_tsft; | ||
| 329 | u8 rt_flags; | 334 | u8 rt_flags; |
| 330 | u8 rt_rate; | 335 | u8 rt_rate; |
| 331 | __le16 rt_channel; | 336 | __le16 rt_channel; |
| @@ -367,6 +372,28 @@ static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb, | |||
| 367 | return NETDEV_TX_OK; | 372 | return NETDEV_TX_OK; |
| 368 | } | 373 | } |
| 369 | 374 | ||
| 375 | static __le64 __mac80211_hwsim_get_tsf(struct mac80211_hwsim_data *data) | ||
| 376 | { | ||
| 377 | struct timeval tv = ktime_to_timeval(ktime_get_real()); | ||
| 378 | u64 now = tv.tv_sec * USEC_PER_SEC + tv.tv_usec; | ||
| 379 | return cpu_to_le64(now + data->tsf_offset); | ||
| 380 | } | ||
| 381 | |||
| 382 | static u64 mac80211_hwsim_get_tsf(struct ieee80211_hw *hw, | ||
| 383 | struct ieee80211_vif *vif) | ||
| 384 | { | ||
| 385 | struct mac80211_hwsim_data *data = hw->priv; | ||
| 386 | return le64_to_cpu(__mac80211_hwsim_get_tsf(data)); | ||
| 387 | } | ||
| 388 | |||
| 389 | static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw, | ||
| 390 | struct ieee80211_vif *vif, u64 tsf) | ||
| 391 | { | ||
| 392 | struct mac80211_hwsim_data *data = hw->priv; | ||
| 393 | struct timeval tv = ktime_to_timeval(ktime_get_real()); | ||
| 394 | u64 now = tv.tv_sec * USEC_PER_SEC + tv.tv_usec; | ||
| 395 | data->tsf_offset = tsf - now; | ||
| 396 | } | ||
| 370 | 397 | ||
| 371 | static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, | 398 | static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, |
| 372 | struct sk_buff *tx_skb) | 399 | struct sk_buff *tx_skb) |
| @@ -391,7 +418,9 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, | |||
| 391 | hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr)); | 418 | hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr)); |
| 392 | hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | 419 | hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | |
| 393 | (1 << IEEE80211_RADIOTAP_RATE) | | 420 | (1 << IEEE80211_RADIOTAP_RATE) | |
| 421 | (1 << IEEE80211_RADIOTAP_TSFT) | | ||
| 394 | (1 << IEEE80211_RADIOTAP_CHANNEL)); | 422 | (1 << IEEE80211_RADIOTAP_CHANNEL)); |
| 423 | hdr->rt_tsft = __mac80211_hwsim_get_tsf(data); | ||
| 395 | hdr->rt_flags = 0; | 424 | hdr->rt_flags = 0; |
| 396 | hdr->rt_rate = txrate->bitrate / 5; | 425 | hdr->rt_rate = txrate->bitrate / 5; |
| 397 | hdr->rt_channel = cpu_to_le16(data->channel->center_freq); | 426 | hdr->rt_channel = cpu_to_le16(data->channel->center_freq); |
| @@ -610,7 +639,8 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, | |||
| 610 | } | 639 | } |
| 611 | 640 | ||
| 612 | memset(&rx_status, 0, sizeof(rx_status)); | 641 | memset(&rx_status, 0, sizeof(rx_status)); |
| 613 | /* TODO: set mactime */ | 642 | rx_status.mactime = le64_to_cpu(__mac80211_hwsim_get_tsf(data)); |
| 643 | rx_status.flag |= RX_FLAG_MACTIME_MPDU; | ||
| 614 | rx_status.freq = data->channel->center_freq; | 644 | rx_status.freq = data->channel->center_freq; |
| 615 | rx_status.band = data->channel->band; | 645 | rx_status.band = data->channel->band; |
| 616 | rx_status.rate_idx = info->control.rates[0].idx; | 646 | rx_status.rate_idx = info->control.rates[0].idx; |
| @@ -667,6 +697,12 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 667 | bool ack; | 697 | bool ack; |
| 668 | struct ieee80211_tx_info *txi; | 698 | struct ieee80211_tx_info *txi; |
| 669 | u32 _pid; | 699 | u32 _pid; |
| 700 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data; | ||
| 701 | struct mac80211_hwsim_data *data = hw->priv; | ||
| 702 | |||
| 703 | if (ieee80211_is_beacon(mgmt->frame_control) || | ||
| 704 | ieee80211_is_probe_resp(mgmt->frame_control)) | ||
| 705 | mgmt->u.beacon.timestamp = __mac80211_hwsim_get_tsf(data); | ||
| 670 | 706 | ||
| 671 | mac80211_hwsim_monitor_rx(hw, skb); | 707 | mac80211_hwsim_monitor_rx(hw, skb); |
| 672 | 708 | ||
| @@ -763,9 +799,11 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, | |||
| 763 | struct ieee80211_vif *vif) | 799 | struct ieee80211_vif *vif) |
| 764 | { | 800 | { |
| 765 | struct ieee80211_hw *hw = arg; | 801 | struct ieee80211_hw *hw = arg; |
| 802 | struct mac80211_hwsim_data *data = hw->priv; | ||
| 766 | struct sk_buff *skb; | 803 | struct sk_buff *skb; |
| 767 | struct ieee80211_tx_info *info; | 804 | struct ieee80211_tx_info *info; |
| 768 | u32 _pid; | 805 | u32 _pid; |
| 806 | struct ieee80211_mgmt *mgmt; | ||
| 769 | 807 | ||
| 770 | hwsim_check_magic(vif); | 808 | hwsim_check_magic(vif); |
| 771 | 809 | ||
| @@ -779,6 +817,9 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, | |||
| 779 | return; | 817 | return; |
| 780 | info = IEEE80211_SKB_CB(skb); | 818 | info = IEEE80211_SKB_CB(skb); |
| 781 | 819 | ||
| 820 | mgmt = (struct ieee80211_mgmt *) skb->data; | ||
| 821 | mgmt->u.beacon.timestamp = __mac80211_hwsim_get_tsf(data); | ||
| 822 | |||
| 782 | mac80211_hwsim_monitor_rx(hw, skb); | 823 | mac80211_hwsim_monitor_rx(hw, skb); |
| 783 | 824 | ||
| 784 | /* wmediumd mode check */ | 825 | /* wmediumd mode check */ |
| @@ -1199,6 +1240,8 @@ static struct ieee80211_ops mac80211_hwsim_ops = | |||
| 1199 | .sw_scan_start = mac80211_hwsim_sw_scan, | 1240 | .sw_scan_start = mac80211_hwsim_sw_scan, |
| 1200 | .sw_scan_complete = mac80211_hwsim_sw_scan_complete, | 1241 | .sw_scan_complete = mac80211_hwsim_sw_scan_complete, |
| 1201 | .flush = mac80211_hwsim_flush, | 1242 | .flush = mac80211_hwsim_flush, |
| 1243 | .get_tsf = mac80211_hwsim_get_tsf, | ||
| 1244 | .set_tsf = mac80211_hwsim_set_tsf, | ||
| 1202 | }; | 1245 | }; |
| 1203 | 1246 | ||
| 1204 | 1247 | ||
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index a460fb0cc503..84508b065265 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
| @@ -613,7 +613,6 @@ static struct ieee80211_rate mwifiex_rates[] = { | |||
| 613 | {.bitrate = 20, .hw_value = 4, }, | 613 | {.bitrate = 20, .hw_value = 4, }, |
| 614 | {.bitrate = 55, .hw_value = 11, }, | 614 | {.bitrate = 55, .hw_value = 11, }, |
| 615 | {.bitrate = 110, .hw_value = 22, }, | 615 | {.bitrate = 110, .hw_value = 22, }, |
| 616 | {.bitrate = 220, .hw_value = 44, }, | ||
| 617 | {.bitrate = 60, .hw_value = 12, }, | 616 | {.bitrate = 60, .hw_value = 12, }, |
| 618 | {.bitrate = 90, .hw_value = 18, }, | 617 | {.bitrate = 90, .hw_value = 18, }, |
| 619 | {.bitrate = 120, .hw_value = 24, }, | 618 | {.bitrate = 120, .hw_value = 24, }, |
| @@ -622,7 +621,6 @@ static struct ieee80211_rate mwifiex_rates[] = { | |||
| 622 | {.bitrate = 360, .hw_value = 72, }, | 621 | {.bitrate = 360, .hw_value = 72, }, |
| 623 | {.bitrate = 480, .hw_value = 96, }, | 622 | {.bitrate = 480, .hw_value = 96, }, |
| 624 | {.bitrate = 540, .hw_value = 108, }, | 623 | {.bitrate = 540, .hw_value = 108, }, |
| 625 | {.bitrate = 720, .hw_value = 144, }, | ||
| 626 | }; | 624 | }; |
| 627 | 625 | ||
| 628 | /* Channel definitions to be advertised to cfg80211 */ | 626 | /* Channel definitions to be advertised to cfg80211 */ |
| @@ -648,7 +646,7 @@ static struct ieee80211_supported_band mwifiex_band_2ghz = { | |||
| 648 | .channels = mwifiex_channels_2ghz, | 646 | .channels = mwifiex_channels_2ghz, |
| 649 | .n_channels = ARRAY_SIZE(mwifiex_channels_2ghz), | 647 | .n_channels = ARRAY_SIZE(mwifiex_channels_2ghz), |
| 650 | .bitrates = mwifiex_rates, | 648 | .bitrates = mwifiex_rates, |
| 651 | .n_bitrates = 14, | 649 | .n_bitrates = ARRAY_SIZE(mwifiex_rates), |
| 652 | }; | 650 | }; |
| 653 | 651 | ||
| 654 | static struct ieee80211_channel mwifiex_channels_5ghz[] = { | 652 | static struct ieee80211_channel mwifiex_channels_5ghz[] = { |
| @@ -688,8 +686,8 @@ static struct ieee80211_channel mwifiex_channels_5ghz[] = { | |||
| 688 | static struct ieee80211_supported_band mwifiex_band_5ghz = { | 686 | static struct ieee80211_supported_band mwifiex_band_5ghz = { |
| 689 | .channels = mwifiex_channels_5ghz, | 687 | .channels = mwifiex_channels_5ghz, |
| 690 | .n_channels = ARRAY_SIZE(mwifiex_channels_5ghz), | 688 | .n_channels = ARRAY_SIZE(mwifiex_channels_5ghz), |
| 691 | .bitrates = mwifiex_rates - 4, | 689 | .bitrates = mwifiex_rates + 4, |
| 692 | .n_bitrates = ARRAY_SIZE(mwifiex_rates) + 4, | 690 | .n_bitrates = ARRAY_SIZE(mwifiex_rates) - 4, |
| 693 | }; | 691 | }; |
| 694 | 692 | ||
| 695 | 693 | ||
| @@ -841,12 +839,12 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
| 841 | u8 *bssid, int mode, struct ieee80211_channel *channel, | 839 | u8 *bssid, int mode, struct ieee80211_channel *channel, |
| 842 | struct cfg80211_connect_params *sme, bool privacy) | 840 | struct cfg80211_connect_params *sme, bool privacy) |
| 843 | { | 841 | { |
| 844 | struct mwifiex_802_11_ssid req_ssid; | 842 | struct cfg80211_ssid req_ssid; |
| 845 | int ret, auth_type = 0; | 843 | int ret, auth_type = 0; |
| 846 | struct cfg80211_bss *bss = NULL; | 844 | struct cfg80211_bss *bss = NULL; |
| 847 | u8 is_scanning_required = 0; | 845 | u8 is_scanning_required = 0; |
| 848 | 846 | ||
| 849 | memset(&req_ssid, 0, sizeof(struct mwifiex_802_11_ssid)); | 847 | memset(&req_ssid, 0, sizeof(struct cfg80211_ssid)); |
| 850 | 848 | ||
| 851 | req_ssid.ssid_len = ssid_len; | 849 | req_ssid.ssid_len = ssid_len; |
| 852 | if (ssid_len > IEEE80211_MAX_SSID_LEN) { | 850 | if (ssid_len > IEEE80211_MAX_SSID_LEN) { |
| @@ -873,6 +871,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
| 873 | priv->sec_info.wpa2_enabled = false; | 871 | priv->sec_info.wpa2_enabled = false; |
| 874 | priv->wep_key_curr_index = 0; | 872 | priv->wep_key_curr_index = 0; |
| 875 | priv->sec_info.encryption_mode = 0; | 873 | priv->sec_info.encryption_mode = 0; |
| 874 | priv->sec_info.is_authtype_auto = 0; | ||
| 876 | ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); | 875 | ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); |
| 877 | 876 | ||
| 878 | if (mode == NL80211_IFTYPE_ADHOC) { | 877 | if (mode == NL80211_IFTYPE_ADHOC) { |
| @@ -894,11 +893,12 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
| 894 | } | 893 | } |
| 895 | 894 | ||
| 896 | /* Now handle infra mode. "sme" is valid for infra mode only */ | 895 | /* Now handle infra mode. "sme" is valid for infra mode only */ |
| 897 | if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC | 896 | if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) { |
| 898 | || sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) | ||
| 899 | auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM; | 897 | auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM; |
| 900 | else if (sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) | 898 | priv->sec_info.is_authtype_auto = 1; |
| 901 | auth_type = NL80211_AUTHTYPE_SHARED_KEY; | 899 | } else { |
| 900 | auth_type = sme->auth_type; | ||
| 901 | } | ||
| 902 | 902 | ||
| 903 | if (sme->crypto.n_ciphers_pairwise) { | 903 | if (sme->crypto.n_ciphers_pairwise) { |
| 904 | priv->sec_info.encryption_mode = | 904 | priv->sec_info.encryption_mode = |
| @@ -1106,12 +1106,10 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, | |||
| 1106 | dev_err(priv->adapter->dev, "failed to alloc scan_req\n"); | 1106 | dev_err(priv->adapter->dev, "failed to alloc scan_req\n"); |
| 1107 | return -ENOMEM; | 1107 | return -ENOMEM; |
| 1108 | } | 1108 | } |
| 1109 | for (i = 0; i < request->n_ssids; i++) { | 1109 | |
| 1110 | memcpy(priv->user_scan_cfg->ssid_list[i].ssid, | 1110 | priv->user_scan_cfg->num_ssids = request->n_ssids; |
| 1111 | request->ssids[i].ssid, request->ssids[i].ssid_len); | 1111 | priv->user_scan_cfg->ssid_list = request->ssids; |
| 1112 | priv->user_scan_cfg->ssid_list[i].max_len = | 1112 | |
| 1113 | request->ssids[i].ssid_len; | ||
| 1114 | } | ||
| 1115 | for (i = 0; i < request->n_channels; i++) { | 1113 | for (i = 0; i < request->n_channels; i++) { |
| 1116 | chan = request->channels[i]; | 1114 | chan = request->channels[i]; |
| 1117 | priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value; | 1115 | priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value; |
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 6623db69e157..c82eb7ff2fa2 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c | |||
| @@ -771,7 +771,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
| 771 | 771 | ||
| 772 | /* Check init command response */ | 772 | /* Check init command response */ |
| 773 | if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) { | 773 | if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) { |
| 774 | if (ret == -1) { | 774 | if (ret) { |
| 775 | dev_err(adapter->dev, "%s: cmd %#x failed during " | 775 | dev_err(adapter->dev, "%s: cmd %#x failed during " |
| 776 | "initialization\n", __func__, cmdresp_no); | 776 | "initialization\n", __func__, cmdresp_no); |
| 777 | mwifiex_init_fw_complete(adapter); | 777 | mwifiex_init_fw_complete(adapter); |
| @@ -781,10 +781,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
| 781 | } | 781 | } |
| 782 | 782 | ||
| 783 | if (adapter->curr_cmd) { | 783 | if (adapter->curr_cmd) { |
| 784 | if (adapter->curr_cmd->wait_q_enabled && (!ret)) | 784 | if (adapter->curr_cmd->wait_q_enabled) |
| 785 | adapter->cmd_wait_q.status = 0; | 785 | adapter->cmd_wait_q.status = ret; |
| 786 | else if (adapter->curr_cmd->wait_q_enabled && (ret == -1)) | ||
| 787 | adapter->cmd_wait_q.status = -1; | ||
| 788 | 786 | ||
| 789 | /* Clean up and put current command back to cmd_free_q */ | 787 | /* Clean up and put current command back to cmd_free_q */ |
| 790 | mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); | 788 | mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); |
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index 3735c775495c..be5fd1652e53 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h | |||
| @@ -91,11 +91,6 @@ struct mwifiex_fw_image { | |||
| 91 | u32 fw_len; | 91 | u32 fw_len; |
| 92 | }; | 92 | }; |
| 93 | 93 | ||
| 94 | struct mwifiex_802_11_ssid { | ||
| 95 | u32 ssid_len; | ||
| 96 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | ||
| 97 | }; | ||
| 98 | |||
| 99 | struct mwifiex_wait_queue { | 94 | struct mwifiex_wait_queue { |
| 100 | wait_queue_head_t wait; | 95 | wait_queue_head_t wait; |
| 101 | int status; | 96 | int status; |
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index c82620094a53..fc4ffee6c6b9 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h | |||
| @@ -852,11 +852,6 @@ struct mwifiex_user_scan_chan { | |||
| 852 | u32 scan_time; | 852 | u32 scan_time; |
| 853 | } __packed; | 853 | } __packed; |
| 854 | 854 | ||
| 855 | struct mwifiex_user_scan_ssid { | ||
| 856 | u8 ssid[IEEE80211_MAX_SSID_LEN + 1]; | ||
| 857 | u8 max_len; | ||
| 858 | } __packed; | ||
| 859 | |||
| 860 | struct mwifiex_user_scan_cfg { | 855 | struct mwifiex_user_scan_cfg { |
| 861 | /* | 856 | /* |
| 862 | * BSS mode to be sent in the firmware command | 857 | * BSS mode to be sent in the firmware command |
| @@ -867,8 +862,9 @@ struct mwifiex_user_scan_cfg { | |||
| 867 | u8 reserved; | 862 | u8 reserved; |
| 868 | /* BSSID filter sent in the firmware command to limit the results */ | 863 | /* BSSID filter sent in the firmware command to limit the results */ |
| 869 | u8 specific_bssid[ETH_ALEN]; | 864 | u8 specific_bssid[ETH_ALEN]; |
| 870 | /* SSID filter list used in the to limit the scan results */ | 865 | /* SSID filter list used in the firmware to limit the scan results */ |
| 871 | struct mwifiex_user_scan_ssid ssid_list[MWIFIEX_MAX_SSID_LIST_LENGTH]; | 866 | struct cfg80211_ssid *ssid_list; |
| 867 | u8 num_ssids; | ||
| 872 | /* Variable number (fixed maximum) of channels to scan up */ | 868 | /* Variable number (fixed maximum) of channels to scan up */ |
| 873 | struct mwifiex_user_scan_chan chan_list[MWIFIEX_USER_SCAN_CHAN_MAX]; | 869 | struct mwifiex_user_scan_chan chan_list[MWIFIEX_USER_SCAN_CHAN_MAX]; |
| 874 | } __packed; | 870 | } __packed; |
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h index d5d81f1fe41c..7ca4e8234f3e 100644 --- a/drivers/net/wireless/mwifiex/ioctl.h +++ b/drivers/net/wireless/mwifiex/ioctl.h | |||
| @@ -50,7 +50,7 @@ struct mwifiex_chan_freq { | |||
| 50 | }; | 50 | }; |
| 51 | 51 | ||
| 52 | struct mwifiex_ssid_bssid { | 52 | struct mwifiex_ssid_bssid { |
| 53 | struct mwifiex_802_11_ssid ssid; | 53 | struct cfg80211_ssid ssid; |
| 54 | u8 bssid[ETH_ALEN]; | 54 | u8 bssid[ETH_ALEN]; |
| 55 | }; | 55 | }; |
| 56 | 56 | ||
| @@ -122,7 +122,7 @@ struct mwifiex_ver_ext { | |||
| 122 | 122 | ||
| 123 | struct mwifiex_bss_info { | 123 | struct mwifiex_bss_info { |
| 124 | u32 bss_mode; | 124 | u32 bss_mode; |
| 125 | struct mwifiex_802_11_ssid ssid; | 125 | struct cfg80211_ssid ssid; |
| 126 | u32 bss_chan; | 126 | u32 bss_chan; |
| 127 | u32 region_code; | 127 | u32 region_code; |
| 128 | u32 media_connected; | 128 | u32 media_connected; |
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index ee439fc2f4f3..bce9991612c8 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c | |||
| @@ -585,7 +585,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, | |||
| 585 | le16_to_cpu(assoc_rsp->cap_info_bitmap), | 585 | le16_to_cpu(assoc_rsp->cap_info_bitmap), |
| 586 | le16_to_cpu(assoc_rsp->a_id)); | 586 | le16_to_cpu(assoc_rsp->a_id)); |
| 587 | 587 | ||
| 588 | ret = -1; | 588 | ret = le16_to_cpu(assoc_rsp->status_code); |
| 589 | goto done; | 589 | goto done; |
| 590 | } | 590 | } |
| 591 | 591 | ||
| @@ -714,7 +714,7 @@ done: | |||
| 714 | int | 714 | int |
| 715 | mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | 715 | mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, |
| 716 | struct host_cmd_ds_command *cmd, | 716 | struct host_cmd_ds_command *cmd, |
| 717 | struct mwifiex_802_11_ssid *req_ssid) | 717 | struct cfg80211_ssid *req_ssid) |
| 718 | { | 718 | { |
| 719 | int rsn_ie_len = 0; | 719 | int rsn_ie_len = 0; |
| 720 | struct mwifiex_adapter *adapter = priv->adapter; | 720 | struct mwifiex_adapter *adapter = priv->adapter; |
| @@ -1245,7 +1245,7 @@ int mwifiex_associate(struct mwifiex_private *priv, | |||
| 1245 | */ | 1245 | */ |
| 1246 | int | 1246 | int |
| 1247 | mwifiex_adhoc_start(struct mwifiex_private *priv, | 1247 | mwifiex_adhoc_start(struct mwifiex_private *priv, |
| 1248 | struct mwifiex_802_11_ssid *adhoc_ssid) | 1248 | struct cfg80211_ssid *adhoc_ssid) |
| 1249 | { | 1249 | { |
| 1250 | dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n", | 1250 | dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n", |
| 1251 | priv->adhoc_channel); | 1251 | priv->adhoc_channel); |
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 4c8621706278..6dc116647411 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
| @@ -219,6 +219,7 @@ struct mwifiex_802_11_security { | |||
| 219 | u8 wapi_key_on; | 219 | u8 wapi_key_on; |
| 220 | u8 wep_enabled; | 220 | u8 wep_enabled; |
| 221 | u32 authentication_mode; | 221 | u32 authentication_mode; |
| 222 | u8 is_authtype_auto; | ||
| 222 | u32 encryption_mode; | 223 | u32 encryption_mode; |
| 223 | }; | 224 | }; |
| 224 | 225 | ||
| @@ -243,7 +244,7 @@ struct ieee_types_generic { | |||
| 243 | 244 | ||
| 244 | struct mwifiex_bssdescriptor { | 245 | struct mwifiex_bssdescriptor { |
| 245 | u8 mac_address[ETH_ALEN]; | 246 | u8 mac_address[ETH_ALEN]; |
| 246 | struct mwifiex_802_11_ssid ssid; | 247 | struct cfg80211_ssid ssid; |
| 247 | u32 privacy; | 248 | u32 privacy; |
| 248 | s32 rssi; | 249 | s32 rssi; |
| 249 | u32 channel; | 250 | u32 channel; |
| @@ -387,7 +388,7 @@ struct mwifiex_private { | |||
| 387 | s16 bcn_rssi_avg; | 388 | s16 bcn_rssi_avg; |
| 388 | s16 bcn_nf_avg; | 389 | s16 bcn_nf_avg; |
| 389 | struct mwifiex_bssdescriptor *attempted_bss_desc; | 390 | struct mwifiex_bssdescriptor *attempted_bss_desc; |
| 390 | struct mwifiex_802_11_ssid prev_ssid; | 391 | struct cfg80211_ssid prev_ssid; |
| 391 | u8 prev_bssid[ETH_ALEN]; | 392 | u8 prev_bssid[ETH_ALEN]; |
| 392 | struct mwifiex_current_bss_params curr_bss_params; | 393 | struct mwifiex_current_bss_params curr_bss_params; |
| 393 | u16 beacon_period; | 394 | u16 beacon_period; |
| @@ -746,8 +747,7 @@ void mwifiex_queue_scan_cmd(struct mwifiex_private *priv, | |||
| 746 | struct cmd_ctrl_node *cmd_node); | 747 | struct cmd_ctrl_node *cmd_node); |
| 747 | int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | 748 | int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, |
| 748 | struct host_cmd_ds_command *resp); | 749 | struct host_cmd_ds_command *resp); |
| 749 | s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, | 750 | s32 mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2); |
| 750 | struct mwifiex_802_11_ssid *ssid2); | ||
| 751 | int mwifiex_associate(struct mwifiex_private *priv, | 751 | int mwifiex_associate(struct mwifiex_private *priv, |
| 752 | struct mwifiex_bssdescriptor *bss_desc); | 752 | struct mwifiex_bssdescriptor *bss_desc); |
| 753 | int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, | 753 | int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, |
| @@ -759,12 +759,12 @@ void mwifiex_reset_connect_state(struct mwifiex_private *priv); | |||
| 759 | u8 mwifiex_band_to_radio_type(u8 band); | 759 | u8 mwifiex_band_to_radio_type(u8 band); |
| 760 | int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac); | 760 | int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac); |
| 761 | int mwifiex_adhoc_start(struct mwifiex_private *priv, | 761 | int mwifiex_adhoc_start(struct mwifiex_private *priv, |
| 762 | struct mwifiex_802_11_ssid *adhoc_ssid); | 762 | struct cfg80211_ssid *adhoc_ssid); |
| 763 | int mwifiex_adhoc_join(struct mwifiex_private *priv, | 763 | int mwifiex_adhoc_join(struct mwifiex_private *priv, |
| 764 | struct mwifiex_bssdescriptor *bss_desc); | 764 | struct mwifiex_bssdescriptor *bss_desc); |
| 765 | int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | 765 | int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, |
| 766 | struct host_cmd_ds_command *cmd, | 766 | struct host_cmd_ds_command *cmd, |
| 767 | struct mwifiex_802_11_ssid *req_ssid); | 767 | struct cfg80211_ssid *req_ssid); |
| 768 | int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, | 768 | int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, |
| 769 | struct host_cmd_ds_command *cmd, | 769 | struct host_cmd_ds_command *cmd, |
| 770 | struct mwifiex_bssdescriptor *bss_desc); | 770 | struct mwifiex_bssdescriptor *bss_desc); |
| @@ -897,7 +897,7 @@ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, | |||
| 897 | struct net_device *dev); | 897 | struct net_device *dev); |
| 898 | int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter); | 898 | int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter); |
| 899 | int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, | 899 | int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, |
| 900 | struct mwifiex_802_11_ssid *req_ssid); | 900 | struct cfg80211_ssid *req_ssid); |
| 901 | int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); | 901 | int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); |
| 902 | int mwifiex_enable_hs(struct mwifiex_adapter *adapter); | 902 | int mwifiex_enable_hs(struct mwifiex_adapter *adapter); |
| 903 | int mwifiex_disable_auto_ds(struct mwifiex_private *priv); | 903 | int mwifiex_disable_auto_ds(struct mwifiex_private *priv); |
| @@ -906,13 +906,12 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv, | |||
| 906 | int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, | 906 | int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, |
| 907 | struct mwifiex_rate_cfg *rate); | 907 | struct mwifiex_rate_cfg *rate); |
| 908 | int mwifiex_request_scan(struct mwifiex_private *priv, | 908 | int mwifiex_request_scan(struct mwifiex_private *priv, |
| 909 | struct mwifiex_802_11_ssid *req_ssid); | 909 | struct cfg80211_ssid *req_ssid); |
| 910 | int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, | 910 | int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, |
| 911 | struct mwifiex_user_scan_cfg *scan_req); | 911 | struct mwifiex_user_scan_cfg *scan_req); |
| 912 | int mwifiex_change_adhoc_chan(struct mwifiex_private *priv, int channel); | ||
| 913 | int mwifiex_set_radio(struct mwifiex_private *priv, u8 option); | 912 | int mwifiex_set_radio(struct mwifiex_private *priv, u8 option); |
| 914 | 913 | ||
| 915 | int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel); | 914 | int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel); |
| 916 | 915 | ||
| 917 | int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, | 916 | int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, |
| 918 | int key_len, u8 key_index, int disable); | 917 | int key_len, u8 key_index, int disable); |
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 8f10038d1b45..fd0302fe5bd8 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
| @@ -163,8 +163,7 @@ mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) | |||
| 163 | * This function compares two SSIDs and checks if they match. | 163 | * This function compares two SSIDs and checks if they match. |
| 164 | */ | 164 | */ |
| 165 | s32 | 165 | s32 |
| 166 | mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, | 166 | mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2) |
| 167 | struct mwifiex_802_11_ssid *ssid2) | ||
| 168 | { | 167 | { |
| 169 | if (!ssid1 || !ssid2 || (ssid1->ssid_len != ssid2->ssid_len)) | 168 | if (!ssid1 || !ssid2 || (ssid1->ssid_len != ssid2->ssid_len)) |
| 170 | return -1; | 169 | return -1; |
| @@ -738,7 +737,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
| 738 | u16 scan_dur; | 737 | u16 scan_dur; |
| 739 | u8 channel; | 738 | u8 channel; |
| 740 | u8 radio_type; | 739 | u8 radio_type; |
| 741 | u32 ssid_idx; | 740 | int i; |
| 742 | u8 ssid_filter; | 741 | u8 ssid_filter; |
| 743 | u8 rates[MWIFIEX_SUPPORTED_RATES]; | 742 | u8 rates[MWIFIEX_SUPPORTED_RATES]; |
| 744 | u32 rates_size; | 743 | u32 rates_size; |
| @@ -793,14 +792,8 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
| 793 | user_scan_in->specific_bssid, | 792 | user_scan_in->specific_bssid, |
| 794 | sizeof(scan_cfg_out->specific_bssid)); | 793 | sizeof(scan_cfg_out->specific_bssid)); |
| 795 | 794 | ||
| 796 | for (ssid_idx = 0; | 795 | for (i = 0; i < user_scan_in->num_ssids; i++) { |
| 797 | ((ssid_idx < ARRAY_SIZE(user_scan_in->ssid_list)) | 796 | ssid_len = user_scan_in->ssid_list[i].ssid_len; |
| 798 | && (*user_scan_in->ssid_list[ssid_idx].ssid | ||
| 799 | || user_scan_in->ssid_list[ssid_idx].max_len)); | ||
| 800 | ssid_idx++) { | ||
| 801 | |||
| 802 | ssid_len = strlen(user_scan_in->ssid_list[ssid_idx]. | ||
| 803 | ssid) + 1; | ||
| 804 | 797 | ||
| 805 | wildcard_ssid_tlv = | 798 | wildcard_ssid_tlv = |
| 806 | (struct mwifiex_ie_types_wildcard_ssid_params *) | 799 | (struct mwifiex_ie_types_wildcard_ssid_params *) |
| @@ -811,19 +804,26 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
| 811 | (u16) (ssid_len + sizeof(wildcard_ssid_tlv-> | 804 | (u16) (ssid_len + sizeof(wildcard_ssid_tlv-> |
| 812 | max_ssid_length))); | 805 | max_ssid_length))); |
| 813 | 806 | ||
| 814 | /* max_ssid_length = 0 tells firmware to perform | 807 | /* |
| 815 | specific scan for the SSID filled */ | 808 | * max_ssid_length = 0 tells firmware to perform |
| 816 | wildcard_ssid_tlv->max_ssid_length = 0; | 809 | * specific scan for the SSID filled, whereas |
| 810 | * max_ssid_length = IEEE80211_MAX_SSID_LEN is for | ||
| 811 | * wildcard scan. | ||
| 812 | */ | ||
| 813 | if (ssid_len) | ||
| 814 | wildcard_ssid_tlv->max_ssid_length = 0; | ||
| 815 | else | ||
| 816 | wildcard_ssid_tlv->max_ssid_length = | ||
| 817 | IEEE80211_MAX_SSID_LEN; | ||
| 817 | 818 | ||
| 818 | memcpy(wildcard_ssid_tlv->ssid, | 819 | memcpy(wildcard_ssid_tlv->ssid, |
| 819 | user_scan_in->ssid_list[ssid_idx].ssid, | 820 | user_scan_in->ssid_list[i].ssid, ssid_len); |
| 820 | ssid_len); | ||
| 821 | 821 | ||
| 822 | tlv_pos += (sizeof(wildcard_ssid_tlv->header) | 822 | tlv_pos += (sizeof(wildcard_ssid_tlv->header) |
| 823 | + le16_to_cpu(wildcard_ssid_tlv->header.len)); | 823 | + le16_to_cpu(wildcard_ssid_tlv->header.len)); |
| 824 | 824 | ||
| 825 | dev_dbg(adapter->dev, "info: scan: ssid_list[%d]: %s, %d\n", | 825 | dev_dbg(adapter->dev, "info: scan: ssid[%d]: %s, %d\n", |
| 826 | ssid_idx, wildcard_ssid_tlv->ssid, | 826 | i, wildcard_ssid_tlv->ssid, |
| 827 | wildcard_ssid_tlv->max_ssid_length); | 827 | wildcard_ssid_tlv->max_ssid_length); |
| 828 | 828 | ||
| 829 | /* Empty wildcard ssid with a maxlen will match many or | 829 | /* Empty wildcard ssid with a maxlen will match many or |
| @@ -832,7 +832,6 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
| 832 | filtered. */ | 832 | filtered. */ |
| 833 | if (!ssid_len && wildcard_ssid_tlv->max_ssid_length) | 833 | if (!ssid_len && wildcard_ssid_tlv->max_ssid_length) |
| 834 | ssid_filter = false; | 834 | ssid_filter = false; |
| 835 | |||
| 836 | } | 835 | } |
| 837 | 836 | ||
| 838 | /* | 837 | /* |
| @@ -841,7 +840,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
| 841 | * truncate scan results. That is not an issue with an SSID | 840 | * truncate scan results. That is not an issue with an SSID |
| 842 | * or BSSID filter applied to the scan results in the firmware. | 841 | * or BSSID filter applied to the scan results in the firmware. |
| 843 | */ | 842 | */ |
| 844 | if ((ssid_idx && ssid_filter) | 843 | if ((i && ssid_filter) |
| 845 | || memcmp(scan_cfg_out->specific_bssid, &zero_mac, | 844 | || memcmp(scan_cfg_out->specific_bssid, &zero_mac, |
| 846 | sizeof(zero_mac))) | 845 | sizeof(zero_mac))) |
| 847 | *filtered_scan = true; | 846 | *filtered_scan = true; |
| @@ -1851,7 +1850,7 @@ mwifiex_queue_scan_cmd(struct mwifiex_private *priv, | |||
| 1851 | * firmware, filtered on a specific SSID. | 1850 | * firmware, filtered on a specific SSID. |
| 1852 | */ | 1851 | */ |
| 1853 | static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, | 1852 | static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, |
| 1854 | struct mwifiex_802_11_ssid *req_ssid) | 1853 | struct cfg80211_ssid *req_ssid) |
| 1855 | { | 1854 | { |
| 1856 | struct mwifiex_adapter *adapter = priv->adapter; | 1855 | struct mwifiex_adapter *adapter = priv->adapter; |
| 1857 | int ret = 0; | 1856 | int ret = 0; |
| @@ -1877,8 +1876,8 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, | |||
| 1877 | return -ENOMEM; | 1876 | return -ENOMEM; |
| 1878 | } | 1877 | } |
| 1879 | 1878 | ||
| 1880 | memcpy(scan_cfg->ssid_list[0].ssid, req_ssid->ssid, | 1879 | scan_cfg->ssid_list = req_ssid; |
| 1881 | req_ssid->ssid_len); | 1880 | scan_cfg->num_ssids = 1; |
| 1882 | 1881 | ||
| 1883 | ret = mwifiex_scan_networks(priv, scan_cfg); | 1882 | ret = mwifiex_scan_networks(priv, scan_cfg); |
| 1884 | 1883 | ||
| @@ -1896,7 +1895,7 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, | |||
| 1896 | * scan, depending upon whether an SSID is provided or not. | 1895 | * scan, depending upon whether an SSID is provided or not. |
| 1897 | */ | 1896 | */ |
| 1898 | int mwifiex_request_scan(struct mwifiex_private *priv, | 1897 | int mwifiex_request_scan(struct mwifiex_private *priv, |
| 1899 | struct mwifiex_802_11_ssid *req_ssid) | 1898 | struct cfg80211_ssid *req_ssid) |
| 1900 | { | 1899 | { |
| 1901 | int ret; | 1900 | int ret; |
| 1902 | 1901 | ||
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index d7aa21da84d0..b9b59db60454 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c | |||
| @@ -101,7 +101,7 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv) | |||
| 101 | 101 | ||
| 102 | memcpy(&priv->prev_ssid, | 102 | memcpy(&priv->prev_ssid, |
| 103 | &priv->curr_bss_params.bss_descriptor.ssid, | 103 | &priv->curr_bss_params.bss_descriptor.ssid, |
| 104 | sizeof(struct mwifiex_802_11_ssid)); | 104 | sizeof(struct cfg80211_ssid)); |
| 105 | 105 | ||
| 106 | memcpy(priv->prev_bssid, | 106 | memcpy(priv->prev_bssid, |
| 107 | priv->curr_bss_params.bss_descriptor.mac_address, ETH_ALEN); | 107 | priv->curr_bss_params.bss_descriptor.mac_address, ETH_ALEN); |
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 866026ecca44..0ae1209646c1 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c | |||
| @@ -192,7 +192,7 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, | |||
| 192 | * first. | 192 | * first. |
| 193 | */ | 193 | */ |
| 194 | int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, | 194 | int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, |
| 195 | struct mwifiex_802_11_ssid *req_ssid) | 195 | struct cfg80211_ssid *req_ssid) |
| 196 | { | 196 | { |
| 197 | int ret; | 197 | int ret; |
| 198 | struct mwifiex_adapter *adapter = priv->adapter; | 198 | struct mwifiex_adapter *adapter = priv->adapter; |
| @@ -249,6 +249,17 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, | |||
| 249 | * application retrieval */ | 249 | * application retrieval */ |
| 250 | priv->assoc_rsp_size = 0; | 250 | priv->assoc_rsp_size = 0; |
| 251 | ret = mwifiex_associate(priv, bss_desc); | 251 | ret = mwifiex_associate(priv, bss_desc); |
| 252 | |||
| 253 | /* If auth type is auto and association fails using open mode, | ||
| 254 | * try to connect using shared mode */ | ||
| 255 | if (ret == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG && | ||
| 256 | priv->sec_info.is_authtype_auto && | ||
| 257 | priv->sec_info.wep_enabled) { | ||
| 258 | priv->sec_info.authentication_mode = | ||
| 259 | NL80211_AUTHTYPE_SHARED_KEY; | ||
| 260 | ret = mwifiex_associate(priv, bss_desc); | ||
| 261 | } | ||
| 262 | |||
| 252 | if (bss) | 263 | if (bss) |
| 253 | cfg80211_put_bss(bss); | 264 | cfg80211_put_bss(bss); |
| 254 | } else { | 265 | } else { |
| @@ -453,8 +464,7 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv, | |||
| 453 | 464 | ||
| 454 | info->bss_mode = priv->bss_mode; | 465 | info->bss_mode = priv->bss_mode; |
| 455 | 466 | ||
| 456 | memcpy(&info->ssid, &bss_desc->ssid, | 467 | memcpy(&info->ssid, &bss_desc->ssid, sizeof(struct cfg80211_ssid)); |
| 457 | sizeof(struct mwifiex_802_11_ssid)); | ||
| 458 | 468 | ||
| 459 | memcpy(&info->bssid, &bss_desc->mac_address, ETH_ALEN); | 469 | memcpy(&info->bssid, &bss_desc->mac_address, ETH_ALEN); |
| 460 | 470 | ||
| @@ -599,7 +609,7 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, | |||
| 599 | * - Start/Join the IBSS | 609 | * - Start/Join the IBSS |
| 600 | */ | 610 | */ |
| 601 | int | 611 | int |
| 602 | mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) | 612 | mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel) |
| 603 | { | 613 | { |
| 604 | int ret; | 614 | int ret; |
| 605 | struct mwifiex_bss_info bss_info; | 615 | struct mwifiex_bss_info bss_info; |
| @@ -636,7 +646,7 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) | |||
| 636 | ret = mwifiex_deauthenticate(priv, ssid_bssid.bssid); | 646 | ret = mwifiex_deauthenticate(priv, ssid_bssid.bssid); |
| 637 | 647 | ||
| 638 | ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_SET, | 648 | ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_SET, |
| 639 | (u16 *) &channel); | 649 | &channel); |
| 640 | 650 | ||
| 641 | /* Do specific SSID scanning */ | 651 | /* Do specific SSID scanning */ |
| 642 | if (mwifiex_request_scan(priv, &bss_info.ssid)) { | 652 | if (mwifiex_request_scan(priv, &bss_info.ssid)) { |
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index 40f4eb7da7b2..ee8af1f047c8 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c | |||
| @@ -227,6 +227,7 @@ static int p54_add_interface(struct ieee80211_hw *dev, | |||
| 227 | struct ieee80211_vif *vif) | 227 | struct ieee80211_vif *vif) |
| 228 | { | 228 | { |
| 229 | struct p54_common *priv = dev->priv; | 229 | struct p54_common *priv = dev->priv; |
| 230 | int err; | ||
| 230 | 231 | ||
| 231 | vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; | 232 | vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; |
| 232 | 233 | ||
| @@ -251,9 +252,9 @@ static int p54_add_interface(struct ieee80211_hw *dev, | |||
| 251 | } | 252 | } |
| 252 | 253 | ||
| 253 | memcpy(priv->mac_addr, vif->addr, ETH_ALEN); | 254 | memcpy(priv->mac_addr, vif->addr, ETH_ALEN); |
| 254 | p54_setup_mac(priv); | 255 | err = p54_setup_mac(priv); |
| 255 | mutex_unlock(&priv->conf_mutex); | 256 | mutex_unlock(&priv->conf_mutex); |
| 256 | return 0; | 257 | return err; |
| 257 | } | 258 | } |
| 258 | 259 | ||
| 259 | static void p54_remove_interface(struct ieee80211_hw *dev, | 260 | static void p54_remove_interface(struct ieee80211_hw *dev, |
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index b1f51a215792..45df728183fd 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c | |||
| @@ -624,36 +624,39 @@ static void __devexit p54p_remove(struct pci_dev *pdev) | |||
| 624 | } | 624 | } |
| 625 | 625 | ||
| 626 | #ifdef CONFIG_PM | 626 | #ifdef CONFIG_PM |
| 627 | static int p54p_suspend(struct pci_dev *pdev, pm_message_t state) | 627 | static int p54p_suspend(struct device *device) |
| 628 | { | 628 | { |
| 629 | struct ieee80211_hw *dev = pci_get_drvdata(pdev); | 629 | struct pci_dev *pdev = to_pci_dev(device); |
| 630 | struct p54p_priv *priv = dev->priv; | ||
| 631 | |||
| 632 | if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED) { | ||
| 633 | ieee80211_stop_queues(dev); | ||
| 634 | p54p_stop(dev); | ||
| 635 | } | ||
| 636 | 630 | ||
| 637 | pci_save_state(pdev); | 631 | pci_save_state(pdev); |
| 638 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 632 | pci_set_power_state(pdev, PCI_D3hot); |
| 633 | pci_disable_device(pdev); | ||
| 639 | return 0; | 634 | return 0; |
| 640 | } | 635 | } |
| 641 | 636 | ||
| 642 | static int p54p_resume(struct pci_dev *pdev) | 637 | static int p54p_resume(struct device *device) |
| 643 | { | 638 | { |
| 644 | struct ieee80211_hw *dev = pci_get_drvdata(pdev); | 639 | struct pci_dev *pdev = to_pci_dev(device); |
| 645 | struct p54p_priv *priv = dev->priv; | 640 | int err; |
| 646 | 641 | ||
| 647 | pci_set_power_state(pdev, PCI_D0); | 642 | err = pci_reenable_device(pdev); |
| 648 | pci_restore_state(pdev); | 643 | if (err) |
| 644 | return err; | ||
| 645 | return pci_set_power_state(pdev, PCI_D0); | ||
| 646 | } | ||
| 649 | 647 | ||
| 650 | if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED) { | 648 | static const struct dev_pm_ops p54pci_pm_ops = { |
| 651 | p54p_open(dev); | 649 | .suspend = p54p_suspend, |
| 652 | ieee80211_wake_queues(dev); | 650 | .resume = p54p_resume, |
| 653 | } | 651 | .freeze = p54p_suspend, |
| 652 | .thaw = p54p_resume, | ||
| 653 | .poweroff = p54p_suspend, | ||
| 654 | .restore = p54p_resume, | ||
| 655 | }; | ||
| 654 | 656 | ||
| 655 | return 0; | 657 | #define P54P_PM_OPS (&p54pci_pm_ops) |
| 656 | } | 658 | #else |
| 659 | #define P54P_PM_OPS (NULL) | ||
| 657 | #endif /* CONFIG_PM */ | 660 | #endif /* CONFIG_PM */ |
| 658 | 661 | ||
| 659 | static struct pci_driver p54p_driver = { | 662 | static struct pci_driver p54p_driver = { |
| @@ -661,10 +664,7 @@ static struct pci_driver p54p_driver = { | |||
| 661 | .id_table = p54p_table, | 664 | .id_table = p54p_table, |
| 662 | .probe = p54p_probe, | 665 | .probe = p54p_probe, |
| 663 | .remove = __devexit_p(p54p_remove), | 666 | .remove = __devexit_p(p54p_remove), |
| 664 | #ifdef CONFIG_PM | 667 | .driver.pm = P54P_PM_OPS, |
| 665 | .suspend = p54p_suspend, | ||
| 666 | .resume = p54p_resume, | ||
| 667 | #endif /* CONFIG_PM */ | ||
| 668 | }; | 668 | }; |
| 669 | 669 | ||
| 670 | static int __init p54p_init(void) | 670 | static int __init p54p_init(void) |
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index 7faed62c6378..f7929906d437 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c | |||
| @@ -618,19 +618,19 @@ static int __devinit p54spi_probe(struct spi_device *spi) | |||
| 618 | ret = spi_setup(spi); | 618 | ret = spi_setup(spi); |
| 619 | if (ret < 0) { | 619 | if (ret < 0) { |
| 620 | dev_err(&priv->spi->dev, "spi_setup failed"); | 620 | dev_err(&priv->spi->dev, "spi_setup failed"); |
| 621 | goto err_free_common; | 621 | goto err_free; |
| 622 | } | 622 | } |
| 623 | 623 | ||
| 624 | ret = gpio_request(p54spi_gpio_power, "p54spi power"); | 624 | ret = gpio_request(p54spi_gpio_power, "p54spi power"); |
| 625 | if (ret < 0) { | 625 | if (ret < 0) { |
| 626 | dev_err(&priv->spi->dev, "power GPIO request failed: %d", ret); | 626 | dev_err(&priv->spi->dev, "power GPIO request failed: %d", ret); |
| 627 | goto err_free_common; | 627 | goto err_free; |
| 628 | } | 628 | } |
| 629 | 629 | ||
| 630 | ret = gpio_request(p54spi_gpio_irq, "p54spi irq"); | 630 | ret = gpio_request(p54spi_gpio_irq, "p54spi irq"); |
| 631 | if (ret < 0) { | 631 | if (ret < 0) { |
| 632 | dev_err(&priv->spi->dev, "irq GPIO request failed: %d", ret); | 632 | dev_err(&priv->spi->dev, "irq GPIO request failed: %d", ret); |
| 633 | goto err_free_common; | 633 | goto err_free_gpio_power; |
| 634 | } | 634 | } |
| 635 | 635 | ||
| 636 | gpio_direction_output(p54spi_gpio_power, 0); | 636 | gpio_direction_output(p54spi_gpio_power, 0); |
| @@ -641,7 +641,7 @@ static int __devinit p54spi_probe(struct spi_device *spi) | |||
| 641 | priv->spi); | 641 | priv->spi); |
| 642 | if (ret < 0) { | 642 | if (ret < 0) { |
| 643 | dev_err(&priv->spi->dev, "request_irq() failed"); | 643 | dev_err(&priv->spi->dev, "request_irq() failed"); |
| 644 | goto err_free_common; | 644 | goto err_free_gpio_irq; |
| 645 | } | 645 | } |
| 646 | 646 | ||
| 647 | irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING); | 647 | irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING); |
| @@ -673,6 +673,12 @@ static int __devinit p54spi_probe(struct spi_device *spi) | |||
| 673 | return 0; | 673 | return 0; |
| 674 | 674 | ||
| 675 | err_free_common: | 675 | err_free_common: |
| 676 | free_irq(gpio_to_irq(p54spi_gpio_irq), spi); | ||
| 677 | err_free_gpio_irq: | ||
| 678 | gpio_free(p54spi_gpio_irq); | ||
| 679 | err_free_gpio_power: | ||
| 680 | gpio_free(p54spi_gpio_power); | ||
| 681 | err_free: | ||
| 676 | p54_free_common(priv->hw); | 682 | p54_free_common(priv->hw); |
| 677 | return ret; | 683 | return ret; |
| 678 | } | 684 | } |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index a330c69583d6..d66e2980bc27 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
| @@ -518,7 +518,7 @@ struct rndis_wlan_private { | |||
| 518 | __le32 current_command_oid; | 518 | __le32 current_command_oid; |
| 519 | 519 | ||
| 520 | /* encryption stuff */ | 520 | /* encryption stuff */ |
| 521 | int encr_tx_key_index; | 521 | u8 encr_tx_key_index; |
| 522 | struct rndis_wlan_encr_key encr_keys[RNDIS_WLAN_NUM_KEYS]; | 522 | struct rndis_wlan_encr_key encr_keys[RNDIS_WLAN_NUM_KEYS]; |
| 523 | int wpa_version; | 523 | int wpa_version; |
| 524 | 524 | ||
| @@ -634,7 +634,7 @@ static u32 get_bcm4320_power_dbm(struct rndis_wlan_private *priv) | |||
| 634 | } | 634 | } |
| 635 | } | 635 | } |
| 636 | 636 | ||
| 637 | static bool is_wpa_key(struct rndis_wlan_private *priv, int idx) | 637 | static bool is_wpa_key(struct rndis_wlan_private *priv, u8 idx) |
| 638 | { | 638 | { |
| 639 | int cipher = priv->encr_keys[idx].cipher; | 639 | int cipher = priv->encr_keys[idx].cipher; |
| 640 | 640 | ||
| @@ -1350,7 +1350,7 @@ static int set_channel(struct usbnet *usbdev, int channel) | |||
| 1350 | } | 1350 | } |
| 1351 | 1351 | ||
| 1352 | static struct ieee80211_channel *get_current_channel(struct usbnet *usbdev, | 1352 | static struct ieee80211_channel *get_current_channel(struct usbnet *usbdev, |
| 1353 | u16 *beacon_interval) | 1353 | u32 *beacon_period) |
| 1354 | { | 1354 | { |
| 1355 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 1355 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
| 1356 | struct ieee80211_channel *channel; | 1356 | struct ieee80211_channel *channel; |
| @@ -1370,14 +1370,14 @@ static struct ieee80211_channel *get_current_channel(struct usbnet *usbdev, | |||
| 1370 | if (!channel) | 1370 | if (!channel) |
| 1371 | return NULL; | 1371 | return NULL; |
| 1372 | 1372 | ||
| 1373 | if (beacon_interval) | 1373 | if (beacon_period) |
| 1374 | *beacon_interval = le16_to_cpu(config.beacon_period); | 1374 | *beacon_period = le32_to_cpu(config.beacon_period); |
| 1375 | return channel; | 1375 | return channel; |
| 1376 | } | 1376 | } |
| 1377 | 1377 | ||
| 1378 | /* index must be 0 - N, as per NDIS */ | 1378 | /* index must be 0 - N, as per NDIS */ |
| 1379 | static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len, | 1379 | static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len, |
| 1380 | int index) | 1380 | u8 index) |
| 1381 | { | 1381 | { |
| 1382 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 1382 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
| 1383 | struct ndis_80211_wep_key ndis_key; | 1383 | struct ndis_80211_wep_key ndis_key; |
| @@ -1387,13 +1387,15 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
| 1387 | netdev_dbg(usbdev->net, "%s(idx: %d, len: %d)\n", | 1387 | netdev_dbg(usbdev->net, "%s(idx: %d, len: %d)\n", |
| 1388 | __func__, index, key_len); | 1388 | __func__, index, key_len); |
| 1389 | 1389 | ||
| 1390 | if ((key_len != 5 && key_len != 13) || index < 0 || index > 3) | 1390 | if (index >= RNDIS_WLAN_NUM_KEYS) |
| 1391 | return -EINVAL; | 1391 | return -EINVAL; |
| 1392 | 1392 | ||
| 1393 | if (key_len == 5) | 1393 | if (key_len == 5) |
| 1394 | cipher = WLAN_CIPHER_SUITE_WEP40; | 1394 | cipher = WLAN_CIPHER_SUITE_WEP40; |
| 1395 | else | 1395 | else if (key_len == 13) |
| 1396 | cipher = WLAN_CIPHER_SUITE_WEP104; | 1396 | cipher = WLAN_CIPHER_SUITE_WEP104; |
| 1397 | else | ||
| 1398 | return -EINVAL; | ||
| 1397 | 1399 | ||
| 1398 | memset(&ndis_key, 0, sizeof(ndis_key)); | 1400 | memset(&ndis_key, 0, sizeof(ndis_key)); |
| 1399 | 1401 | ||
| @@ -1428,7 +1430,7 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
| 1428 | } | 1430 | } |
| 1429 | 1431 | ||
| 1430 | static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | 1432 | static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, |
| 1431 | int index, const u8 *addr, const u8 *rx_seq, | 1433 | u8 index, const u8 *addr, const u8 *rx_seq, |
| 1432 | int seq_len, u32 cipher, __le32 flags) | 1434 | int seq_len, u32 cipher, __le32 flags) |
| 1433 | { | 1435 | { |
| 1434 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 1436 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
| @@ -1436,7 +1438,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
| 1436 | bool is_addr_ok; | 1438 | bool is_addr_ok; |
| 1437 | int ret; | 1439 | int ret; |
| 1438 | 1440 | ||
| 1439 | if (index < 0 || index >= 4) { | 1441 | if (index >= RNDIS_WLAN_NUM_KEYS) { |
| 1440 | netdev_dbg(usbdev->net, "%s(): index out of range (%i)\n", | 1442 | netdev_dbg(usbdev->net, "%s(): index out of range (%i)\n", |
| 1441 | __func__, index); | 1443 | __func__, index); |
| 1442 | return -EINVAL; | 1444 | return -EINVAL; |
| @@ -1524,7 +1526,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
| 1524 | return 0; | 1526 | return 0; |
| 1525 | } | 1527 | } |
| 1526 | 1528 | ||
| 1527 | static int restore_key(struct usbnet *usbdev, int key_idx) | 1529 | static int restore_key(struct usbnet *usbdev, u8 key_idx) |
| 1528 | { | 1530 | { |
| 1529 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 1531 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
| 1530 | struct rndis_wlan_encr_key key; | 1532 | struct rndis_wlan_encr_key key; |
| @@ -1550,13 +1552,13 @@ static void restore_keys(struct usbnet *usbdev) | |||
| 1550 | restore_key(usbdev, i); | 1552 | restore_key(usbdev, i); |
| 1551 | } | 1553 | } |
| 1552 | 1554 | ||
| 1553 | static void clear_key(struct rndis_wlan_private *priv, int idx) | 1555 | static void clear_key(struct rndis_wlan_private *priv, u8 idx) |
| 1554 | { | 1556 | { |
| 1555 | memset(&priv->encr_keys[idx], 0, sizeof(priv->encr_keys[idx])); | 1557 | memset(&priv->encr_keys[idx], 0, sizeof(priv->encr_keys[idx])); |
| 1556 | } | 1558 | } |
| 1557 | 1559 | ||
| 1558 | /* remove_key is for both wep and wpa */ | 1560 | /* remove_key is for both wep and wpa */ |
| 1559 | static int remove_key(struct usbnet *usbdev, int index, const u8 *bssid) | 1561 | static int remove_key(struct usbnet *usbdev, u8 index, const u8 *bssid) |
| 1560 | { | 1562 | { |
| 1561 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 1563 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
| 1562 | struct ndis_80211_remove_key remove_key; | 1564 | struct ndis_80211_remove_key remove_key; |
| @@ -1790,9 +1792,9 @@ static struct ndis_80211_pmkid *remove_pmkid(struct usbnet *usbdev, | |||
| 1790 | struct cfg80211_pmksa *pmksa, | 1792 | struct cfg80211_pmksa *pmksa, |
| 1791 | int max_pmkids) | 1793 | int max_pmkids) |
| 1792 | { | 1794 | { |
| 1793 | int i, len, count, newlen, err; | 1795 | int i, newlen, err; |
| 1796 | unsigned int count; | ||
| 1794 | 1797 | ||
| 1795 | len = le32_to_cpu(pmkids->length); | ||
| 1796 | count = le32_to_cpu(pmkids->bssid_info_count); | 1798 | count = le32_to_cpu(pmkids->bssid_info_count); |
| 1797 | 1799 | ||
| 1798 | if (count > max_pmkids) | 1800 | if (count > max_pmkids) |
| @@ -1831,9 +1833,9 @@ static struct ndis_80211_pmkid *update_pmkid(struct usbnet *usbdev, | |||
| 1831 | struct cfg80211_pmksa *pmksa, | 1833 | struct cfg80211_pmksa *pmksa, |
| 1832 | int max_pmkids) | 1834 | int max_pmkids) |
| 1833 | { | 1835 | { |
| 1834 | int i, err, len, count, newlen; | 1836 | int i, err, newlen; |
| 1837 | unsigned int count; | ||
| 1835 | 1838 | ||
| 1836 | len = le32_to_cpu(pmkids->length); | ||
| 1837 | count = le32_to_cpu(pmkids->bssid_info_count); | 1839 | count = le32_to_cpu(pmkids->bssid_info_count); |
| 1838 | 1840 | ||
| 1839 | if (count > max_pmkids) | 1841 | if (count > max_pmkids) |
| @@ -2683,7 +2685,7 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, | |||
| 2683 | s32 signal; | 2685 | s32 signal; |
| 2684 | u64 timestamp; | 2686 | u64 timestamp; |
| 2685 | u16 capability; | 2687 | u16 capability; |
| 2686 | u16 beacon_interval = 0; | 2688 | u32 beacon_period = 0; |
| 2687 | __le32 rssi; | 2689 | __le32 rssi; |
| 2688 | u8 ie_buf[34]; | 2690 | u8 ie_buf[34]; |
| 2689 | int len, ret, ie_len; | 2691 | int len, ret, ie_len; |
| @@ -2708,7 +2710,7 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, | |||
| 2708 | } | 2710 | } |
| 2709 | 2711 | ||
| 2710 | /* Get channel and beacon interval */ | 2712 | /* Get channel and beacon interval */ |
| 2711 | channel = get_current_channel(usbdev, &beacon_interval); | 2713 | channel = get_current_channel(usbdev, &beacon_period); |
| 2712 | if (!channel) { | 2714 | if (!channel) { |
| 2713 | netdev_warn(usbdev->net, "%s(): could not get channel.\n", | 2715 | netdev_warn(usbdev->net, "%s(): could not get channel.\n", |
| 2714 | __func__); | 2716 | __func__); |
| @@ -2738,11 +2740,11 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, | |||
| 2738 | netdev_dbg(usbdev->net, "%s(): channel:%d(freq), bssid:[%pM], tsf:%d, " | 2740 | netdev_dbg(usbdev->net, "%s(): channel:%d(freq), bssid:[%pM], tsf:%d, " |
| 2739 | "capa:%x, beacon int:%d, resp_ie(len:%d, essid:'%.32s'), " | 2741 | "capa:%x, beacon int:%d, resp_ie(len:%d, essid:'%.32s'), " |
| 2740 | "signal:%d\n", __func__, (channel ? channel->center_freq : -1), | 2742 | "signal:%d\n", __func__, (channel ? channel->center_freq : -1), |
| 2741 | bssid, (u32)timestamp, capability, beacon_interval, ie_len, | 2743 | bssid, (u32)timestamp, capability, beacon_period, ie_len, |
| 2742 | ssid.essid, signal); | 2744 | ssid.essid, signal); |
| 2743 | 2745 | ||
| 2744 | bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid, | 2746 | bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid, |
| 2745 | timestamp, capability, beacon_interval, ie_buf, ie_len, | 2747 | timestamp, capability, beacon_period, ie_buf, ie_len, |
| 2746 | signal, GFP_KERNEL); | 2748 | signal, GFP_KERNEL); |
| 2747 | cfg80211_put_bss(bss); | 2749 | cfg80211_put_bss(bss); |
| 2748 | } | 2750 | } |
| @@ -2755,9 +2757,10 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) | |||
| 2755 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 2757 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
| 2756 | struct ndis_80211_assoc_info *info = NULL; | 2758 | struct ndis_80211_assoc_info *info = NULL; |
| 2757 | u8 bssid[ETH_ALEN]; | 2759 | u8 bssid[ETH_ALEN]; |
| 2758 | int resp_ie_len, req_ie_len; | 2760 | unsigned int resp_ie_len, req_ie_len; |
| 2761 | unsigned int offset; | ||
| 2759 | u8 *req_ie, *resp_ie; | 2762 | u8 *req_ie, *resp_ie; |
| 2760 | int ret, offset; | 2763 | int ret; |
| 2761 | bool roamed = false; | 2764 | bool roamed = false; |
| 2762 | bool match_bss; | 2765 | bool match_bss; |
| 2763 | 2766 | ||
| @@ -2785,7 +2788,9 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) | |||
| 2785 | ret = get_association_info(usbdev, info, CONTROL_BUFFER_SIZE); | 2788 | ret = get_association_info(usbdev, info, CONTROL_BUFFER_SIZE); |
| 2786 | if (!ret) { | 2789 | if (!ret) { |
| 2787 | req_ie_len = le32_to_cpu(info->req_ie_length); | 2790 | req_ie_len = le32_to_cpu(info->req_ie_length); |
| 2788 | if (req_ie_len > 0) { | 2791 | if (req_ie_len > CONTROL_BUFFER_SIZE) |
| 2792 | req_ie_len = CONTROL_BUFFER_SIZE; | ||
| 2793 | if (req_ie_len != 0) { | ||
| 2789 | offset = le32_to_cpu(info->offset_req_ies); | 2794 | offset = le32_to_cpu(info->offset_req_ies); |
| 2790 | 2795 | ||
| 2791 | if (offset > CONTROL_BUFFER_SIZE) | 2796 | if (offset > CONTROL_BUFFER_SIZE) |
| @@ -2799,7 +2804,9 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) | |||
| 2799 | } | 2804 | } |
| 2800 | 2805 | ||
| 2801 | resp_ie_len = le32_to_cpu(info->resp_ie_length); | 2806 | resp_ie_len = le32_to_cpu(info->resp_ie_length); |
| 2802 | if (resp_ie_len > 0) { | 2807 | if (resp_ie_len > CONTROL_BUFFER_SIZE) |
| 2808 | resp_ie_len = CONTROL_BUFFER_SIZE; | ||
| 2809 | if (resp_ie_len != 0) { | ||
| 2803 | offset = le32_to_cpu(info->offset_resp_ies); | 2810 | offset = le32_to_cpu(info->offset_resp_ies); |
| 2804 | 2811 | ||
| 2805 | if (offset > CONTROL_BUFFER_SIZE) | 2812 | if (offset > CONTROL_BUFFER_SIZE) |
| @@ -3038,7 +3045,7 @@ static void rndis_wlan_media_specific_indication(struct usbnet *usbdev, | |||
| 3038 | struct rndis_indicate *msg, int buflen) | 3045 | struct rndis_indicate *msg, int buflen) |
| 3039 | { | 3046 | { |
| 3040 | struct ndis_80211_status_indication *indication; | 3047 | struct ndis_80211_status_indication *indication; |
| 3041 | int len, offset; | 3048 | unsigned int len, offset; |
| 3042 | 3049 | ||
| 3043 | offset = offsetof(struct rndis_indicate, status) + | 3050 | offset = offsetof(struct rndis_indicate, status) + |
| 3044 | le32_to_cpu(msg->offset); | 3051 | le32_to_cpu(msg->offset); |
| @@ -3050,7 +3057,7 @@ static void rndis_wlan_media_specific_indication(struct usbnet *usbdev, | |||
| 3050 | return; | 3057 | return; |
| 3051 | } | 3058 | } |
| 3052 | 3059 | ||
| 3053 | if (offset + len > buflen) { | 3060 | if (len > buflen || offset > buflen || offset + len > buflen) { |
| 3054 | netdev_info(usbdev->net, "media specific indication, too large to fit to buffer (%i > %i)\n", | 3061 | netdev_info(usbdev->net, "media specific indication, too large to fit to buffer (%i > %i)\n", |
| 3055 | offset + len, buflen); | 3062 | offset + len, buflen); |
| 3056 | return; | 3063 | return; |
diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c index 638fbef693e6..cf53ac9d6f23 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al. | 8 | * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al. |
| 9 | * | 9 | * |
| 10 | * The driver was extended to the RTL8187B in 2008 by: | 10 | * The driver was extended to the RTL8187B in 2008 by: |
| 11 | * Herton Ronaldo Krzesinski <herton@mandriva.com.br> | 11 | * Herton Ronaldo Krzesinski <herton@mandriva.com.br> |
| 12 | * Hin-Tak Leung <htl10@users.sourceforge.net> | 12 | * Hin-Tak Leung <htl10@users.sourceforge.net> |
| 13 | * Larry Finger <Larry.Finger@lwfinger.net> | 13 | * Larry Finger <Larry.Finger@lwfinger.net> |
| 14 | * | 14 | * |
| @@ -232,6 +232,7 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
| 232 | { | 232 | { |
| 233 | struct rtl8187_priv *priv = dev->priv; | 233 | struct rtl8187_priv *priv = dev->priv; |
| 234 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 234 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 235 | struct ieee80211_hdr *tx_hdr = (struct ieee80211_hdr *)(skb->data); | ||
| 235 | unsigned int ep; | 236 | unsigned int ep; |
| 236 | void *buf; | 237 | void *buf; |
| 237 | struct urb *urb; | 238 | struct urb *urb; |
| @@ -249,7 +250,7 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
| 249 | flags |= RTL818X_TX_DESC_FLAG_NO_ENC; | 250 | flags |= RTL818X_TX_DESC_FLAG_NO_ENC; |
| 250 | 251 | ||
| 251 | flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24; | 252 | flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24; |
| 252 | if (ieee80211_has_morefrags(((struct ieee80211_hdr *)skb->data)->frame_control)) | 253 | if (ieee80211_has_morefrags(tx_hdr->frame_control)) |
| 253 | flags |= RTL818X_TX_DESC_FLAG_MOREFRAG; | 254 | flags |= RTL818X_TX_DESC_FLAG_MOREFRAG; |
| 254 | if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { | 255 | if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { |
| 255 | flags |= RTL818X_TX_DESC_FLAG_RTS; | 256 | flags |= RTL818X_TX_DESC_FLAG_RTS; |
| @@ -261,6 +262,13 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
| 261 | flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; | 262 | flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; |
| 262 | } | 263 | } |
| 263 | 264 | ||
| 265 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | ||
| 266 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | ||
| 267 | priv->seqno += 0x10; | ||
| 268 | tx_hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | ||
| 269 | tx_hdr->seq_ctrl |= cpu_to_le16(priv->seqno); | ||
| 270 | } | ||
| 271 | |||
| 264 | if (!priv->is_rtl8187b) { | 272 | if (!priv->is_rtl8187b) { |
| 265 | struct rtl8187_tx_hdr *hdr = | 273 | struct rtl8187_tx_hdr *hdr = |
| 266 | (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr)); | 274 | (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr)); |
| @@ -274,8 +282,6 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
| 274 | } else { | 282 | } else { |
| 275 | /* fc needs to be calculated before skb_push() */ | 283 | /* fc needs to be calculated before skb_push() */ |
| 276 | unsigned int epmap[4] = { 6, 7, 5, 4 }; | 284 | unsigned int epmap[4] = { 6, 7, 5, 4 }; |
| 277 | struct ieee80211_hdr *tx_hdr = | ||
| 278 | (struct ieee80211_hdr *)(skb->data); | ||
| 279 | u16 fc = le16_to_cpu(tx_hdr->frame_control); | 285 | u16 fc = le16_to_cpu(tx_hdr->frame_control); |
| 280 | 286 | ||
| 281 | struct rtl8187b_tx_hdr *hdr = | 287 | struct rtl8187b_tx_hdr *hdr = |
| @@ -1031,10 +1037,61 @@ static void rtl8187_stop(struct ieee80211_hw *dev) | |||
| 1031 | cancel_delayed_work_sync(&priv->work); | 1037 | cancel_delayed_work_sync(&priv->work); |
| 1032 | } | 1038 | } |
| 1033 | 1039 | ||
| 1040 | static u64 rtl8187_get_tsf(struct ieee80211_hw *dev, struct ieee80211_vif *vif) | ||
| 1041 | { | ||
| 1042 | struct rtl8187_priv *priv = dev->priv; | ||
| 1043 | |||
| 1044 | return rtl818x_ioread32(priv, &priv->map->TSFT[0]) | | ||
| 1045 | (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32; | ||
| 1046 | } | ||
| 1047 | |||
| 1048 | |||
| 1049 | static void rtl8187_beacon_work(struct work_struct *work) | ||
| 1050 | { | ||
| 1051 | struct rtl8187_vif *vif_priv = | ||
| 1052 | container_of(work, struct rtl8187_vif, beacon_work.work); | ||
| 1053 | struct ieee80211_vif *vif = | ||
| 1054 | container_of((void *)vif_priv, struct ieee80211_vif, drv_priv); | ||
| 1055 | struct ieee80211_hw *dev = vif_priv->dev; | ||
| 1056 | struct ieee80211_mgmt *mgmt; | ||
| 1057 | struct sk_buff *skb; | ||
| 1058 | |||
| 1059 | /* don't overflow the tx ring */ | ||
| 1060 | if (ieee80211_queue_stopped(dev, 0)) | ||
| 1061 | goto resched; | ||
| 1062 | |||
| 1063 | /* grab a fresh beacon */ | ||
| 1064 | skb = ieee80211_beacon_get(dev, vif); | ||
| 1065 | if (!skb) | ||
| 1066 | goto resched; | ||
| 1067 | |||
| 1068 | /* | ||
| 1069 | * update beacon timestamp w/ TSF value | ||
| 1070 | * TODO: make hardware update beacon timestamp | ||
| 1071 | */ | ||
| 1072 | mgmt = (struct ieee80211_mgmt *)skb->data; | ||
| 1073 | mgmt->u.beacon.timestamp = cpu_to_le64(rtl8187_get_tsf(dev, vif)); | ||
| 1074 | |||
| 1075 | /* TODO: use actual beacon queue */ | ||
| 1076 | skb_set_queue_mapping(skb, 0); | ||
| 1077 | |||
| 1078 | rtl8187_tx(dev, skb); | ||
| 1079 | |||
| 1080 | resched: | ||
| 1081 | /* | ||
| 1082 | * schedule next beacon | ||
| 1083 | * TODO: use hardware support for beacon timing | ||
| 1084 | */ | ||
| 1085 | schedule_delayed_work(&vif_priv->beacon_work, | ||
| 1086 | usecs_to_jiffies(1024 * vif->bss_conf.beacon_int)); | ||
| 1087 | } | ||
| 1088 | |||
| 1089 | |||
| 1034 | static int rtl8187_add_interface(struct ieee80211_hw *dev, | 1090 | static int rtl8187_add_interface(struct ieee80211_hw *dev, |
| 1035 | struct ieee80211_vif *vif) | 1091 | struct ieee80211_vif *vif) |
| 1036 | { | 1092 | { |
| 1037 | struct rtl8187_priv *priv = dev->priv; | 1093 | struct rtl8187_priv *priv = dev->priv; |
| 1094 | struct rtl8187_vif *vif_priv; | ||
| 1038 | int i; | 1095 | int i; |
| 1039 | int ret = -EOPNOTSUPP; | 1096 | int ret = -EOPNOTSUPP; |
| 1040 | 1097 | ||
| @@ -1044,6 +1101,7 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev, | |||
| 1044 | 1101 | ||
| 1045 | switch (vif->type) { | 1102 | switch (vif->type) { |
| 1046 | case NL80211_IFTYPE_STATION: | 1103 | case NL80211_IFTYPE_STATION: |
| 1104 | case NL80211_IFTYPE_ADHOC: | ||
| 1047 | break; | 1105 | break; |
| 1048 | default: | 1106 | default: |
| 1049 | goto exit; | 1107 | goto exit; |
| @@ -1052,6 +1110,13 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev, | |||
| 1052 | ret = 0; | 1110 | ret = 0; |
| 1053 | priv->vif = vif; | 1111 | priv->vif = vif; |
| 1054 | 1112 | ||
| 1113 | /* Initialize driver private area */ | ||
| 1114 | vif_priv = (struct rtl8187_vif *)&vif->drv_priv; | ||
| 1115 | vif_priv->dev = dev; | ||
| 1116 | INIT_DELAYED_WORK(&vif_priv->beacon_work, rtl8187_beacon_work); | ||
| 1117 | vif_priv->enable_beacon = false; | ||
| 1118 | |||
| 1119 | |||
| 1055 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); | 1120 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); |
| 1056 | for (i = 0; i < ETH_ALEN; i++) | 1121 | for (i = 0; i < ETH_ALEN; i++) |
| 1057 | rtl818x_iowrite8(priv, &priv->map->MAC[i], | 1122 | rtl818x_iowrite8(priv, &priv->map->MAC[i], |
| @@ -1175,9 +1240,12 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev, | |||
| 1175 | u32 changed) | 1240 | u32 changed) |
| 1176 | { | 1241 | { |
| 1177 | struct rtl8187_priv *priv = dev->priv; | 1242 | struct rtl8187_priv *priv = dev->priv; |
| 1243 | struct rtl8187_vif *vif_priv; | ||
| 1178 | int i; | 1244 | int i; |
| 1179 | u8 reg; | 1245 | u8 reg; |
| 1180 | 1246 | ||
| 1247 | vif_priv = (struct rtl8187_vif *)&vif->drv_priv; | ||
| 1248 | |||
| 1181 | if (changed & BSS_CHANGED_BSSID) { | 1249 | if (changed & BSS_CHANGED_BSSID) { |
| 1182 | mutex_lock(&priv->conf_mutex); | 1250 | mutex_lock(&priv->conf_mutex); |
| 1183 | for (i = 0; i < ETH_ALEN; i++) | 1251 | for (i = 0; i < ETH_ALEN; i++) |
| @@ -1189,8 +1257,12 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev, | |||
| 1189 | else | 1257 | else |
| 1190 | reg = 0; | 1258 | reg = 0; |
| 1191 | 1259 | ||
| 1192 | if (is_valid_ether_addr(info->bssid)) | 1260 | if (is_valid_ether_addr(info->bssid)) { |
| 1193 | reg |= RTL818X_MSR_INFRA; | 1261 | if (vif->type == NL80211_IFTYPE_ADHOC) |
| 1262 | reg |= RTL818X_MSR_ADHOC; | ||
| 1263 | else | ||
| 1264 | reg |= RTL818X_MSR_INFRA; | ||
| 1265 | } | ||
| 1194 | else | 1266 | else |
| 1195 | reg |= RTL818X_MSR_NO_LINK; | 1267 | reg |= RTL818X_MSR_NO_LINK; |
| 1196 | 1268 | ||
| @@ -1202,6 +1274,16 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev, | |||
| 1202 | if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE)) | 1274 | if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE)) |
| 1203 | rtl8187_conf_erp(priv, info->use_short_slot, | 1275 | rtl8187_conf_erp(priv, info->use_short_slot, |
| 1204 | info->use_short_preamble); | 1276 | info->use_short_preamble); |
| 1277 | |||
| 1278 | if (changed & BSS_CHANGED_BEACON_ENABLED) | ||
| 1279 | vif_priv->enable_beacon = info->enable_beacon; | ||
| 1280 | |||
| 1281 | if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON)) { | ||
| 1282 | cancel_delayed_work_sync(&vif_priv->beacon_work); | ||
| 1283 | if (vif_priv->enable_beacon) | ||
| 1284 | schedule_work(&vif_priv->beacon_work.work); | ||
| 1285 | } | ||
| 1286 | |||
| 1205 | } | 1287 | } |
| 1206 | 1288 | ||
| 1207 | static u64 rtl8187_prepare_multicast(struct ieee80211_hw *dev, | 1289 | static u64 rtl8187_prepare_multicast(struct ieee80211_hw *dev, |
| @@ -1279,13 +1361,6 @@ static int rtl8187_conf_tx(struct ieee80211_hw *dev, | |||
| 1279 | return 0; | 1361 | return 0; |
| 1280 | } | 1362 | } |
| 1281 | 1363 | ||
| 1282 | static u64 rtl8187_get_tsf(struct ieee80211_hw *dev, struct ieee80211_vif *vif) | ||
| 1283 | { | ||
| 1284 | struct rtl8187_priv *priv = dev->priv; | ||
| 1285 | |||
| 1286 | return rtl818x_ioread32(priv, &priv->map->TSFT[0]) | | ||
| 1287 | (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32; | ||
| 1288 | } | ||
| 1289 | 1364 | ||
| 1290 | static const struct ieee80211_ops rtl8187_ops = { | 1365 | static const struct ieee80211_ops rtl8187_ops = { |
| 1291 | .tx = rtl8187_tx, | 1366 | .tx = rtl8187_tx, |
| @@ -1514,12 +1589,9 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
| 1514 | if (reg & 0xFF00) | 1589 | if (reg & 0xFF00) |
| 1515 | priv->rfkill_mask = RFKILL_MASK_8198; | 1590 | priv->rfkill_mask = RFKILL_MASK_8198; |
| 1516 | } | 1591 | } |
| 1517 | 1592 | dev->vif_data_size = sizeof(struct rtl8187_vif); | |
| 1518 | /* | 1593 | dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
| 1519 | * XXX: Once this driver supports anything that requires | 1594 | BIT(NL80211_IFTYPE_ADHOC) ; |
| 1520 | * beacons it must implement IEEE80211_TX_CTL_ASSIGN_SEQ. | ||
| 1521 | */ | ||
| 1522 | dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); | ||
| 1523 | 1595 | ||
| 1524 | if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b) | 1596 | if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b) |
| 1525 | printk(KERN_INFO "rtl8187: inconsistency between id with OEM" | 1597 | printk(KERN_INFO "rtl8187: inconsistency between id with OEM" |
diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h index f1cc90751dbf..e19a20a8e955 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h +++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h | |||
| @@ -89,6 +89,14 @@ enum { | |||
| 89 | DEVICE_RTL8187B | 89 | DEVICE_RTL8187B |
| 90 | }; | 90 | }; |
| 91 | 91 | ||
| 92 | struct rtl8187_vif { | ||
| 93 | struct ieee80211_hw *dev; | ||
| 94 | |||
| 95 | /* beaconing */ | ||
| 96 | struct delayed_work beacon_work; | ||
| 97 | bool enable_beacon; | ||
| 98 | }; | ||
| 99 | |||
| 92 | struct rtl8187_priv { | 100 | struct rtl8187_priv { |
| 93 | /* common between rtl818x drivers */ | 101 | /* common between rtl818x drivers */ |
| 94 | struct rtl818x_csr *map; | 102 | struct rtl818x_csr *map; |
| @@ -141,6 +149,7 @@ struct rtl8187_priv { | |||
| 141 | __le32 bits32; | 149 | __le32 bits32; |
| 142 | } *io_dmabuf; | 150 | } *io_dmabuf; |
| 143 | bool rfkill_off; | 151 | bool rfkill_off; |
| 152 | u16 seqno; | ||
| 144 | }; | 153 | }; |
| 145 | 154 | ||
| 146 | void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); | 155 | void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index a64473556ea8..1208b753f62f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | |||
| @@ -520,6 +520,10 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw) | |||
| 520 | dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, | 520 | dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, |
| 521 | dm_digtable.backoff_val); | 521 | dm_digtable.backoff_val); |
| 522 | 522 | ||
| 523 | dm_digtable.cur_igvalue += 2; | ||
| 524 | if (dm_digtable.cur_igvalue > 0x3f) | ||
| 525 | dm_digtable.cur_igvalue = 0x3f; | ||
| 526 | |||
| 523 | if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) { | 527 | if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) { |
| 524 | rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, | 528 | rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, |
| 525 | dm_digtable.cur_igvalue); | 529 | dm_digtable.cur_igvalue); |
| @@ -1201,13 +1205,18 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) | |||
| 1201 | "PreState = %d, CurState = %d\n", | 1205 | "PreState = %d, CurState = %d\n", |
| 1202 | p_ra->pre_ratr_state, p_ra->ratr_state); | 1206 | p_ra->pre_ratr_state, p_ra->ratr_state); |
| 1203 | 1207 | ||
| 1204 | rcu_read_lock(); | 1208 | /* Only the PCI card uses sta in the update rate table |
| 1205 | sta = ieee80211_find_sta(mac->vif, mac->bssid); | 1209 | * callback routine */ |
| 1210 | if (rtlhal->interface == INTF_PCI) { | ||
| 1211 | rcu_read_lock(); | ||
| 1212 | sta = ieee80211_find_sta(mac->vif, mac->bssid); | ||
| 1213 | } | ||
| 1206 | rtlpriv->cfg->ops->update_rate_tbl(hw, sta, | 1214 | rtlpriv->cfg->ops->update_rate_tbl(hw, sta, |
| 1207 | p_ra->ratr_state); | 1215 | p_ra->ratr_state); |
| 1208 | 1216 | ||
| 1209 | p_ra->pre_ratr_state = p_ra->ratr_state; | 1217 | p_ra->pre_ratr_state = p_ra->ratr_state; |
| 1210 | rcu_read_unlock(); | 1218 | if (rtlhal->interface == INTF_PCI) |
| 1219 | rcu_read_unlock(); | ||
| 1211 | } | 1220 | } |
| 1212 | } | 1221 | } |
| 1213 | } | 1222 | } |
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index ffcf89fe45e4..2e1e352864bb 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c | |||
| @@ -346,9 +346,14 @@ static int _rtl_usb_init(struct ieee80211_hw *hw) | |||
| 346 | pep_desc->bEndpointAddress, pep_desc->wMaxPacketSize, | 346 | pep_desc->bEndpointAddress, pep_desc->wMaxPacketSize, |
| 347 | pep_desc->bInterval); | 347 | pep_desc->bInterval); |
| 348 | } | 348 | } |
| 349 | if (rtlusb->in_ep_nums < rtlpriv->cfg->usb_interface_cfg->in_ep_num) | 349 | if (rtlusb->in_ep_nums < rtlpriv->cfg->usb_interface_cfg->in_ep_num) { |
| 350 | return -EINVAL ; | 350 | pr_err("Too few input end points found\n"); |
| 351 | 351 | return -EINVAL; | |
| 352 | } | ||
| 353 | if (rtlusb->out_ep_nums == 0) { | ||
| 354 | pr_err("No output end points found\n"); | ||
| 355 | return -EINVAL; | ||
| 356 | } | ||
| 352 | /* usb endpoint mapping */ | 357 | /* usb endpoint mapping */ |
| 353 | err = rtlpriv->cfg->usb_interface_cfg->usb_endpoint_mapping(hw); | 358 | err = rtlpriv->cfg->usb_interface_cfg->usb_endpoint_mapping(hw); |
| 354 | rtlusb->usb_mq_to_hwq = rtlpriv->cfg->usb_interface_cfg->usb_mq_to_hwq; | 359 | rtlusb->usb_mq_to_hwq = rtlpriv->cfg->usb_interface_cfg->usb_mq_to_hwq; |
| @@ -357,7 +362,7 @@ static int _rtl_usb_init(struct ieee80211_hw *hw) | |||
| 357 | return err; | 362 | return err; |
| 358 | } | 363 | } |
| 359 | 364 | ||
| 360 | static int _rtl_usb_init_sw(struct ieee80211_hw *hw) | 365 | static void rtl_usb_init_sw(struct ieee80211_hw *hw) |
| 361 | { | 366 | { |
| 362 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 367 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
| 363 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 368 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
| @@ -392,7 +397,6 @@ static int _rtl_usb_init_sw(struct ieee80211_hw *hw) | |||
| 392 | /* HIMR_EX - turn all on */ | 397 | /* HIMR_EX - turn all on */ |
| 393 | rtlusb->irq_mask[1] = 0xFFFFFFFF; | 398 | rtlusb->irq_mask[1] = 0xFFFFFFFF; |
| 394 | rtlusb->disableHWSM = true; | 399 | rtlusb->disableHWSM = true; |
| 395 | return 0; | ||
| 396 | } | 400 | } |
| 397 | 401 | ||
| 398 | #define __RADIO_TAP_SIZE_RSV 32 | 402 | #define __RADIO_TAP_SIZE_RSV 32 |
| @@ -976,7 +980,9 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, | |||
| 976 | } | 980 | } |
| 977 | rtlpriv->cfg->ops->init_sw_leds(hw); | 981 | rtlpriv->cfg->ops->init_sw_leds(hw); |
| 978 | err = _rtl_usb_init(hw); | 982 | err = _rtl_usb_init(hw); |
| 979 | err = _rtl_usb_init_sw(hw); | 983 | if (err) |
| 984 | goto error_out; | ||
| 985 | rtl_usb_init_sw(hw); | ||
| 980 | /* Init mac80211 sw */ | 986 | /* Init mac80211 sw */ |
| 981 | err = rtl_init_core(hw); | 987 | err = rtl_init_core(hw); |
| 982 | if (err) { | 988 | if (err) { |
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index b776d9d5efe8..3414fc11e9ba 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c | |||
| @@ -459,23 +459,39 @@ out: | |||
| 459 | 459 | ||
| 460 | int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) | 460 | int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) |
| 461 | { | 461 | { |
| 462 | unsigned long flags; | ||
| 462 | u8 link = find_first_zero_bit(wl->links_map, WL12XX_MAX_LINKS); | 463 | u8 link = find_first_zero_bit(wl->links_map, WL12XX_MAX_LINKS); |
| 463 | if (link >= WL12XX_MAX_LINKS) | 464 | if (link >= WL12XX_MAX_LINKS) |
| 464 | return -EBUSY; | 465 | return -EBUSY; |
| 465 | 466 | ||
| 467 | /* these bits are used by op_tx */ | ||
| 468 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
| 466 | __set_bit(link, wl->links_map); | 469 | __set_bit(link, wl->links_map); |
| 467 | __set_bit(link, wlvif->links_map); | 470 | __set_bit(link, wlvif->links_map); |
| 471 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
| 468 | *hlid = link; | 472 | *hlid = link; |
| 469 | return 0; | 473 | return 0; |
| 470 | } | 474 | } |
| 471 | 475 | ||
| 472 | void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) | 476 | void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) |
| 473 | { | 477 | { |
| 478 | unsigned long flags; | ||
| 479 | |||
| 474 | if (*hlid == WL12XX_INVALID_LINK_ID) | 480 | if (*hlid == WL12XX_INVALID_LINK_ID) |
| 475 | return; | 481 | return; |
| 476 | 482 | ||
| 483 | /* these bits are used by op_tx */ | ||
| 484 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
| 477 | __clear_bit(*hlid, wl->links_map); | 485 | __clear_bit(*hlid, wl->links_map); |
| 478 | __clear_bit(*hlid, wlvif->links_map); | 486 | __clear_bit(*hlid, wlvif->links_map); |
| 487 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
| 488 | |||
| 489 | /* | ||
| 490 | * At this point op_tx() will not add more packets to the queues. We | ||
| 491 | * can purge them. | ||
| 492 | */ | ||
| 493 | wl1271_tx_reset_link_queues(wl, *hlid); | ||
| 494 | |||
| 479 | *hlid = WL12XX_INVALID_LINK_ID; | 495 | *hlid = WL12XX_INVALID_LINK_ID; |
| 480 | } | 496 | } |
| 481 | 497 | ||
| @@ -515,7 +531,7 @@ static int wl12xx_cmd_role_start_dev(struct wl1271 *wl, | |||
| 515 | goto out_free; | 531 | goto out_free; |
| 516 | } | 532 | } |
| 517 | cmd->device.hlid = wlvif->dev_hlid; | 533 | cmd->device.hlid = wlvif->dev_hlid; |
| 518 | cmd->device.session = wlvif->session_counter; | 534 | cmd->device.session = wl12xx_get_new_session_id(wl, wlvif); |
| 519 | 535 | ||
| 520 | wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d", | 536 | wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d", |
| 521 | cmd->role_id, cmd->device.hlid, cmd->device.session); | 537 | cmd->role_id, cmd->device.hlid, cmd->device.session); |
| @@ -1802,6 +1818,14 @@ int wl12xx_croc(struct wl1271 *wl, u8 role_id) | |||
| 1802 | goto out; | 1818 | goto out; |
| 1803 | 1819 | ||
| 1804 | __clear_bit(role_id, wl->roc_map); | 1820 | __clear_bit(role_id, wl->roc_map); |
| 1821 | |||
| 1822 | /* | ||
| 1823 | * Rearm the tx watchdog when removing the last ROC. This prevents | ||
| 1824 | * recoveries due to just finished ROCs - when Tx hasn't yet had | ||
| 1825 | * a chance to get out. | ||
| 1826 | */ | ||
| 1827 | if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) >= WL12XX_MAX_ROLES) | ||
| 1828 | wl12xx_rearm_tx_watchdog_locked(wl); | ||
| 1805 | out: | 1829 | out: |
| 1806 | return ret; | 1830 | return ret; |
| 1807 | } | 1831 | } |
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index cc50faaf03d1..3e581e19424c 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h | |||
| @@ -690,6 +690,9 @@ struct conf_tx_settings { | |||
| 690 | */ | 690 | */ |
| 691 | u8 tmpl_short_retry_limit; | 691 | u8 tmpl_short_retry_limit; |
| 692 | u8 tmpl_long_retry_limit; | 692 | u8 tmpl_long_retry_limit; |
| 693 | |||
| 694 | /* Time in ms for Tx watchdog timer to expire */ | ||
| 695 | u32 tx_watchdog_timeout; | ||
| 693 | }; | 696 | }; |
| 694 | 697 | ||
| 695 | enum { | 698 | enum { |
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index adf9bbcf88fd..39002363611e 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
| @@ -217,6 +217,7 @@ static struct conf_drv_settings default_conf = { | |||
| 217 | .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS, | 217 | .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS, |
| 218 | .tmpl_short_retry_limit = 10, | 218 | .tmpl_short_retry_limit = 10, |
| 219 | .tmpl_long_retry_limit = 10, | 219 | .tmpl_long_retry_limit = 10, |
| 220 | .tx_watchdog_timeout = 5000, | ||
| 220 | }, | 221 | }, |
| 221 | .conn = { | 222 | .conn = { |
| 222 | .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, | 223 | .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, |
| @@ -246,7 +247,7 @@ static struct conf_drv_settings default_conf = { | |||
| 246 | .psm_entry_retries = 8, | 247 | .psm_entry_retries = 8, |
| 247 | .psm_exit_retries = 16, | 248 | .psm_exit_retries = 16, |
| 248 | .psm_entry_nullfunc_retries = 3, | 249 | .psm_entry_nullfunc_retries = 3, |
| 249 | .dynamic_ps_timeout = 100, | 250 | .dynamic_ps_timeout = 200, |
| 250 | .forced_ps = false, | 251 | .forced_ps = false, |
| 251 | .keep_alive_interval = 55000, | 252 | .keep_alive_interval = 55000, |
| 252 | .max_listen_interval = 20, | 253 | .max_listen_interval = 20, |
| @@ -392,15 +393,15 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, | |||
| 392 | static void wl1271_op_stop(struct ieee80211_hw *hw); | 393 | static void wl1271_op_stop(struct ieee80211_hw *hw); |
| 393 | static void wl1271_free_ap_keys(struct wl1271 *wl, struct wl12xx_vif *wlvif); | 394 | static void wl1271_free_ap_keys(struct wl1271 *wl, struct wl12xx_vif *wlvif); |
| 394 | 395 | ||
| 395 | static DEFINE_MUTEX(wl_list_mutex); | 396 | static int wl12xx_set_authorized(struct wl1271 *wl, |
| 396 | static LIST_HEAD(wl_list); | 397 | struct wl12xx_vif *wlvif) |
| 397 | |||
| 398 | static int wl1271_check_operstate(struct wl1271 *wl, struct wl12xx_vif *wlvif, | ||
| 399 | unsigned char operstate) | ||
| 400 | { | 398 | { |
| 401 | int ret; | 399 | int ret; |
| 402 | 400 | ||
| 403 | if (operstate != IF_OPER_UP) | 401 | if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS)) |
| 402 | return -EINVAL; | ||
| 403 | |||
| 404 | if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) | ||
| 404 | return 0; | 405 | return 0; |
| 405 | 406 | ||
| 406 | if (test_and_set_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags)) | 407 | if (test_and_set_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags)) |
| @@ -415,76 +416,6 @@ static int wl1271_check_operstate(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
| 415 | wl1271_info("Association completed."); | 416 | wl1271_info("Association completed."); |
| 416 | return 0; | 417 | return 0; |
| 417 | } | 418 | } |
| 418 | static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, | ||
| 419 | void *arg) | ||
| 420 | { | ||
| 421 | struct net_device *dev = arg; | ||
| 422 | struct wireless_dev *wdev; | ||
| 423 | struct wiphy *wiphy; | ||
| 424 | struct ieee80211_hw *hw; | ||
| 425 | struct wl1271 *wl; | ||
| 426 | struct wl1271 *wl_temp; | ||
| 427 | struct wl12xx_vif *wlvif; | ||
| 428 | int ret = 0; | ||
| 429 | |||
| 430 | /* Check that this notification is for us. */ | ||
| 431 | if (what != NETDEV_CHANGE) | ||
| 432 | return NOTIFY_DONE; | ||
| 433 | |||
| 434 | wdev = dev->ieee80211_ptr; | ||
| 435 | if (wdev == NULL) | ||
| 436 | return NOTIFY_DONE; | ||
| 437 | |||
| 438 | wiphy = wdev->wiphy; | ||
| 439 | if (wiphy == NULL) | ||
| 440 | return NOTIFY_DONE; | ||
| 441 | |||
| 442 | hw = wiphy_priv(wiphy); | ||
| 443 | if (hw == NULL) | ||
| 444 | return NOTIFY_DONE; | ||
| 445 | |||
| 446 | wl_temp = hw->priv; | ||
| 447 | mutex_lock(&wl_list_mutex); | ||
| 448 | list_for_each_entry(wl, &wl_list, list) { | ||
| 449 | if (wl == wl_temp) | ||
| 450 | break; | ||
| 451 | } | ||
| 452 | mutex_unlock(&wl_list_mutex); | ||
| 453 | if (wl != wl_temp) | ||
| 454 | return NOTIFY_DONE; | ||
| 455 | |||
| 456 | mutex_lock(&wl->mutex); | ||
| 457 | |||
| 458 | if (wl->state == WL1271_STATE_OFF) | ||
| 459 | goto out; | ||
| 460 | |||
| 461 | if (dev->operstate != IF_OPER_UP) | ||
| 462 | goto out; | ||
| 463 | /* | ||
| 464 | * The correct behavior should be just getting the appropriate wlvif | ||
| 465 | * from the given dev, but currently we don't have a mac80211 | ||
| 466 | * interface for it. | ||
| 467 | */ | ||
| 468 | wl12xx_for_each_wlvif_sta(wl, wlvif) { | ||
| 469 | struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); | ||
| 470 | |||
| 471 | if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) | ||
| 472 | continue; | ||
| 473 | |||
| 474 | ret = wl1271_ps_elp_wakeup(wl); | ||
| 475 | if (ret < 0) | ||
| 476 | goto out; | ||
| 477 | |||
| 478 | wl1271_check_operstate(wl, wlvif, | ||
| 479 | ieee80211_get_operstate(vif)); | ||
| 480 | |||
| 481 | wl1271_ps_elp_sleep(wl); | ||
| 482 | } | ||
| 483 | out: | ||
| 484 | mutex_unlock(&wl->mutex); | ||
| 485 | |||
| 486 | return NOTIFY_OK; | ||
| 487 | } | ||
| 488 | 419 | ||
| 489 | static int wl1271_reg_notify(struct wiphy *wiphy, | 420 | static int wl1271_reg_notify(struct wiphy *wiphy, |
| 490 | struct regulatory_request *request) | 421 | struct regulatory_request *request) |
| @@ -623,6 +554,80 @@ static void wl1271_rx_streaming_timer(unsigned long data) | |||
| 623 | ieee80211_queue_work(wl->hw, &wlvif->rx_streaming_disable_work); | 554 | ieee80211_queue_work(wl->hw, &wlvif->rx_streaming_disable_work); |
| 624 | } | 555 | } |
| 625 | 556 | ||
| 557 | /* wl->mutex must be taken */ | ||
| 558 | void wl12xx_rearm_tx_watchdog_locked(struct wl1271 *wl) | ||
| 559 | { | ||
| 560 | /* if the watchdog is not armed, don't do anything */ | ||
| 561 | if (wl->tx_allocated_blocks == 0) | ||
| 562 | return; | ||
| 563 | |||
| 564 | cancel_delayed_work(&wl->tx_watchdog_work); | ||
| 565 | ieee80211_queue_delayed_work(wl->hw, &wl->tx_watchdog_work, | ||
| 566 | msecs_to_jiffies(wl->conf.tx.tx_watchdog_timeout)); | ||
| 567 | } | ||
| 568 | |||
| 569 | static void wl12xx_tx_watchdog_work(struct work_struct *work) | ||
| 570 | { | ||
| 571 | struct delayed_work *dwork; | ||
| 572 | struct wl1271 *wl; | ||
| 573 | |||
| 574 | dwork = container_of(work, struct delayed_work, work); | ||
| 575 | wl = container_of(dwork, struct wl1271, tx_watchdog_work); | ||
| 576 | |||
| 577 | mutex_lock(&wl->mutex); | ||
| 578 | |||
| 579 | if (unlikely(wl->state == WL1271_STATE_OFF)) | ||
| 580 | goto out; | ||
| 581 | |||
| 582 | /* Tx went out in the meantime - everything is ok */ | ||
| 583 | if (unlikely(wl->tx_allocated_blocks == 0)) | ||
| 584 | goto out; | ||
| 585 | |||
| 586 | /* | ||
| 587 | * if a ROC is in progress, we might not have any Tx for a long | ||
| 588 | * time (e.g. pending Tx on the non-ROC channels) | ||
| 589 | */ | ||
| 590 | if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES) { | ||
| 591 | wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms due to ROC", | ||
| 592 | wl->conf.tx.tx_watchdog_timeout); | ||
| 593 | wl12xx_rearm_tx_watchdog_locked(wl); | ||
| 594 | goto out; | ||
| 595 | } | ||
| 596 | |||
| 597 | /* | ||
| 598 | * if a scan is in progress, we might not have any Tx for a long | ||
| 599 | * time | ||
| 600 | */ | ||
| 601 | if (wl->scan.state != WL1271_SCAN_STATE_IDLE) { | ||
| 602 | wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms due to scan", | ||
| 603 | wl->conf.tx.tx_watchdog_timeout); | ||
| 604 | wl12xx_rearm_tx_watchdog_locked(wl); | ||
| 605 | goto out; | ||
| 606 | } | ||
| 607 | |||
| 608 | /* | ||
| 609 | * AP might cache a frame for a long time for a sleeping station, | ||
| 610 | * so rearm the timer if there's an AP interface with stations. If | ||
| 611 | * Tx is genuinely stuck we will most hopefully discover it when all | ||
| 612 | * stations are removed due to inactivity. | ||
| 613 | */ | ||
| 614 | if (wl->active_sta_count) { | ||
| 615 | wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms. AP has " | ||
| 616 | " %d stations", | ||
| 617 | wl->conf.tx.tx_watchdog_timeout, | ||
| 618 | wl->active_sta_count); | ||
| 619 | wl12xx_rearm_tx_watchdog_locked(wl); | ||
| 620 | goto out; | ||
| 621 | } | ||
| 622 | |||
| 623 | wl1271_error("Tx stuck (in FW) for %d ms. Starting recovery", | ||
| 624 | wl->conf.tx.tx_watchdog_timeout); | ||
| 625 | wl12xx_queue_recovery_work(wl); | ||
| 626 | |||
| 627 | out: | ||
| 628 | mutex_unlock(&wl->mutex); | ||
| 629 | } | ||
| 630 | |||
| 626 | static void wl1271_conf_init(struct wl1271 *wl) | 631 | static void wl1271_conf_init(struct wl1271 *wl) |
| 627 | { | 632 | { |
| 628 | 633 | ||
| @@ -815,6 +820,18 @@ static void wl12xx_fw_status(struct wl1271 *wl, | |||
| 815 | 820 | ||
| 816 | wl->tx_allocated_blocks -= freed_blocks; | 821 | wl->tx_allocated_blocks -= freed_blocks; |
| 817 | 822 | ||
| 823 | /* | ||
| 824 | * If the FW freed some blocks: | ||
| 825 | * If we still have allocated blocks - re-arm the timer, Tx is | ||
| 826 | * not stuck. Otherwise, cancel the timer (no Tx currently). | ||
| 827 | */ | ||
| 828 | if (freed_blocks) { | ||
| 829 | if (wl->tx_allocated_blocks) | ||
| 830 | wl12xx_rearm_tx_watchdog_locked(wl); | ||
| 831 | else | ||
| 832 | cancel_delayed_work(&wl->tx_watchdog_work); | ||
| 833 | } | ||
| 834 | |||
| 818 | avail = le32_to_cpu(status->tx_total) - wl->tx_allocated_blocks; | 835 | avail = le32_to_cpu(status->tx_total) - wl->tx_allocated_blocks; |
| 819 | 836 | ||
| 820 | /* | 837 | /* |
| @@ -1224,7 +1241,8 @@ static void wl1271_recovery_work(struct work_struct *work) | |||
| 1224 | wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x", | 1241 | wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x", |
| 1225 | wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4)); | 1242 | wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4)); |
| 1226 | 1243 | ||
| 1227 | BUG_ON(bug_on_recovery); | 1244 | BUG_ON(bug_on_recovery && |
| 1245 | !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)); | ||
| 1228 | 1246 | ||
| 1229 | /* | 1247 | /* |
| 1230 | * Advance security sequence number to overcome potential progress | 1248 | * Advance security sequence number to overcome potential progress |
| @@ -1487,6 +1505,7 @@ int wl1271_plt_stop(struct wl1271 *wl) | |||
| 1487 | cancel_work_sync(&wl->netstack_work); | 1505 | cancel_work_sync(&wl->netstack_work); |
| 1488 | cancel_work_sync(&wl->recovery_work); | 1506 | cancel_work_sync(&wl->recovery_work); |
| 1489 | cancel_delayed_work_sync(&wl->elp_work); | 1507 | cancel_delayed_work_sync(&wl->elp_work); |
| 1508 | cancel_delayed_work_sync(&wl->tx_watchdog_work); | ||
| 1490 | 1509 | ||
| 1491 | mutex_lock(&wl->mutex); | 1510 | mutex_lock(&wl->mutex); |
| 1492 | wl1271_power_off(wl); | 1511 | wl1271_power_off(wl); |
| @@ -1528,7 +1547,8 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 1528 | goto out; | 1547 | goto out; |
| 1529 | } | 1548 | } |
| 1530 | 1549 | ||
| 1531 | wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d", hlid, q); | 1550 | wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d len %d", |
| 1551 | hlid, q, skb->len); | ||
| 1532 | skb_queue_tail(&wl->links[hlid].tx_queue[q], skb); | 1552 | skb_queue_tail(&wl->links[hlid].tx_queue[q], skb); |
| 1533 | 1553 | ||
| 1534 | wl->tx_queue_count[q]++; | 1554 | wl->tx_queue_count[q]++; |
| @@ -1626,10 +1646,6 @@ static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl) | |||
| 1626 | } | 1646 | } |
| 1627 | 1647 | ||
| 1628 | 1648 | ||
| 1629 | static struct notifier_block wl1271_dev_notifier = { | ||
| 1630 | .notifier_call = wl1271_dev_notify, | ||
| 1631 | }; | ||
| 1632 | |||
| 1633 | #ifdef CONFIG_PM | 1649 | #ifdef CONFIG_PM |
| 1634 | static int wl1271_configure_suspend_sta(struct wl1271 *wl, | 1650 | static int wl1271_configure_suspend_sta(struct wl1271 *wl, |
| 1635 | struct wl12xx_vif *wlvif) | 1651 | struct wl12xx_vif *wlvif) |
| @@ -1737,6 +1753,8 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw, | |||
| 1737 | wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow); | 1753 | wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow); |
| 1738 | WARN_ON(!wow || !wow->any); | 1754 | WARN_ON(!wow || !wow->any); |
| 1739 | 1755 | ||
| 1756 | wl1271_tx_flush(wl); | ||
| 1757 | |||
| 1740 | wl->wow_enabled = true; | 1758 | wl->wow_enabled = true; |
| 1741 | wl12xx_for_each_wlvif(wl, wlvif) { | 1759 | wl12xx_for_each_wlvif(wl, wlvif) { |
| 1742 | ret = wl1271_configure_suspend(wl, wlvif); | 1760 | ret = wl1271_configure_suspend(wl, wlvif); |
| @@ -1854,15 +1872,12 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) | |||
| 1854 | wl->state = WL1271_STATE_OFF; | 1872 | wl->state = WL1271_STATE_OFF; |
| 1855 | mutex_unlock(&wl->mutex); | 1873 | mutex_unlock(&wl->mutex); |
| 1856 | 1874 | ||
| 1857 | mutex_lock(&wl_list_mutex); | ||
| 1858 | list_del(&wl->list); | ||
| 1859 | mutex_unlock(&wl_list_mutex); | ||
| 1860 | |||
| 1861 | wl1271_flush_deferred_work(wl); | 1875 | wl1271_flush_deferred_work(wl); |
| 1862 | cancel_delayed_work_sync(&wl->scan_complete_work); | 1876 | cancel_delayed_work_sync(&wl->scan_complete_work); |
| 1863 | cancel_work_sync(&wl->netstack_work); | 1877 | cancel_work_sync(&wl->netstack_work); |
| 1864 | cancel_work_sync(&wl->tx_work); | 1878 | cancel_work_sync(&wl->tx_work); |
| 1865 | cancel_delayed_work_sync(&wl->elp_work); | 1879 | cancel_delayed_work_sync(&wl->elp_work); |
| 1880 | cancel_delayed_work_sync(&wl->tx_watchdog_work); | ||
| 1866 | 1881 | ||
| 1867 | /* let's notify MAC80211 about the remaining pending TX frames */ | 1882 | /* let's notify MAC80211 about the remaining pending TX frames */ |
| 1868 | wl12xx_tx_reset(wl, true); | 1883 | wl12xx_tx_reset(wl, true); |
| @@ -2209,6 +2224,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, | |||
| 2209 | 2224 | ||
| 2210 | if (wl12xx_need_fw_change(wl, vif_count, true)) { | 2225 | if (wl12xx_need_fw_change(wl, vif_count, true)) { |
| 2211 | wl12xx_force_active_psm(wl); | 2226 | wl12xx_force_active_psm(wl); |
| 2227 | set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags); | ||
| 2212 | mutex_unlock(&wl->mutex); | 2228 | mutex_unlock(&wl->mutex); |
| 2213 | wl1271_recovery_work(&wl->recovery_work); | 2229 | wl1271_recovery_work(&wl->recovery_work); |
| 2214 | return 0; | 2230 | return 0; |
| @@ -2268,11 +2284,6 @@ out: | |||
| 2268 | out_unlock: | 2284 | out_unlock: |
| 2269 | mutex_unlock(&wl->mutex); | 2285 | mutex_unlock(&wl->mutex); |
| 2270 | 2286 | ||
| 2271 | mutex_lock(&wl_list_mutex); | ||
| 2272 | if (!ret) | ||
| 2273 | list_add(&wl->list, &wl_list); | ||
| 2274 | mutex_unlock(&wl_list_mutex); | ||
| 2275 | |||
| 2276 | return ret; | 2287 | return ret; |
| 2277 | } | 2288 | } |
| 2278 | 2289 | ||
| @@ -2296,6 +2307,12 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, | |||
| 2296 | 2307 | ||
| 2297 | if (wl->scan.state != WL1271_SCAN_STATE_IDLE && | 2308 | if (wl->scan.state != WL1271_SCAN_STATE_IDLE && |
| 2298 | wl->scan_vif == vif) { | 2309 | wl->scan_vif == vif) { |
| 2310 | /* | ||
| 2311 | * Rearm the tx watchdog just before idling scan. This | ||
| 2312 | * prevents just-finished scans from triggering the watchdog | ||
| 2313 | */ | ||
| 2314 | wl12xx_rearm_tx_watchdog_locked(wl); | ||
| 2315 | |||
| 2299 | wl->scan.state = WL1271_SCAN_STATE_IDLE; | 2316 | wl->scan.state = WL1271_SCAN_STATE_IDLE; |
| 2300 | memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); | 2317 | memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); |
| 2301 | wl->scan_vif = NULL; | 2318 | wl->scan_vif = NULL; |
| @@ -2398,6 +2415,7 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, | |||
| 2398 | WARN_ON(iter != wlvif); | 2415 | WARN_ON(iter != wlvif); |
| 2399 | if (wl12xx_need_fw_change(wl, vif_count, false)) { | 2416 | if (wl12xx_need_fw_change(wl, vif_count, false)) { |
| 2400 | wl12xx_force_active_psm(wl); | 2417 | wl12xx_force_active_psm(wl); |
| 2418 | set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags); | ||
| 2401 | wl12xx_queue_recovery_work(wl); | 2419 | wl12xx_queue_recovery_work(wl); |
| 2402 | cancel_recovery = false; | 2420 | cancel_recovery = false; |
| 2403 | } | 2421 | } |
| @@ -2417,7 +2435,7 @@ static int wl12xx_op_change_interface(struct ieee80211_hw *hw, | |||
| 2417 | set_bit(WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, &wl->flags); | 2435 | set_bit(WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, &wl->flags); |
| 2418 | wl1271_op_remove_interface(hw, vif); | 2436 | wl1271_op_remove_interface(hw, vif); |
| 2419 | 2437 | ||
| 2420 | vif->type = ieee80211_iftype_p2p(new_type, p2p); | 2438 | vif->type = new_type; |
| 2421 | vif->p2p = p2p; | 2439 | vif->p2p = p2p; |
| 2422 | ret = wl1271_op_add_interface(hw, vif); | 2440 | ret = wl1271_op_add_interface(hw, vif); |
| 2423 | 2441 | ||
| @@ -2596,35 +2614,22 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
| 2596 | wl1271_warning("rate policy for channel " | 2614 | wl1271_warning("rate policy for channel " |
| 2597 | "failed %d", ret); | 2615 | "failed %d", ret); |
| 2598 | 2616 | ||
| 2599 | if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, | 2617 | /* |
| 2600 | &wlvif->flags)) { | 2618 | * change the ROC channel. do it only if we are |
| 2601 | if (wl12xx_dev_role_started(wlvif)) { | 2619 | * not idle. otherwise, CROC will be called |
| 2602 | /* roaming */ | 2620 | * anyway. |
| 2603 | ret = wl12xx_croc(wl, | 2621 | */ |
| 2604 | wlvif->dev_role_id); | 2622 | if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, |
| 2605 | if (ret < 0) | 2623 | &wlvif->flags) && |
| 2606 | return ret; | 2624 | wl12xx_dev_role_started(wlvif) && |
| 2607 | } | 2625 | !(conf->flags & IEEE80211_CONF_IDLE)) { |
| 2608 | ret = wl1271_join(wl, wlvif, false); | 2626 | ret = wl12xx_stop_dev(wl, wlvif); |
| 2609 | if (ret < 0) | 2627 | if (ret < 0) |
| 2610 | wl1271_warning("cmd join on channel " | 2628 | return ret; |
| 2611 | "failed %d", ret); | ||
| 2612 | } else { | ||
| 2613 | /* | ||
| 2614 | * change the ROC channel. do it only if we are | ||
| 2615 | * not idle. otherwise, CROC will be called | ||
| 2616 | * anyway. | ||
| 2617 | */ | ||
| 2618 | if (wl12xx_dev_role_started(wlvif) && | ||
| 2619 | !(conf->flags & IEEE80211_CONF_IDLE)) { | ||
| 2620 | ret = wl12xx_stop_dev(wl, wlvif); | ||
| 2621 | if (ret < 0) | ||
| 2622 | return ret; | ||
| 2623 | 2629 | ||
| 2624 | ret = wl12xx_start_dev(wl, wlvif); | 2630 | ret = wl12xx_start_dev(wl, wlvif); |
| 2625 | if (ret < 0) | 2631 | if (ret < 0) |
| 2626 | return ret; | 2632 | return ret; |
| 2627 | } | ||
| 2628 | } | 2633 | } |
| 2629 | } | 2634 | } |
| 2630 | } | 2635 | } |
| @@ -3151,8 +3156,6 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, | |||
| 3151 | struct cfg80211_scan_request *req) | 3156 | struct cfg80211_scan_request *req) |
| 3152 | { | 3157 | { |
| 3153 | struct wl1271 *wl = hw->priv; | 3158 | struct wl1271 *wl = hw->priv; |
| 3154 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); | ||
| 3155 | |||
| 3156 | int ret; | 3159 | int ret; |
| 3157 | u8 *ssid = NULL; | 3160 | u8 *ssid = NULL; |
| 3158 | size_t len = 0; | 3161 | size_t len = 0; |
| @@ -3180,8 +3183,8 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, | |||
| 3180 | if (ret < 0) | 3183 | if (ret < 0) |
| 3181 | goto out; | 3184 | goto out; |
| 3182 | 3185 | ||
| 3183 | if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) && | 3186 | /* fail if there is any role in ROC */ |
| 3184 | test_bit(wlvif->role_id, wl->roc_map)) { | 3187 | if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES) { |
| 3185 | /* don't allow scanning right now */ | 3188 | /* don't allow scanning right now */ |
| 3186 | ret = -EBUSY; | 3189 | ret = -EBUSY; |
| 3187 | goto out_sleep; | 3190 | goto out_sleep; |
| @@ -3221,6 +3224,13 @@ static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw, | |||
| 3221 | if (ret < 0) | 3224 | if (ret < 0) |
| 3222 | goto out_sleep; | 3225 | goto out_sleep; |
| 3223 | } | 3226 | } |
| 3227 | |||
| 3228 | /* | ||
| 3229 | * Rearm the tx watchdog just before idling scan. This | ||
| 3230 | * prevents just-finished scans from triggering the watchdog | ||
| 3231 | */ | ||
| 3232 | wl12xx_rearm_tx_watchdog_locked(wl); | ||
| 3233 | |||
| 3224 | wl->scan.state = WL1271_SCAN_STATE_IDLE; | 3234 | wl->scan.state = WL1271_SCAN_STATE_IDLE; |
| 3225 | memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); | 3235 | memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); |
| 3226 | wl->scan_vif = NULL; | 3236 | wl->scan_vif = NULL; |
| @@ -3744,10 +3754,8 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, | |||
| 3744 | ibss_joined = true; | 3754 | ibss_joined = true; |
| 3745 | } else { | 3755 | } else { |
| 3746 | if (test_and_clear_bit(WLVIF_FLAG_IBSS_JOINED, | 3756 | if (test_and_clear_bit(WLVIF_FLAG_IBSS_JOINED, |
| 3747 | &wlvif->flags)) { | 3757 | &wlvif->flags)) |
| 3748 | wl1271_unjoin(wl, wlvif); | 3758 | wl1271_unjoin(wl, wlvif); |
| 3749 | wl12xx_start_dev(wl, wlvif); | ||
| 3750 | } | ||
| 3751 | } | 3759 | } |
| 3752 | } | 3760 | } |
| 3753 | 3761 | ||
| @@ -3765,7 +3773,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, | |||
| 3765 | do_join = true; | 3773 | do_join = true; |
| 3766 | } | 3774 | } |
| 3767 | 3775 | ||
| 3768 | if (changed & BSS_CHANGED_IDLE) { | 3776 | if (changed & BSS_CHANGED_IDLE && !is_ibss) { |
| 3769 | ret = wl1271_sta_handle_idle(wl, wlvif, bss_conf->idle); | 3777 | ret = wl1271_sta_handle_idle(wl, wlvif, bss_conf->idle); |
| 3770 | if (ret < 0) | 3778 | if (ret < 0) |
| 3771 | wl1271_warning("idle mode change failed %d", ret); | 3779 | wl1271_warning("idle mode change failed %d", ret); |
| @@ -3821,6 +3829,7 @@ sta_not_found: | |||
| 3821 | u32 rates; | 3829 | u32 rates; |
| 3822 | int ieoffset; | 3830 | int ieoffset; |
| 3823 | wlvif->aid = bss_conf->aid; | 3831 | wlvif->aid = bss_conf->aid; |
| 3832 | wlvif->beacon_int = bss_conf->beacon_int; | ||
| 3824 | set_assoc = true; | 3833 | set_assoc = true; |
| 3825 | 3834 | ||
| 3826 | /* | 3835 | /* |
| @@ -3901,7 +3910,6 @@ sta_not_found: | |||
| 3901 | 3910 | ||
| 3902 | /* restore the bssid filter and go to dummy bssid */ | 3911 | /* restore the bssid filter and go to dummy bssid */ |
| 3903 | if (was_assoc) { | 3912 | if (was_assoc) { |
| 3904 | u32 conf_flags = wl->hw->conf.flags; | ||
| 3905 | /* | 3913 | /* |
| 3906 | * we might have to disable roc, if there was | 3914 | * we might have to disable roc, if there was |
| 3907 | * no IF_OPER_UP notification. | 3915 | * no IF_OPER_UP notification. |
| @@ -3924,7 +3932,7 @@ sta_not_found: | |||
| 3924 | } | 3932 | } |
| 3925 | 3933 | ||
| 3926 | wl1271_unjoin(wl, wlvif); | 3934 | wl1271_unjoin(wl, wlvif); |
| 3927 | if (!(conf_flags & IEEE80211_CONF_IDLE)) | 3935 | if (!bss_conf->idle) |
| 3928 | wl12xx_start_dev(wl, wlvif); | 3936 | wl12xx_start_dev(wl, wlvif); |
| 3929 | } | 3937 | } |
| 3930 | } | 3938 | } |
| @@ -3968,8 +3976,8 @@ sta_not_found: | |||
| 3968 | if (ret < 0) | 3976 | if (ret < 0) |
| 3969 | goto out; | 3977 | goto out; |
| 3970 | 3978 | ||
| 3971 | wl1271_check_operstate(wl, wlvif, | 3979 | if (test_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags)) |
| 3972 | ieee80211_get_operstate(vif)); | 3980 | wl12xx_set_authorized(wl, wlvif); |
| 3973 | } | 3981 | } |
| 3974 | /* | 3982 | /* |
| 3975 | * stop device role if started (we might already be in | 3983 | * stop device role if started (we might already be in |
| @@ -4228,107 +4236,155 @@ void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid) | |||
| 4228 | clear_bit(hlid, wlvif->ap.sta_hlid_map); | 4236 | clear_bit(hlid, wlvif->ap.sta_hlid_map); |
| 4229 | memset(wl->links[hlid].addr, 0, ETH_ALEN); | 4237 | memset(wl->links[hlid].addr, 0, ETH_ALEN); |
| 4230 | wl->links[hlid].ba_bitmap = 0; | 4238 | wl->links[hlid].ba_bitmap = 0; |
| 4231 | wl1271_tx_reset_link_queues(wl, hlid); | ||
| 4232 | __clear_bit(hlid, &wl->ap_ps_map); | 4239 | __clear_bit(hlid, &wl->ap_ps_map); |
| 4233 | __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); | 4240 | __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); |
| 4234 | wl12xx_free_link(wl, wlvif, &hlid); | 4241 | wl12xx_free_link(wl, wlvif, &hlid); |
| 4235 | wl->active_sta_count--; | 4242 | wl->active_sta_count--; |
| 4243 | |||
| 4244 | /* | ||
| 4245 | * rearm the tx watchdog when the last STA is freed - give the FW a | ||
| 4246 | * chance to return STA-buffered packets before complaining. | ||
| 4247 | */ | ||
| 4248 | if (wl->active_sta_count == 0) | ||
| 4249 | wl12xx_rearm_tx_watchdog_locked(wl); | ||
| 4236 | } | 4250 | } |
| 4237 | 4251 | ||
| 4238 | static int wl1271_op_sta_add(struct ieee80211_hw *hw, | 4252 | static int wl12xx_sta_add(struct wl1271 *wl, |
| 4239 | struct ieee80211_vif *vif, | 4253 | struct wl12xx_vif *wlvif, |
| 4240 | struct ieee80211_sta *sta) | 4254 | struct ieee80211_sta *sta) |
| 4241 | { | 4255 | { |
| 4242 | struct wl1271 *wl = hw->priv; | ||
| 4243 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); | ||
| 4244 | struct wl1271_station *wl_sta; | 4256 | struct wl1271_station *wl_sta; |
| 4245 | int ret = 0; | 4257 | int ret = 0; |
| 4246 | u8 hlid; | 4258 | u8 hlid; |
| 4247 | 4259 | ||
| 4248 | mutex_lock(&wl->mutex); | ||
| 4249 | |||
| 4250 | if (unlikely(wl->state == WL1271_STATE_OFF)) | ||
| 4251 | goto out; | ||
| 4252 | |||
| 4253 | if (wlvif->bss_type != BSS_TYPE_AP_BSS) | ||
| 4254 | goto out; | ||
| 4255 | |||
| 4256 | wl1271_debug(DEBUG_MAC80211, "mac80211 add sta %d", (int)sta->aid); | 4260 | wl1271_debug(DEBUG_MAC80211, "mac80211 add sta %d", (int)sta->aid); |
| 4257 | 4261 | ||
| 4258 | ret = wl1271_allocate_sta(wl, wlvif, sta); | 4262 | ret = wl1271_allocate_sta(wl, wlvif, sta); |
| 4259 | if (ret < 0) | 4263 | if (ret < 0) |
| 4260 | goto out; | 4264 | return ret; |
| 4261 | 4265 | ||
| 4262 | wl_sta = (struct wl1271_station *)sta->drv_priv; | 4266 | wl_sta = (struct wl1271_station *)sta->drv_priv; |
| 4263 | hlid = wl_sta->hlid; | 4267 | hlid = wl_sta->hlid; |
| 4264 | 4268 | ||
| 4265 | ret = wl1271_ps_elp_wakeup(wl); | ||
| 4266 | if (ret < 0) | ||
| 4267 | goto out_free_sta; | ||
| 4268 | |||
| 4269 | ret = wl12xx_cmd_add_peer(wl, wlvif, sta, hlid); | 4269 | ret = wl12xx_cmd_add_peer(wl, wlvif, sta, hlid); |
| 4270 | if (ret < 0) | 4270 | if (ret < 0) |
| 4271 | goto out_sleep; | 4271 | wl1271_free_sta(wl, wlvif, hlid); |
| 4272 | 4272 | ||
| 4273 | ret = wl12xx_cmd_set_peer_state(wl, hlid); | 4273 | return ret; |
| 4274 | if (ret < 0) | 4274 | } |
| 4275 | goto out_sleep; | ||
| 4276 | 4275 | ||
| 4277 | ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true, hlid); | 4276 | static int wl12xx_sta_remove(struct wl1271 *wl, |
| 4278 | if (ret < 0) | 4277 | struct wl12xx_vif *wlvif, |
| 4279 | goto out_sleep; | 4278 | struct ieee80211_sta *sta) |
| 4279 | { | ||
| 4280 | struct wl1271_station *wl_sta; | ||
| 4281 | int ret = 0, id; | ||
| 4280 | 4282 | ||
| 4281 | out_sleep: | 4283 | wl1271_debug(DEBUG_MAC80211, "mac80211 remove sta %d", (int)sta->aid); |
| 4282 | wl1271_ps_elp_sleep(wl); | ||
| 4283 | 4284 | ||
| 4284 | out_free_sta: | 4285 | wl_sta = (struct wl1271_station *)sta->drv_priv; |
| 4286 | id = wl_sta->hlid; | ||
| 4287 | if (WARN_ON(!test_bit(id, wlvif->ap.sta_hlid_map))) | ||
| 4288 | return -EINVAL; | ||
| 4289 | |||
| 4290 | ret = wl12xx_cmd_remove_peer(wl, wl_sta->hlid); | ||
| 4285 | if (ret < 0) | 4291 | if (ret < 0) |
| 4286 | wl1271_free_sta(wl, wlvif, hlid); | 4292 | return ret; |
| 4287 | 4293 | ||
| 4288 | out: | 4294 | wl1271_free_sta(wl, wlvif, wl_sta->hlid); |
| 4289 | mutex_unlock(&wl->mutex); | ||
| 4290 | return ret; | 4295 | return ret; |
| 4291 | } | 4296 | } |
| 4292 | 4297 | ||
| 4293 | static int wl1271_op_sta_remove(struct ieee80211_hw *hw, | 4298 | static int wl12xx_update_sta_state(struct wl1271 *wl, |
| 4294 | struct ieee80211_vif *vif, | 4299 | struct wl12xx_vif *wlvif, |
| 4295 | struct ieee80211_sta *sta) | 4300 | struct ieee80211_sta *sta, |
| 4301 | enum ieee80211_sta_state old_state, | ||
| 4302 | enum ieee80211_sta_state new_state) | ||
| 4296 | { | 4303 | { |
| 4297 | struct wl1271 *wl = hw->priv; | ||
| 4298 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); | ||
| 4299 | struct wl1271_station *wl_sta; | 4304 | struct wl1271_station *wl_sta; |
| 4300 | int ret = 0, id; | 4305 | u8 hlid; |
| 4306 | bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS; | ||
| 4307 | bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS; | ||
| 4308 | int ret; | ||
| 4301 | 4309 | ||
| 4302 | mutex_lock(&wl->mutex); | 4310 | wl_sta = (struct wl1271_station *)sta->drv_priv; |
| 4311 | hlid = wl_sta->hlid; | ||
| 4303 | 4312 | ||
| 4304 | if (unlikely(wl->state == WL1271_STATE_OFF)) | 4313 | /* Add station (AP mode) */ |
| 4305 | goto out; | 4314 | if (is_ap && |
| 4315 | old_state == IEEE80211_STA_NOTEXIST && | ||
| 4316 | new_state == IEEE80211_STA_NONE) | ||
| 4317 | return wl12xx_sta_add(wl, wlvif, sta); | ||
| 4318 | |||
| 4319 | /* Remove station (AP mode) */ | ||
| 4320 | if (is_ap && | ||
| 4321 | old_state == IEEE80211_STA_NONE && | ||
| 4322 | new_state == IEEE80211_STA_NOTEXIST) { | ||
| 4323 | /* must not fail */ | ||
| 4324 | wl12xx_sta_remove(wl, wlvif, sta); | ||
| 4325 | return 0; | ||
| 4326 | } | ||
| 4306 | 4327 | ||
| 4307 | if (wlvif->bss_type != BSS_TYPE_AP_BSS) | 4328 | /* Authorize station (AP mode) */ |
| 4308 | goto out; | 4329 | if (is_ap && |
| 4330 | new_state == IEEE80211_STA_AUTHORIZED) { | ||
| 4331 | ret = wl12xx_cmd_set_peer_state(wl, hlid); | ||
| 4332 | if (ret < 0) | ||
| 4333 | return ret; | ||
| 4309 | 4334 | ||
| 4310 | wl1271_debug(DEBUG_MAC80211, "mac80211 remove sta %d", (int)sta->aid); | 4335 | ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true, |
| 4336 | hlid); | ||
| 4337 | return ret; | ||
| 4338 | } | ||
| 4311 | 4339 | ||
| 4312 | wl_sta = (struct wl1271_station *)sta->drv_priv; | 4340 | /* Authorize station */ |
| 4313 | id = wl_sta->hlid; | 4341 | if (is_sta && |
| 4314 | if (WARN_ON(!test_bit(id, wlvif->ap.sta_hlid_map))) | 4342 | new_state == IEEE80211_STA_AUTHORIZED) { |
| 4343 | set_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags); | ||
| 4344 | return wl12xx_set_authorized(wl, wlvif); | ||
| 4345 | } | ||
| 4346 | |||
| 4347 | if (is_sta && | ||
| 4348 | old_state == IEEE80211_STA_AUTHORIZED && | ||
| 4349 | new_state == IEEE80211_STA_ASSOC) { | ||
| 4350 | clear_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags); | ||
| 4351 | return 0; | ||
| 4352 | } | ||
| 4353 | |||
| 4354 | return 0; | ||
| 4355 | } | ||
| 4356 | |||
| 4357 | static int wl12xx_op_sta_state(struct ieee80211_hw *hw, | ||
| 4358 | struct ieee80211_vif *vif, | ||
| 4359 | struct ieee80211_sta *sta, | ||
| 4360 | enum ieee80211_sta_state old_state, | ||
| 4361 | enum ieee80211_sta_state new_state) | ||
| 4362 | { | ||
| 4363 | struct wl1271 *wl = hw->priv; | ||
| 4364 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); | ||
| 4365 | int ret; | ||
| 4366 | |||
| 4367 | wl1271_debug(DEBUG_MAC80211, "mac80211 sta %d state=%d->%d", | ||
| 4368 | sta->aid, old_state, new_state); | ||
| 4369 | |||
| 4370 | mutex_lock(&wl->mutex); | ||
| 4371 | |||
| 4372 | if (unlikely(wl->state == WL1271_STATE_OFF)) { | ||
| 4373 | ret = -EBUSY; | ||
| 4315 | goto out; | 4374 | goto out; |
| 4375 | } | ||
| 4316 | 4376 | ||
| 4317 | ret = wl1271_ps_elp_wakeup(wl); | 4377 | ret = wl1271_ps_elp_wakeup(wl); |
| 4318 | if (ret < 0) | 4378 | if (ret < 0) |
| 4319 | goto out; | 4379 | goto out; |
| 4320 | 4380 | ||
| 4321 | ret = wl12xx_cmd_remove_peer(wl, wl_sta->hlid); | 4381 | ret = wl12xx_update_sta_state(wl, wlvif, sta, old_state, new_state); |
| 4322 | if (ret < 0) | ||
| 4323 | goto out_sleep; | ||
| 4324 | |||
| 4325 | wl1271_free_sta(wl, wlvif, wl_sta->hlid); | ||
| 4326 | 4382 | ||
| 4327 | out_sleep: | ||
| 4328 | wl1271_ps_elp_sleep(wl); | 4383 | wl1271_ps_elp_sleep(wl); |
| 4329 | |||
| 4330 | out: | 4384 | out: |
| 4331 | mutex_unlock(&wl->mutex); | 4385 | mutex_unlock(&wl->mutex); |
| 4386 | if (new_state < old_state) | ||
| 4387 | return 0; | ||
| 4332 | return ret; | 4388 | return ret; |
| 4333 | } | 4389 | } |
| 4334 | 4390 | ||
| @@ -4497,6 +4553,8 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, | |||
| 4497 | 4553 | ||
| 4498 | wl1271_debug(DEBUG_MAC80211, "mac80211 channel switch"); | 4554 | wl1271_debug(DEBUG_MAC80211, "mac80211 channel switch"); |
| 4499 | 4555 | ||
| 4556 | wl1271_tx_flush(wl); | ||
| 4557 | |||
| 4500 | mutex_lock(&wl->mutex); | 4558 | mutex_lock(&wl->mutex); |
| 4501 | 4559 | ||
| 4502 | if (unlikely(wl->state == WL1271_STATE_OFF)) { | 4560 | if (unlikely(wl->state == WL1271_STATE_OFF)) { |
| @@ -4795,8 +4853,7 @@ static const struct ieee80211_ops wl1271_ops = { | |||
| 4795 | .conf_tx = wl1271_op_conf_tx, | 4853 | .conf_tx = wl1271_op_conf_tx, |
| 4796 | .get_tsf = wl1271_op_get_tsf, | 4854 | .get_tsf = wl1271_op_get_tsf, |
| 4797 | .get_survey = wl1271_op_get_survey, | 4855 | .get_survey = wl1271_op_get_survey, |
| 4798 | .sta_add = wl1271_op_sta_add, | 4856 | .sta_state = wl12xx_op_sta_state, |
| 4799 | .sta_remove = wl1271_op_sta_remove, | ||
| 4800 | .ampdu_action = wl1271_op_ampdu_action, | 4857 | .ampdu_action = wl1271_op_ampdu_action, |
| 4801 | .tx_frames_pending = wl1271_tx_frames_pending, | 4858 | .tx_frames_pending = wl1271_tx_frames_pending, |
| 4802 | .set_bitrate_mask = wl12xx_set_bitrate_mask, | 4859 | .set_bitrate_mask = wl12xx_set_bitrate_mask, |
| @@ -5117,8 +5174,6 @@ static int wl1271_register_hw(struct wl1271 *wl) | |||
| 5117 | 5174 | ||
| 5118 | wl1271_debugfs_init(wl); | 5175 | wl1271_debugfs_init(wl); |
| 5119 | 5176 | ||
| 5120 | register_netdevice_notifier(&wl1271_dev_notifier); | ||
| 5121 | |||
| 5122 | wl1271_notice("loaded"); | 5177 | wl1271_notice("loaded"); |
| 5123 | 5178 | ||
| 5124 | out: | 5179 | out: |
| @@ -5130,7 +5185,6 @@ static void wl1271_unregister_hw(struct wl1271 *wl) | |||
| 5130 | if (wl->plt) | 5185 | if (wl->plt) |
| 5131 | wl1271_plt_stop(wl); | 5186 | wl1271_plt_stop(wl); |
| 5132 | 5187 | ||
| 5133 | unregister_netdevice_notifier(&wl1271_dev_notifier); | ||
| 5134 | ieee80211_unregister_hw(wl->hw); | 5188 | ieee80211_unregister_hw(wl->hw); |
| 5135 | wl->mac80211_registered = false; | 5189 | wl->mac80211_registered = false; |
| 5136 | 5190 | ||
| @@ -5251,7 +5305,6 @@ static struct ieee80211_hw *wl1271_alloc_hw(void) | |||
| 5251 | wl = hw->priv; | 5305 | wl = hw->priv; |
| 5252 | memset(wl, 0, sizeof(*wl)); | 5306 | memset(wl, 0, sizeof(*wl)); |
| 5253 | 5307 | ||
| 5254 | INIT_LIST_HEAD(&wl->list); | ||
| 5255 | INIT_LIST_HEAD(&wl->wlvif_list); | 5308 | INIT_LIST_HEAD(&wl->wlvif_list); |
| 5256 | 5309 | ||
| 5257 | wl->hw = hw; | 5310 | wl->hw = hw; |
| @@ -5268,6 +5321,7 @@ static struct ieee80211_hw *wl1271_alloc_hw(void) | |||
| 5268 | INIT_WORK(&wl->tx_work, wl1271_tx_work); | 5321 | INIT_WORK(&wl->tx_work, wl1271_tx_work); |
| 5269 | INIT_WORK(&wl->recovery_work, wl1271_recovery_work); | 5322 | INIT_WORK(&wl->recovery_work, wl1271_recovery_work); |
| 5270 | INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); | 5323 | INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); |
| 5324 | INIT_DELAYED_WORK(&wl->tx_watchdog_work, wl12xx_tx_watchdog_work); | ||
| 5271 | 5325 | ||
| 5272 | wl->freezable_wq = create_freezable_workqueue("wl12xx_wq"); | 5326 | wl->freezable_wq = create_freezable_workqueue("wl12xx_wq"); |
| 5273 | if (!wl->freezable_wq) { | 5327 | if (!wl->freezable_wq) { |
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c index 23d67501c50a..78f598b4f97b 100644 --- a/drivers/net/wireless/wl12xx/ps.c +++ b/drivers/net/wireless/wl12xx/ps.c | |||
| @@ -69,8 +69,6 @@ out: | |||
| 69 | mutex_unlock(&wl->mutex); | 69 | mutex_unlock(&wl->mutex); |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | #define ELP_ENTRY_DELAY 5 | ||
| 73 | |||
| 74 | /* Routines to toggle sleep mode while in ELP */ | 72 | /* Routines to toggle sleep mode while in ELP */ |
| 75 | void wl1271_ps_elp_sleep(struct wl1271 *wl) | 73 | void wl1271_ps_elp_sleep(struct wl1271 *wl) |
| 76 | { | 74 | { |
| @@ -90,7 +88,7 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl) | |||
| 90 | } | 88 | } |
| 91 | 89 | ||
| 92 | ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, | 90 | ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, |
| 93 | msecs_to_jiffies(ELP_ENTRY_DELAY)); | 91 | msecs_to_jiffies(wl->conf.conn.dynamic_ps_timeout)); |
| 94 | } | 92 | } |
| 95 | 93 | ||
| 96 | int wl1271_ps_elp_wakeup(struct wl1271 *wl) | 94 | int wl1271_ps_elp_wakeup(struct wl1271 *wl) |
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index e43a6b2c1d91..fcba055ef196 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c | |||
| @@ -55,6 +55,12 @@ void wl1271_scan_complete_work(struct work_struct *work) | |||
| 55 | vif = wl->scan_vif; | 55 | vif = wl->scan_vif; |
| 56 | wlvif = wl12xx_vif_to_data(vif); | 56 | wlvif = wl12xx_vif_to_data(vif); |
| 57 | 57 | ||
| 58 | /* | ||
| 59 | * Rearm the tx watchdog just before idling scan. This | ||
| 60 | * prevents just-finished scans from triggering the watchdog | ||
| 61 | */ | ||
| 62 | wl12xx_rearm_tx_watchdog_locked(wl); | ||
| 63 | |||
| 58 | wl->scan.state = WL1271_SCAN_STATE_IDLE; | 64 | wl->scan.state = WL1271_SCAN_STATE_IDLE; |
| 59 | memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); | 65 | memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); |
| 60 | wl->scan.req = NULL; | 66 | wl->scan.req = NULL; |
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 6446e4d3e8f9..43ae49143d68 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c | |||
| @@ -226,6 +226,10 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
| 226 | wl->tx_blocks_available -= total_blocks; | 226 | wl->tx_blocks_available -= total_blocks; |
| 227 | wl->tx_allocated_blocks += total_blocks; | 227 | wl->tx_allocated_blocks += total_blocks; |
| 228 | 228 | ||
| 229 | /* If the FW was empty before, arm the Tx watchdog */ | ||
| 230 | if (wl->tx_allocated_blocks == total_blocks) | ||
| 231 | wl12xx_rearm_tx_watchdog_locked(wl); | ||
| 232 | |||
| 229 | ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); | 233 | ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); |
| 230 | wl->tx_allocated_pkts[ac]++; | 234 | wl->tx_allocated_pkts[ac]++; |
| 231 | 235 | ||
| @@ -527,6 +531,7 @@ static struct sk_buff *wl12xx_lnk_skb_dequeue(struct wl1271 *wl, | |||
| 527 | if (skb) { | 531 | if (skb) { |
| 528 | int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); | 532 | int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); |
| 529 | spin_lock_irqsave(&wl->wl_lock, flags); | 533 | spin_lock_irqsave(&wl->wl_lock, flags); |
| 534 | WARN_ON_ONCE(wl->tx_queue_count[q] <= 0); | ||
| 530 | wl->tx_queue_count[q]--; | 535 | wl->tx_queue_count[q]--; |
| 531 | spin_unlock_irqrestore(&wl->wl_lock, flags); | 536 | spin_unlock_irqrestore(&wl->wl_lock, flags); |
| 532 | } | 537 | } |
| @@ -571,6 +576,7 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) | |||
| 571 | struct wl12xx_vif *wlvif = wl->last_wlvif; | 576 | struct wl12xx_vif *wlvif = wl->last_wlvif; |
| 572 | struct sk_buff *skb = NULL; | 577 | struct sk_buff *skb = NULL; |
| 573 | 578 | ||
| 579 | /* continue from last wlvif (round robin) */ | ||
| 574 | if (wlvif) { | 580 | if (wlvif) { |
| 575 | wl12xx_for_each_wlvif_continue(wl, wlvif) { | 581 | wl12xx_for_each_wlvif_continue(wl, wlvif) { |
| 576 | skb = wl12xx_vif_skb_dequeue(wl, wlvif); | 582 | skb = wl12xx_vif_skb_dequeue(wl, wlvif); |
| @@ -581,7 +587,11 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) | |||
| 581 | } | 587 | } |
| 582 | } | 588 | } |
| 583 | 589 | ||
| 584 | /* do another pass */ | 590 | /* dequeue from the system HLID before the restarting wlvif list */ |
| 591 | if (!skb) | ||
| 592 | skb = wl12xx_lnk_skb_dequeue(wl, &wl->links[wl->system_hlid]); | ||
| 593 | |||
| 594 | /* do a new pass over the wlvif list */ | ||
| 585 | if (!skb) { | 595 | if (!skb) { |
| 586 | wl12xx_for_each_wlvif(wl, wlvif) { | 596 | wl12xx_for_each_wlvif(wl, wlvif) { |
| 587 | skb = wl12xx_vif_skb_dequeue(wl, wlvif); | 597 | skb = wl12xx_vif_skb_dequeue(wl, wlvif); |
| @@ -589,12 +599,16 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) | |||
| 589 | wl->last_wlvif = wlvif; | 599 | wl->last_wlvif = wlvif; |
| 590 | break; | 600 | break; |
| 591 | } | 601 | } |
| 602 | |||
| 603 | /* | ||
| 604 | * No need to continue after last_wlvif. The previous | ||
| 605 | * pass should have found it. | ||
| 606 | */ | ||
| 607 | if (wlvif == wl->last_wlvif) | ||
| 608 | break; | ||
| 592 | } | 609 | } |
| 593 | } | 610 | } |
| 594 | 611 | ||
| 595 | if (!skb) | ||
| 596 | skb = wl12xx_lnk_skb_dequeue(wl, &wl->links[wl->system_hlid]); | ||
| 597 | |||
| 598 | if (!skb && | 612 | if (!skb && |
| 599 | test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) { | 613 | test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) { |
| 600 | int q; | 614 | int q; |
| @@ -602,6 +616,7 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) | |||
| 602 | skb = wl->dummy_packet; | 616 | skb = wl->dummy_packet; |
| 603 | q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); | 617 | q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); |
| 604 | spin_lock_irqsave(&wl->wl_lock, flags); | 618 | spin_lock_irqsave(&wl->wl_lock, flags); |
| 619 | WARN_ON_ONCE(wl->tx_queue_count[q] <= 0); | ||
| 605 | wl->tx_queue_count[q]--; | 620 | wl->tx_queue_count[q]--; |
| 606 | spin_unlock_irqrestore(&wl->wl_lock, flags); | 621 | spin_unlock_irqrestore(&wl->wl_lock, flags); |
| 607 | } | 622 | } |
| @@ -959,7 +974,6 @@ void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
| 959 | else | 974 | else |
| 960 | wlvif->sta.ba_rx_bitmap = 0; | 975 | wlvif->sta.ba_rx_bitmap = 0; |
| 961 | 976 | ||
| 962 | wl1271_tx_reset_link_queues(wl, i); | ||
| 963 | wl->links[i].allocated_pkts = 0; | 977 | wl->links[i].allocated_pkts = 0; |
| 964 | wl->links[i].prev_freed_pkts = 0; | 978 | wl->links[i].prev_freed_pkts = 0; |
| 965 | } | 979 | } |
| @@ -973,8 +987,14 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues) | |||
| 973 | struct sk_buff *skb; | 987 | struct sk_buff *skb; |
| 974 | struct ieee80211_tx_info *info; | 988 | struct ieee80211_tx_info *info; |
| 975 | 989 | ||
| 976 | for (i = 0; i < NUM_TX_QUEUES; i++) | 990 | /* only reset the queues if something bad happened */ |
| 977 | wl->tx_queue_count[i] = 0; | 991 | if (WARN_ON_ONCE(wl1271_tx_total_queue_count(wl) != 0)) { |
| 992 | for (i = 0; i < WL12XX_MAX_LINKS; i++) | ||
| 993 | wl1271_tx_reset_link_queues(wl, i); | ||
| 994 | |||
| 995 | for (i = 0; i < NUM_TX_QUEUES; i++) | ||
| 996 | wl->tx_queue_count[i] = 0; | ||
| 997 | } | ||
| 978 | 998 | ||
| 979 | wl->stopped_queues_map = 0; | 999 | wl->stopped_queues_map = 0; |
| 980 | 1000 | ||
| @@ -1024,6 +1044,7 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues) | |||
| 1024 | void wl1271_tx_flush(struct wl1271 *wl) | 1044 | void wl1271_tx_flush(struct wl1271 *wl) |
| 1025 | { | 1045 | { |
| 1026 | unsigned long timeout; | 1046 | unsigned long timeout; |
| 1047 | int i; | ||
| 1027 | timeout = jiffies + usecs_to_jiffies(WL1271_TX_FLUSH_TIMEOUT); | 1048 | timeout = jiffies + usecs_to_jiffies(WL1271_TX_FLUSH_TIMEOUT); |
| 1028 | 1049 | ||
| 1029 | while (!time_after(jiffies, timeout)) { | 1050 | while (!time_after(jiffies, timeout)) { |
| @@ -1041,6 +1062,12 @@ void wl1271_tx_flush(struct wl1271 *wl) | |||
| 1041 | } | 1062 | } |
| 1042 | 1063 | ||
| 1043 | wl1271_warning("Unable to flush all TX buffers, timed out."); | 1064 | wl1271_warning("Unable to flush all TX buffers, timed out."); |
| 1065 | |||
| 1066 | /* forcibly flush all Tx buffers on our queues */ | ||
| 1067 | mutex_lock(&wl->mutex); | ||
| 1068 | for (i = 0; i < WL12XX_MAX_LINKS; i++) | ||
| 1069 | wl1271_tx_reset_link_queues(wl, i); | ||
| 1070 | mutex_unlock(&wl->mutex); | ||
| 1044 | } | 1071 | } |
| 1045 | 1072 | ||
| 1046 | u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set) | 1073 | u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set) |
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h index e3977b55a710..5cf8c32d40d1 100644 --- a/drivers/net/wireless/wl12xx/tx.h +++ b/drivers/net/wireless/wl12xx/tx.h | |||
| @@ -227,5 +227,6 @@ void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids); | |||
| 227 | 227 | ||
| 228 | /* from main.c */ | 228 | /* from main.c */ |
| 229 | void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid); | 229 | void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid); |
| 230 | void wl12xx_rearm_tx_watchdog_locked(struct wl1271 *wl); | ||
| 230 | 231 | ||
| 231 | #endif | 232 | #endif |
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 90352415e2aa..749a15a75d38 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h | |||
| @@ -260,11 +260,13 @@ enum wl12xx_flags { | |||
| 260 | WL1271_FLAG_SOFT_GEMINI, | 260 | WL1271_FLAG_SOFT_GEMINI, |
| 261 | WL1271_FLAG_RECOVERY_IN_PROGRESS, | 261 | WL1271_FLAG_RECOVERY_IN_PROGRESS, |
| 262 | WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, | 262 | WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, |
| 263 | WL1271_FLAG_INTENDED_FW_RECOVERY, | ||
| 263 | }; | 264 | }; |
| 264 | 265 | ||
| 265 | enum wl12xx_vif_flags { | 266 | enum wl12xx_vif_flags { |
| 266 | WLVIF_FLAG_INITIALIZED, | 267 | WLVIF_FLAG_INITIALIZED, |
| 267 | WLVIF_FLAG_STA_ASSOCIATED, | 268 | WLVIF_FLAG_STA_ASSOCIATED, |
| 269 | WLVIF_FLAG_STA_AUTHORIZED, | ||
| 268 | WLVIF_FLAG_IBSS_JOINED, | 270 | WLVIF_FLAG_IBSS_JOINED, |
| 269 | WLVIF_FLAG_AP_STARTED, | 271 | WLVIF_FLAG_AP_STARTED, |
| 270 | WLVIF_FLAG_IN_PS, | 272 | WLVIF_FLAG_IN_PS, |
| @@ -452,8 +454,6 @@ struct wl1271 { | |||
| 452 | 454 | ||
| 453 | bool enable_11a; | 455 | bool enable_11a; |
| 454 | 456 | ||
| 455 | struct list_head list; | ||
| 456 | |||
| 457 | /* Most recently reported noise in dBm */ | 457 | /* Most recently reported noise in dBm */ |
| 458 | s8 noise; | 458 | s8 noise; |
| 459 | 459 | ||
| @@ -495,6 +495,9 @@ struct wl1271 { | |||
| 495 | 495 | ||
| 496 | /* last wlvif we transmitted from */ | 496 | /* last wlvif we transmitted from */ |
| 497 | struct wl12xx_vif *last_wlvif; | 497 | struct wl12xx_vif *last_wlvif; |
| 498 | |||
| 499 | /* work to fire when Tx is stuck */ | ||
| 500 | struct delayed_work tx_watchdog_work; | ||
| 498 | }; | 501 | }; |
| 499 | 502 | ||
| 500 | struct wl1271_station { | 503 | struct wl1271_station { |
diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 1a1500bc8452..cb6204f78300 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c | |||
| @@ -736,6 +736,8 @@ static int pn533_target_found_type_a(struct nfc_target *nfc_tgt, u8 *tgt_data, | |||
| 736 | 736 | ||
| 737 | nfc_tgt->sens_res = be16_to_cpu(tgt_type_a->sens_res); | 737 | nfc_tgt->sens_res = be16_to_cpu(tgt_type_a->sens_res); |
| 738 | nfc_tgt->sel_res = tgt_type_a->sel_res; | 738 | nfc_tgt->sel_res = tgt_type_a->sel_res; |
| 739 | nfc_tgt->nfcid1_len = tgt_type_a->nfcid_len; | ||
| 740 | memcpy(nfc_tgt->nfcid1, tgt_type_a->nfcid_data, nfc_tgt->nfcid1_len); | ||
| 739 | 741 | ||
| 740 | return 0; | 742 | return 0; |
| 741 | } | 743 | } |
| @@ -781,6 +783,9 @@ static int pn533_target_found_felica(struct nfc_target *nfc_tgt, u8 *tgt_data, | |||
| 781 | else | 783 | else |
| 782 | nfc_tgt->supported_protocols = NFC_PROTO_FELICA_MASK; | 784 | nfc_tgt->supported_protocols = NFC_PROTO_FELICA_MASK; |
| 783 | 785 | ||
| 786 | memcpy(nfc_tgt->sensf_res, &tgt_felica->opcode, 9); | ||
| 787 | nfc_tgt->sensf_res_len = 9; | ||
| 788 | |||
| 784 | return 0; | 789 | return 0; |
| 785 | } | 790 | } |
| 786 | 791 | ||
| @@ -823,6 +828,8 @@ static int pn533_target_found_jewel(struct nfc_target *nfc_tgt, u8 *tgt_data, | |||
| 823 | 828 | ||
| 824 | nfc_tgt->supported_protocols = NFC_PROTO_JEWEL_MASK; | 829 | nfc_tgt->supported_protocols = NFC_PROTO_JEWEL_MASK; |
| 825 | nfc_tgt->sens_res = be16_to_cpu(tgt_jewel->sens_res); | 830 | nfc_tgt->sens_res = be16_to_cpu(tgt_jewel->sens_res); |
| 831 | nfc_tgt->nfcid1_len = 4; | ||
| 832 | memcpy(nfc_tgt->nfcid1, tgt_jewel->jewelid, nfc_tgt->nfcid1_len); | ||
| 826 | 833 | ||
| 827 | return 0; | 834 | return 0; |
| 828 | } | 835 | } |
| @@ -902,6 +909,8 @@ static int pn533_target_found(struct pn533 *dev, | |||
| 902 | if (resp->tg != 1) | 909 | if (resp->tg != 1) |
| 903 | return -EPROTO; | 910 | return -EPROTO; |
| 904 | 911 | ||
| 912 | memset(&nfc_tgt, 0, sizeof(struct nfc_target)); | ||
| 913 | |||
| 905 | target_data_len = resp_len - sizeof(struct pn533_poll_response); | 914 | target_data_len = resp_len - sizeof(struct pn533_poll_response); |
| 906 | 915 | ||
| 907 | switch (dev->poll_mod_curr) { | 916 | switch (dev->poll_mod_curr) { |
| @@ -1307,6 +1316,8 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, | |||
| 1307 | nfc_dev_dbg(&dev->interface->dev, "Creating new target"); | 1316 | nfc_dev_dbg(&dev->interface->dev, "Creating new target"); |
| 1308 | 1317 | ||
| 1309 | nfc_target.supported_protocols = NFC_PROTO_NFC_DEP_MASK; | 1318 | nfc_target.supported_protocols = NFC_PROTO_NFC_DEP_MASK; |
| 1319 | nfc_target.nfcid1_len = 10; | ||
| 1320 | memcpy(nfc_target.nfcid1, resp->nfcid3t, nfc_target.nfcid1_len); | ||
| 1310 | rc = nfc_targets_found(dev->nfc_dev, &nfc_target, 1); | 1321 | rc = nfc_targets_found(dev->nfc_dev, &nfc_target, 1); |
| 1311 | if (rc) | 1322 | if (rc) |
| 1312 | return 0; | 1323 | return 0; |
| @@ -1329,21 +1340,15 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, | |||
| 1329 | } | 1340 | } |
| 1330 | 1341 | ||
| 1331 | static int pn533_dep_link_up(struct nfc_dev *nfc_dev, int target_idx, | 1342 | static int pn533_dep_link_up(struct nfc_dev *nfc_dev, int target_idx, |
| 1332 | u8 comm_mode, u8 rf_mode) | 1343 | u8 comm_mode, u8* gb, size_t gb_len) |
| 1333 | { | 1344 | { |
| 1334 | struct pn533 *dev = nfc_get_drvdata(nfc_dev); | 1345 | struct pn533 *dev = nfc_get_drvdata(nfc_dev); |
| 1335 | struct pn533_cmd_jump_dep *cmd; | 1346 | struct pn533_cmd_jump_dep *cmd; |
| 1336 | u8 cmd_len, local_gt_len, *local_gt; | 1347 | u8 cmd_len; |
| 1337 | int rc; | 1348 | int rc; |
| 1338 | 1349 | ||
| 1339 | nfc_dev_dbg(&dev->interface->dev, "%s", __func__); | 1350 | nfc_dev_dbg(&dev->interface->dev, "%s", __func__); |
| 1340 | 1351 | ||
| 1341 | if (rf_mode == NFC_RF_TARGET) { | ||
| 1342 | nfc_dev_err(&dev->interface->dev, "Target mode not supported"); | ||
| 1343 | return -EOPNOTSUPP; | ||
| 1344 | } | ||
| 1345 | |||
| 1346 | |||
| 1347 | if (dev->poll_mod_count) { | 1352 | if (dev->poll_mod_count) { |
| 1348 | nfc_dev_err(&dev->interface->dev, | 1353 | nfc_dev_err(&dev->interface->dev, |
| 1349 | "Cannot bring the DEP link up while polling"); | 1354 | "Cannot bring the DEP link up while polling"); |
| @@ -1356,11 +1361,7 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, int target_idx, | |||
| 1356 | return -EBUSY; | 1361 | return -EBUSY; |
| 1357 | } | 1362 | } |
| 1358 | 1363 | ||
| 1359 | local_gt = nfc_get_local_general_bytes(dev->nfc_dev, &local_gt_len); | 1364 | cmd_len = sizeof(struct pn533_cmd_jump_dep) + gb_len; |
| 1360 | if (local_gt_len > NFC_MAX_GT_LEN) | ||
| 1361 | return -EINVAL; | ||
| 1362 | |||
| 1363 | cmd_len = sizeof(struct pn533_cmd_jump_dep) + local_gt_len; | ||
| 1364 | cmd = kzalloc(cmd_len, GFP_KERNEL); | 1365 | cmd = kzalloc(cmd_len, GFP_KERNEL); |
| 1365 | if (cmd == NULL) | 1366 | if (cmd == NULL) |
| 1366 | return -ENOMEM; | 1367 | return -ENOMEM; |
| @@ -1369,9 +1370,9 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, int target_idx, | |||
| 1369 | 1370 | ||
| 1370 | cmd->active = !comm_mode; | 1371 | cmd->active = !comm_mode; |
| 1371 | cmd->baud = 0; | 1372 | cmd->baud = 0; |
| 1372 | if (local_gt != NULL) { | 1373 | if (gb != NULL && gb_len > 0) { |
| 1373 | cmd->next = 4; /* We have some Gi */ | 1374 | cmd->next = 4; /* We have some Gi */ |
| 1374 | memcpy(cmd->gt, local_gt, local_gt_len); | 1375 | memcpy(cmd->gt, gb, gb_len); |
| 1375 | } else { | 1376 | } else { |
| 1376 | cmd->next = 0; | 1377 | cmd->next = 0; |
| 1377 | } | 1378 | } |
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index befa89eac6f3..ed4124469a3a 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c | |||
| @@ -331,7 +331,6 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) | |||
| 331 | { | 331 | { |
| 332 | int i; | 332 | int i; |
| 333 | u16 v; | 333 | u16 v; |
| 334 | s8 gain; | ||
| 335 | u16 loc[3]; | 334 | u16 loc[3]; |
| 336 | 335 | ||
| 337 | if (out->revision == 3) /* rev 3 moved MAC */ | 336 | if (out->revision == 3) /* rev 3 moved MAC */ |
| @@ -390,20 +389,12 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) | |||
| 390 | SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0); | 389 | SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0); |
| 391 | 390 | ||
| 392 | /* Extract the antenna gain values. */ | 391 | /* Extract the antenna gain values. */ |
| 393 | gain = r123_extract_antgain(out->revision, in, | 392 | out->antenna_gain.a0 = r123_extract_antgain(out->revision, in, |
| 394 | SSB_SPROM1_AGAIN_BG, | 393 | SSB_SPROM1_AGAIN_BG, |
| 395 | SSB_SPROM1_AGAIN_BG_SHIFT); | 394 | SSB_SPROM1_AGAIN_BG_SHIFT); |
| 396 | out->antenna_gain.ghz24.a0 = gain; | 395 | out->antenna_gain.a1 = r123_extract_antgain(out->revision, in, |
| 397 | out->antenna_gain.ghz24.a1 = gain; | 396 | SSB_SPROM1_AGAIN_A, |
| 398 | out->antenna_gain.ghz24.a2 = gain; | 397 | SSB_SPROM1_AGAIN_A_SHIFT); |
| 399 | out->antenna_gain.ghz24.a3 = gain; | ||
| 400 | gain = r123_extract_antgain(out->revision, in, | ||
| 401 | SSB_SPROM1_AGAIN_A, | ||
| 402 | SSB_SPROM1_AGAIN_A_SHIFT); | ||
| 403 | out->antenna_gain.ghz5.a0 = gain; | ||
| 404 | out->antenna_gain.ghz5.a1 = gain; | ||
| 405 | out->antenna_gain.ghz5.a2 = gain; | ||
| 406 | out->antenna_gain.ghz5.a3 = gain; | ||
| 407 | } | 398 | } |
| 408 | 399 | ||
| 409 | /* Revs 4 5 and 8 have partially shared layout */ | 400 | /* Revs 4 5 and 8 have partially shared layout */ |
| @@ -504,16 +495,14 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) | |||
| 504 | } | 495 | } |
| 505 | 496 | ||
| 506 | /* Extract the antenna gain values. */ | 497 | /* Extract the antenna gain values. */ |
| 507 | SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01, | 498 | SPEX(antenna_gain.a0, SSB_SPROM4_AGAIN01, |
| 508 | SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT); | 499 | SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT); |
| 509 | SPEX(antenna_gain.ghz24.a1, SSB_SPROM4_AGAIN01, | 500 | SPEX(antenna_gain.a1, SSB_SPROM4_AGAIN01, |
| 510 | SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT); | 501 | SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT); |
| 511 | SPEX(antenna_gain.ghz24.a2, SSB_SPROM4_AGAIN23, | 502 | SPEX(antenna_gain.a2, SSB_SPROM4_AGAIN23, |
| 512 | SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT); | 503 | SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT); |
| 513 | SPEX(antenna_gain.ghz24.a3, SSB_SPROM4_AGAIN23, | 504 | SPEX(antenna_gain.a3, SSB_SPROM4_AGAIN23, |
| 514 | SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT); | 505 | SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT); |
| 515 | memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24, | ||
| 516 | sizeof(out->antenna_gain.ghz5)); | ||
| 517 | 506 | ||
| 518 | sprom_extract_r458(out, in); | 507 | sprom_extract_r458(out, in); |
| 519 | 508 | ||
| @@ -602,16 +591,14 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in) | |||
| 602 | SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0); | 591 | SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0); |
| 603 | 592 | ||
| 604 | /* Extract the antenna gain values. */ | 593 | /* Extract the antenna gain values. */ |
| 605 | SPEX(antenna_gain.ghz24.a0, SSB_SPROM8_AGAIN01, | 594 | SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01, |
| 606 | SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT); | 595 | SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT); |
| 607 | SPEX(antenna_gain.ghz24.a1, SSB_SPROM8_AGAIN01, | 596 | SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01, |
| 608 | SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT); | 597 | SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT); |
| 609 | SPEX(antenna_gain.ghz24.a2, SSB_SPROM8_AGAIN23, | 598 | SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23, |
| 610 | SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT); | 599 | SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT); |
| 611 | SPEX(antenna_gain.ghz24.a3, SSB_SPROM8_AGAIN23, | 600 | SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23, |
| 612 | SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT); | 601 | SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT); |
| 613 | memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24, | ||
| 614 | sizeof(out->antenna_gain.ghz5)); | ||
| 615 | 602 | ||
| 616 | /* Extract cores power info info */ | 603 | /* Extract cores power info info */ |
| 617 | for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { | 604 | for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { |
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c index c821c6b2a6a0..fbafed5b729b 100644 --- a/drivers/ssb/pcmcia.c +++ b/drivers/ssb/pcmcia.c | |||
| @@ -676,14 +676,10 @@ static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev, | |||
| 676 | case SSB_PCMCIA_CIS_ANTGAIN: | 676 | case SSB_PCMCIA_CIS_ANTGAIN: |
| 677 | GOTO_ERROR_ON(tuple->TupleDataLen != 2, | 677 | GOTO_ERROR_ON(tuple->TupleDataLen != 2, |
| 678 | "antg tpl size"); | 678 | "antg tpl size"); |
| 679 | sprom->antenna_gain.ghz24.a0 = tuple->TupleData[1]; | 679 | sprom->antenna_gain.a0 = tuple->TupleData[1]; |
| 680 | sprom->antenna_gain.ghz24.a1 = tuple->TupleData[1]; | 680 | sprom->antenna_gain.a1 = tuple->TupleData[1]; |
| 681 | sprom->antenna_gain.ghz24.a2 = tuple->TupleData[1]; | 681 | sprom->antenna_gain.a2 = tuple->TupleData[1]; |
| 682 | sprom->antenna_gain.ghz24.a3 = tuple->TupleData[1]; | 682 | sprom->antenna_gain.a3 = tuple->TupleData[1]; |
| 683 | sprom->antenna_gain.ghz5.a0 = tuple->TupleData[1]; | ||
| 684 | sprom->antenna_gain.ghz5.a1 = tuple->TupleData[1]; | ||
| 685 | sprom->antenna_gain.ghz5.a2 = tuple->TupleData[1]; | ||
| 686 | sprom->antenna_gain.ghz5.a3 = tuple->TupleData[1]; | ||
| 687 | break; | 683 | break; |
| 688 | case SSB_PCMCIA_CIS_BFLAGS: | 684 | case SSB_PCMCIA_CIS_BFLAGS: |
| 689 | GOTO_ERROR_ON((tuple->TupleDataLen != 3) && | 685 | GOTO_ERROR_ON((tuple->TupleDataLen != 3) && |
diff --git a/drivers/ssb/sdio.c b/drivers/ssb/sdio.c index 63fd709038ca..b2d36f7736c5 100644 --- a/drivers/ssb/sdio.c +++ b/drivers/ssb/sdio.c | |||
| @@ -551,14 +551,10 @@ int ssb_sdio_get_invariants(struct ssb_bus *bus, | |||
| 551 | case SSB_SDIO_CIS_ANTGAIN: | 551 | case SSB_SDIO_CIS_ANTGAIN: |
| 552 | GOTO_ERROR_ON(tuple->size != 2, | 552 | GOTO_ERROR_ON(tuple->size != 2, |
| 553 | "antg tpl size"); | 553 | "antg tpl size"); |
| 554 | sprom->antenna_gain.ghz24.a0 = tuple->data[1]; | 554 | sprom->antenna_gain.a0 = tuple->data[1]; |
| 555 | sprom->antenna_gain.ghz24.a1 = tuple->data[1]; | 555 | sprom->antenna_gain.a1 = tuple->data[1]; |
| 556 | sprom->antenna_gain.ghz24.a2 = tuple->data[1]; | 556 | sprom->antenna_gain.a2 = tuple->data[1]; |
| 557 | sprom->antenna_gain.ghz24.a3 = tuple->data[1]; | 557 | sprom->antenna_gain.a3 = tuple->data[1]; |
| 558 | sprom->antenna_gain.ghz5.a0 = tuple->data[1]; | ||
| 559 | sprom->antenna_gain.ghz5.a1 = tuple->data[1]; | ||
| 560 | sprom->antenna_gain.ghz5.a2 = tuple->data[1]; | ||
| 561 | sprom->antenna_gain.ghz5.a3 = tuple->data[1]; | ||
| 562 | break; | 558 | break; |
| 563 | case SSB_SDIO_CIS_BFLAGS: | 559 | case SSB_SDIO_CIS_BFLAGS: |
| 564 | GOTO_ERROR_ON((tuple->size != 3) && | 560 | GOTO_ERROR_ON((tuple->size != 3) && |
