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