linux/drivers/net/wireless/iwlwifi/iwl-io.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved.
   4 *
   5 * Portions of this file are derived from the ipw3945 project.
   6 *
   7 * This program is free software; you can redistribute it and/or modify it
   8 * under the terms of version 2 of the GNU General Public License as
   9 * published by the Free Software Foundation.
  10 *
  11 * This program is distributed in the hope that it will be useful, but WITHOUT
  12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  14 * more details.
  15 *
  16 * You should have received a copy of the GNU General Public License along with
  17 * this program; if not, write to the Free Software Foundation, Inc.,
  18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  19 *
  20 * The full GNU General Public License is included in this distribution in the
  21 * file called LICENSE.
  22 *
  23 * Contact Information:
  24 *  Intel Linux Wireless <ilw@linux.intel.com>
  25 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  26 *
  27 *****************************************************************************/
  28#include <linux/delay.h>
  29#include <linux/device.h>
  30#include <linux/export.h>
  31
  32#include "iwl-drv.h"
  33#include "iwl-io.h"
  34#include "iwl-csr.h"
  35#include "iwl-debug.h"
  36
  37#define IWL_POLL_INTERVAL 10    /* microseconds */
  38
  39int iwl_poll_bit(struct iwl_trans *trans, u32 addr,
  40                 u32 bits, u32 mask, int timeout)
  41{
  42        int t = 0;
  43
  44        do {
  45                if ((iwl_read32(trans, addr) & mask) == (bits & mask))
  46                        return t;
  47                udelay(IWL_POLL_INTERVAL);
  48                t += IWL_POLL_INTERVAL;
  49        } while (t < timeout);
  50
  51        return -ETIMEDOUT;
  52}
  53IWL_EXPORT_SYMBOL(iwl_poll_bit);
  54
  55u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg)
  56{
  57        u32 value = 0x5a5a5a5a;
  58        unsigned long flags;
  59        if (iwl_trans_grab_nic_access(trans, false, &flags)) {
  60                value = iwl_read32(trans, reg);
  61                iwl_trans_release_nic_access(trans, &flags);
  62        }
  63
  64        return value;
  65}
  66IWL_EXPORT_SYMBOL(iwl_read_direct32);
  67
  68void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value)
  69{
  70        unsigned long flags;
  71
  72        if (iwl_trans_grab_nic_access(trans, false, &flags)) {
  73                iwl_write32(trans, reg, value);
  74                iwl_trans_release_nic_access(trans, &flags);
  75        }
  76}
  77IWL_EXPORT_SYMBOL(iwl_write_direct32);
  78
  79int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask,
  80                        int timeout)
  81{
  82        int t = 0;
  83
  84        do {
  85                if ((iwl_read_direct32(trans, addr) & mask) == mask)
  86                        return t;
  87                udelay(IWL_POLL_INTERVAL);
  88                t += IWL_POLL_INTERVAL;
  89        } while (t < timeout);
  90
  91        return -ETIMEDOUT;
  92}
  93IWL_EXPORT_SYMBOL(iwl_poll_direct_bit);
  94
  95static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 ofs)
  96{
  97        u32 val = iwl_trans_read_prph(trans, ofs);
  98        trace_iwlwifi_dev_ioread_prph32(trans->dev, ofs, val);
  99        return val;
 100}
 101
 102static inline void __iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val)
 103{
 104        trace_iwlwifi_dev_iowrite_prph32(trans->dev, ofs, val);
 105        iwl_trans_write_prph(trans, ofs, val);
 106}
 107
 108u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs)
 109{
 110        unsigned long flags;
 111        u32 val = 0x5a5a5a5a;
 112
 113        if (iwl_trans_grab_nic_access(trans, false, &flags)) {
 114                val = __iwl_read_prph(trans, ofs);
 115                iwl_trans_release_nic_access(trans, &flags);
 116        }
 117        return val;
 118}
 119IWL_EXPORT_SYMBOL(iwl_read_prph);
 120
 121void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val)
 122{
 123        unsigned long flags;
 124
 125        if (iwl_trans_grab_nic_access(trans, false, &flags)) {
 126                __iwl_write_prph(trans, ofs, val);
 127                iwl_trans_release_nic_access(trans, &flags);
 128        }
 129}
 130IWL_EXPORT_SYMBOL(iwl_write_prph);
 131
 132void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
 133{
 134        unsigned long flags;
 135
 136        if (iwl_trans_grab_nic_access(trans, false, &flags)) {
 137                __iwl_write_prph(trans, ofs,
 138                                 __iwl_read_prph(trans, ofs) | mask);
 139                iwl_trans_release_nic_access(trans, &flags);
 140        }
 141}
 142IWL_EXPORT_SYMBOL(iwl_set_bits_prph);
 143
 144void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
 145                            u32 bits, u32 mask)
 146{
 147        unsigned long flags;
 148
 149        if (iwl_trans_grab_nic_access(trans, false, &flags)) {
 150                __iwl_write_prph(trans, ofs,
 151                                 (__iwl_read_prph(trans, ofs) & mask) | bits);
 152                iwl_trans_release_nic_access(trans, &flags);
 153        }
 154}
 155IWL_EXPORT_SYMBOL(iwl_set_bits_mask_prph);
 156
 157void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
 158{
 159        unsigned long flags;
 160        u32 val;
 161
 162        if (iwl_trans_grab_nic_access(trans, false, &flags)) {
 163                val = __iwl_read_prph(trans, ofs);
 164                __iwl_write_prph(trans, ofs, (val & ~mask));
 165                iwl_trans_release_nic_access(trans, &flags);
 166        }
 167}
 168IWL_EXPORT_SYMBOL(iwl_clear_bits_prph);
 169