102a7fa00a6d145037d549c779ad7692deb504accJohannes Berg/****************************************************************************** 202a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * 34e3182626a914443a5e0fbe014813f03e51a75dfWey-Yi Guy * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. 402a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * 502a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * Portions of this file are derived from the ipw3945 project. 602a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * 702a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * This program is free software; you can redistribute it and/or modify it 802a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * under the terms of version 2 of the GNU General Public License as 902a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * published by the Free Software Foundation. 1002a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * 1102a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * This program is distributed in the hope that it will be useful, but WITHOUT 1202a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1302a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 1402a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * more details. 1502a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * 1602a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * You should have received a copy of the GNU General Public License along with 1702a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * this program; if not, write to the Free Software Foundation, Inc., 1802a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 1902a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * 2002a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * The full GNU General Public License is included in this distribution in the 2102a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * file called LICENSE. 2202a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * 2302a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * Contact Information: 2402a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * Intel Linux Wireless <ilw@linux.intel.com> 2502a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 2602a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * 2702a7fa00a6d145037d549c779ad7692deb504accJohannes Berg *****************************************************************************/ 2883ed90155f98bd949735c2cc22d832b557a6d7d1Emmanuel Grumbach#include <linux/delay.h> 2983ed90155f98bd949735c2cc22d832b557a6d7d1Emmanuel Grumbach#include <linux/device.h> 3002a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 3102a7fa00a6d145037d549c779ad7692deb504accJohannes Berg#include "iwl-io.h" 3283ed90155f98bd949735c2cc22d832b557a6d7d1Emmanuel Grumbach#include"iwl-csr.h" 3383ed90155f98bd949735c2cc22d832b557a6d7d1Emmanuel Grumbach#include "iwl-debug.h" 3402a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 3502a7fa00a6d145037d549c779ad7692deb504accJohannes Berg#define IWL_POLL_INTERVAL 10 /* microseconds */ 3602a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 371042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbachstatic inline void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask) 3802a7fa00a6d145037d549c779ad7692deb504accJohannes Berg{ 391042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach iwl_write32(trans, reg, iwl_read32(trans, reg) | mask); 4002a7fa00a6d145037d549c779ad7692deb504accJohannes Berg} 4102a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 421042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbachstatic inline void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) 4302a7fa00a6d145037d549c779ad7692deb504accJohannes Berg{ 441042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach iwl_write32(trans, reg, iwl_read32(trans, reg) & ~mask); 4502a7fa00a6d145037d549c779ad7692deb504accJohannes Berg} 4602a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 471042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbachvoid iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask) 4802a7fa00a6d145037d549c779ad7692deb504accJohannes Berg{ 4902a7fa00a6d145037d549c779ad7692deb504accJohannes Berg unsigned long flags; 5002a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 511042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_lock_irqsave(&trans->reg_lock, flags); 521042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach __iwl_set_bit(trans, reg, mask); 531042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_unlock_irqrestore(&trans->reg_lock, flags); 5402a7fa00a6d145037d549c779ad7692deb504accJohannes Berg} 5502a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 561042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbachvoid iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) 5702a7fa00a6d145037d549c779ad7692deb504accJohannes Berg{ 5802a7fa00a6d145037d549c779ad7692deb504accJohannes Berg unsigned long flags; 5902a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 601042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_lock_irqsave(&trans->reg_lock, flags); 611042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach __iwl_clear_bit(trans, reg, mask); 621042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_unlock_irqrestore(&trans->reg_lock, flags); 6302a7fa00a6d145037d549c779ad7692deb504accJohannes Berg} 6402a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 651042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbachint iwl_poll_bit(struct iwl_trans *trans, u32 addr, 6602a7fa00a6d145037d549c779ad7692deb504accJohannes Berg u32 bits, u32 mask, int timeout) 6702a7fa00a6d145037d549c779ad7692deb504accJohannes Berg{ 6802a7fa00a6d145037d549c779ad7692deb504accJohannes Berg int t = 0; 6902a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 7002a7fa00a6d145037d549c779ad7692deb504accJohannes Berg do { 711042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach if ((iwl_read32(trans, addr) & mask) == (bits & mask)) 7202a7fa00a6d145037d549c779ad7692deb504accJohannes Berg return t; 7302a7fa00a6d145037d549c779ad7692deb504accJohannes Berg udelay(IWL_POLL_INTERVAL); 7402a7fa00a6d145037d549c779ad7692deb504accJohannes Berg t += IWL_POLL_INTERVAL; 7502a7fa00a6d145037d549c779ad7692deb504accJohannes Berg } while (t < timeout); 7602a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 7702a7fa00a6d145037d549c779ad7692deb504accJohannes Berg return -ETIMEDOUT; 7802a7fa00a6d145037d549c779ad7692deb504accJohannes Berg} 7902a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 801042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbachint iwl_grab_nic_access_silent(struct iwl_trans *trans) 8102a7fa00a6d145037d549c779ad7692deb504accJohannes Berg{ 8202a7fa00a6d145037d549c779ad7692deb504accJohannes Berg int ret; 8302a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 841042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach lockdep_assert_held(&trans->reg_lock); 8502a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 8602a7fa00a6d145037d549c779ad7692deb504accJohannes Berg /* this bit wakes up the NIC */ 871042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach __iwl_set_bit(trans, CSR_GP_CNTRL, 881042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 8902a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 9002a7fa00a6d145037d549c779ad7692deb504accJohannes Berg /* 9102a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * These bits say the device is running, and should keep running for 9202a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * at least a short while (at least as long as MAC_ACCESS_REQ stays 1), 9302a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * but they do not indicate that embedded SRAM is restored yet; 9402a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * 3945 and 4965 have volatile SRAM, and must save/restore contents 9502a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * to/from host DRAM when sleeping/waking for power-saving. 9602a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * Each direction takes approximately 1/4 millisecond; with this 9702a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a 9802a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * series of register accesses are expected (e.g. reading Event Log), 9902a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * to keep device from sleeping. 10002a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * 10102a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that 10202a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * SRAM is okay/restored. We don't check that here because this call 10302a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * is just for hardware register access; but GP1 MAC_SLEEP check is a 10402a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log). 10502a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * 10602a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * 5000 series and later (including 1000 series) have non-volatile SRAM, 10702a7fa00a6d145037d549c779ad7692deb504accJohannes Berg * and do not save/restore SRAM when power cycling. 10802a7fa00a6d145037d549c779ad7692deb504accJohannes Berg */ 1091042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach ret = iwl_poll_bit(trans, CSR_GP_CNTRL, 11002a7fa00a6d145037d549c779ad7692deb504accJohannes Berg CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, 11102a7fa00a6d145037d549c779ad7692deb504accJohannes Berg (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | 11202a7fa00a6d145037d549c779ad7692deb504accJohannes Berg CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); 11302a7fa00a6d145037d549c779ad7692deb504accJohannes Berg if (ret < 0) { 1141042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); 11502a7fa00a6d145037d549c779ad7692deb504accJohannes Berg return -EIO; 11602a7fa00a6d145037d549c779ad7692deb504accJohannes Berg } 11702a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 11802a7fa00a6d145037d549c779ad7692deb504accJohannes Berg return 0; 11902a7fa00a6d145037d549c779ad7692deb504accJohannes Berg} 12002a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 121bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszkabool iwl_grab_nic_access(struct iwl_trans *trans) 1224119904f3ebf30c25afb42195740f9ee5dc7749cJohannes Berg{ 1231042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach int ret = iwl_grab_nic_access_silent(trans); 124aa5affbacb24cb5d8fd6f7c66e57d62164ed6d34Stanislaw Gruszka if (unlikely(ret)) { 1251042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach u32 val = iwl_read32(trans, CSR_GP_CNTRL); 126aa5affbacb24cb5d8fd6f7c66e57d62164ed6d34Stanislaw Gruszka WARN_ONCE(1, "Timeout waiting for hardware access " 127aa5affbacb24cb5d8fd6f7c66e57d62164ed6d34Stanislaw Gruszka "(CSR_GP_CNTRL 0x%08x)\n", val); 128bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka return false; 1294119904f3ebf30c25afb42195740f9ee5dc7749cJohannes Berg } 1304119904f3ebf30c25afb42195740f9ee5dc7749cJohannes Berg 131bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka return true; 1324119904f3ebf30c25afb42195740f9ee5dc7749cJohannes Berg} 1334119904f3ebf30c25afb42195740f9ee5dc7749cJohannes Berg 1341042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbachvoid iwl_release_nic_access(struct iwl_trans *trans) 13502a7fa00a6d145037d549c779ad7692deb504accJohannes Berg{ 1361042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach lockdep_assert_held(&trans->reg_lock); 1371042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach __iwl_clear_bit(trans, CSR_GP_CNTRL, 13802a7fa00a6d145037d549c779ad7692deb504accJohannes Berg CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 1393a73a30049f20a0ff3ef1c5c10170a9c5539e042Stanislaw Gruszka /* 1403a73a30049f20a0ff3ef1c5c10170a9c5539e042Stanislaw Gruszka * Above we read the CSR_GP_CNTRL register, which will flush 1413a73a30049f20a0ff3ef1c5c10170a9c5539e042Stanislaw Gruszka * any previous writes, but we need the write that clears the 1423a73a30049f20a0ff3ef1c5c10170a9c5539e042Stanislaw Gruszka * MAC_ACCESS_REQ bit to be performed before any other writes 1433a73a30049f20a0ff3ef1c5c10170a9c5539e042Stanislaw Gruszka * scheduled on different CPUs (after we drop reg_lock). 1443a73a30049f20a0ff3ef1c5c10170a9c5539e042Stanislaw Gruszka */ 1453a73a30049f20a0ff3ef1c5c10170a9c5539e042Stanislaw Gruszka mmiowb(); 14602a7fa00a6d145037d549c779ad7692deb504accJohannes Berg} 14702a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 1481042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbachu32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) 14902a7fa00a6d145037d549c779ad7692deb504accJohannes Berg{ 15002a7fa00a6d145037d549c779ad7692deb504accJohannes Berg u32 value; 15102a7fa00a6d145037d549c779ad7692deb504accJohannes Berg unsigned long flags; 15202a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 1531042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_lock_irqsave(&trans->reg_lock, flags); 1541042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach iwl_grab_nic_access(trans); 1551042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach value = iwl_read32(trans, reg); 1561042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach iwl_release_nic_access(trans); 1571042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_unlock_irqrestore(&trans->reg_lock, flags); 15802a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 15902a7fa00a6d145037d549c779ad7692deb504accJohannes Berg return value; 16002a7fa00a6d145037d549c779ad7692deb504accJohannes Berg} 16102a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 1621042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbachvoid iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) 16302a7fa00a6d145037d549c779ad7692deb504accJohannes Berg{ 16402a7fa00a6d145037d549c779ad7692deb504accJohannes Berg unsigned long flags; 16502a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 1661042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_lock_irqsave(&trans->reg_lock, flags); 167bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka if (likely(iwl_grab_nic_access(trans))) { 1681042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach iwl_write32(trans, reg, value); 1691042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach iwl_release_nic_access(trans); 17002a7fa00a6d145037d549c779ad7692deb504accJohannes Berg } 1711042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_unlock_irqrestore(&trans->reg_lock, flags); 17202a7fa00a6d145037d549c779ad7692deb504accJohannes Berg} 17302a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 1741042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbachint iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, 17502a7fa00a6d145037d549c779ad7692deb504accJohannes Berg int timeout) 17602a7fa00a6d145037d549c779ad7692deb504accJohannes Berg{ 17702a7fa00a6d145037d549c779ad7692deb504accJohannes Berg int t = 0; 17802a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 17902a7fa00a6d145037d549c779ad7692deb504accJohannes Berg do { 1801042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach if ((iwl_read_direct32(trans, addr) & mask) == mask) 18102a7fa00a6d145037d549c779ad7692deb504accJohannes Berg return t; 18202a7fa00a6d145037d549c779ad7692deb504accJohannes Berg udelay(IWL_POLL_INTERVAL); 18302a7fa00a6d145037d549c779ad7692deb504accJohannes Berg t += IWL_POLL_INTERVAL; 18402a7fa00a6d145037d549c779ad7692deb504accJohannes Berg } while (t < timeout); 18502a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 18602a7fa00a6d145037d549c779ad7692deb504accJohannes Berg return -ETIMEDOUT; 18702a7fa00a6d145037d549c779ad7692deb504accJohannes Berg} 18802a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 1891042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbachstatic inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 reg) 19002a7fa00a6d145037d549c779ad7692deb504accJohannes Berg{ 1911042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach iwl_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); 1921042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach return iwl_read32(trans, HBUS_TARG_PRPH_RDAT); 19302a7fa00a6d145037d549c779ad7692deb504accJohannes Berg} 19402a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 1951042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbachstatic inline void __iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) 19602a7fa00a6d145037d549c779ad7692deb504accJohannes Berg{ 1971042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach iwl_write32(trans, HBUS_TARG_PRPH_WADDR, 19802a7fa00a6d145037d549c779ad7692deb504accJohannes Berg ((addr & 0x0000FFFF) | (3 << 24))); 1991042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); 20002a7fa00a6d145037d549c779ad7692deb504accJohannes Berg} 20102a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 2021042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbachu32 iwl_read_prph(struct iwl_trans *trans, u32 reg) 20302a7fa00a6d145037d549c779ad7692deb504accJohannes Berg{ 20402a7fa00a6d145037d549c779ad7692deb504accJohannes Berg unsigned long flags; 20502a7fa00a6d145037d549c779ad7692deb504accJohannes Berg u32 val; 20602a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 2071042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_lock_irqsave(&trans->reg_lock, flags); 2081042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach iwl_grab_nic_access(trans); 2091042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach val = __iwl_read_prph(trans, reg); 2101042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach iwl_release_nic_access(trans); 2111042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_unlock_irqrestore(&trans->reg_lock, flags); 21202a7fa00a6d145037d549c779ad7692deb504accJohannes Berg return val; 21302a7fa00a6d145037d549c779ad7692deb504accJohannes Berg} 21402a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 2151042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbachvoid iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) 21602a7fa00a6d145037d549c779ad7692deb504accJohannes Berg{ 21702a7fa00a6d145037d549c779ad7692deb504accJohannes Berg unsigned long flags; 21802a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 2191042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_lock_irqsave(&trans->reg_lock, flags); 220bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka if (likely(iwl_grab_nic_access(trans))) { 2211042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach __iwl_write_prph(trans, addr, val); 2221042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach iwl_release_nic_access(trans); 22302a7fa00a6d145037d549c779ad7692deb504accJohannes Berg } 2241042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_unlock_irqrestore(&trans->reg_lock, flags); 22502a7fa00a6d145037d549c779ad7692deb504accJohannes Berg} 22602a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 2271042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbachvoid iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) 22802a7fa00a6d145037d549c779ad7692deb504accJohannes Berg{ 22902a7fa00a6d145037d549c779ad7692deb504accJohannes Berg unsigned long flags; 23002a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 2311042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_lock_irqsave(&trans->reg_lock, flags); 232bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka if (likely(iwl_grab_nic_access(trans))) { 233bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka __iwl_write_prph(trans, reg, 234bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka __iwl_read_prph(trans, reg) | mask); 235bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka iwl_release_nic_access(trans); 236bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka } 2371042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_unlock_irqrestore(&trans->reg_lock, flags); 23802a7fa00a6d145037d549c779ad7692deb504accJohannes Berg} 23902a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 2401042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbachvoid iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg, 24102a7fa00a6d145037d549c779ad7692deb504accJohannes Berg u32 bits, u32 mask) 24202a7fa00a6d145037d549c779ad7692deb504accJohannes Berg{ 24302a7fa00a6d145037d549c779ad7692deb504accJohannes Berg unsigned long flags; 24402a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 2451042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_lock_irqsave(&trans->reg_lock, flags); 246bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka if (likely(iwl_grab_nic_access(trans))) { 247bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka __iwl_write_prph(trans, reg, 248bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka (__iwl_read_prph(trans, reg) & mask) | bits); 249bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka iwl_release_nic_access(trans); 250bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka } 2511042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_unlock_irqrestore(&trans->reg_lock, flags); 25202a7fa00a6d145037d549c779ad7692deb504accJohannes Berg} 25302a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 2541042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbachvoid iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) 25502a7fa00a6d145037d549c779ad7692deb504accJohannes Berg{ 25602a7fa00a6d145037d549c779ad7692deb504accJohannes Berg unsigned long flags; 25702a7fa00a6d145037d549c779ad7692deb504accJohannes Berg u32 val; 25802a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 2591042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_lock_irqsave(&trans->reg_lock, flags); 260bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka if (likely(iwl_grab_nic_access(trans))) { 261bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka val = __iwl_read_prph(trans, reg); 262bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka __iwl_write_prph(trans, reg, (val & ~mask)); 263bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka iwl_release_nic_access(trans); 264bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka } 2651042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_unlock_irqrestore(&trans->reg_lock, flags); 26602a7fa00a6d145037d549c779ad7692deb504accJohannes Berg} 26702a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 2681042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbachvoid _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, 269e46f6538c24f01bb68dc374358ce85a0af666682Johannes Berg void *buf, int words) 27002a7fa00a6d145037d549c779ad7692deb504accJohannes Berg{ 27102a7fa00a6d145037d549c779ad7692deb504accJohannes Berg unsigned long flags; 272e46f6538c24f01bb68dc374358ce85a0af666682Johannes Berg int offs; 273e46f6538c24f01bb68dc374358ce85a0af666682Johannes Berg u32 *vals = buf; 27402a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 2751042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_lock_irqsave(&trans->reg_lock, flags); 276bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka if (likely(iwl_grab_nic_access(trans))) { 277bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); 278bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka for (offs = 0; offs < words; offs++) 279bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); 280bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka iwl_release_nic_access(trans); 281bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka } 2821042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_unlock_irqrestore(&trans->reg_lock, flags); 283e46f6538c24f01bb68dc374358ce85a0af666682Johannes Berg} 284e46f6538c24f01bb68dc374358ce85a0af666682Johannes Berg 2851042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbachu32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr) 286e46f6538c24f01bb68dc374358ce85a0af666682Johannes Berg{ 287e46f6538c24f01bb68dc374358ce85a0af666682Johannes Berg u32 value; 288e46f6538c24f01bb68dc374358ce85a0af666682Johannes Berg 2891042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach _iwl_read_targ_mem_words(trans, addr, &value, 1); 290e46f6538c24f01bb68dc374358ce85a0af666682Johannes Berg 29102a7fa00a6d145037d549c779ad7692deb504accJohannes Berg return value; 29202a7fa00a6d145037d549c779ad7692deb504accJohannes Berg} 29302a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 2941042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbachint _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, 295ee8ba8800b4f20845aa542ce53f3bc29064674b5Hsu, Kenny void *buf, int words) 29602a7fa00a6d145037d549c779ad7692deb504accJohannes Berg{ 29702a7fa00a6d145037d549c779ad7692deb504accJohannes Berg unsigned long flags; 298ee8ba8800b4f20845aa542ce53f3bc29064674b5Hsu, Kenny int offs, result = 0; 299ee8ba8800b4f20845aa542ce53f3bc29064674b5Hsu, Kenny u32 *vals = buf; 30002a7fa00a6d145037d549c779ad7692deb504accJohannes Berg 3011042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_lock_irqsave(&trans->reg_lock, flags); 302bfe4b80e9f7385f34986736cdc094be56782109aStanislaw Gruszka if (likely(iwl_grab_nic_access(trans))) { 3031042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); 304ee8ba8800b4f20845aa542ce53f3bc29064674b5Hsu, Kenny for (offs = 0; offs < words; offs++) 3051042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]); 3061042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach iwl_release_nic_access(trans); 307ee8ba8800b4f20845aa542ce53f3bc29064674b5Hsu, Kenny } else 308ee8ba8800b4f20845aa542ce53f3bc29064674b5Hsu, Kenny result = -EBUSY; 3091042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach spin_unlock_irqrestore(&trans->reg_lock, flags); 310ee8ba8800b4f20845aa542ce53f3bc29064674b5Hsu, Kenny 311ee8ba8800b4f20845aa542ce53f3bc29064674b5Hsu, Kenny return result; 312ee8ba8800b4f20845aa542ce53f3bc29064674b5Hsu, Kenny} 313ee8ba8800b4f20845aa542ce53f3bc29064674b5Hsu, Kenny 3141042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbachint iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val) 315ee8ba8800b4f20845aa542ce53f3bc29064674b5Hsu, Kenny{ 3161042db2af183b96cdce5972014d85e8bca0634adEmmanuel Grumbach return _iwl_write_targ_mem_words(trans, addr, &val, 1); 31702a7fa00a6d145037d549c779ad7692deb504accJohannes Berg} 318