|  | /* | 
|  | * Atheros AR9170 driver | 
|  | * | 
|  | * Basic HW register/memory/command access functions | 
|  | * | 
|  | * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> | 
|  | * | 
|  | * This program is free software; you can redistribute it and/or modify | 
|  | * it under the terms of the GNU General Public License as published by | 
|  | * the Free Software Foundation; either version 2 of the License, or | 
|  | * (at your option) any later version. | 
|  | * | 
|  | * This program is distributed in the hope that it will be useful, | 
|  | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | * GNU General Public License for more details. | 
|  | * | 
|  | * You should have received a copy of the GNU General Public License | 
|  | * along with this program; see the file COPYING.  If not, see | 
|  | * http://www.gnu.org/licenses/. | 
|  | * | 
|  | * This file incorporates work covered by the following copyright and | 
|  | * permission notice: | 
|  | *    Copyright (c) 2007-2008 Atheros Communications, Inc. | 
|  | * | 
|  | *    Permission to use, copy, modify, and/or distribute this software for any | 
|  | *    purpose with or without fee is hereby granted, provided that the above | 
|  | *    copyright notice and this permission notice appear in all copies. | 
|  | * | 
|  | *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | 
|  | *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | 
|  | *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | 
|  | *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | 
|  | *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | 
|  | *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | 
|  | *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 
|  | */ | 
|  |  | 
|  | #include "ar9170.h" | 
|  | #include "cmd.h" | 
|  |  | 
|  | int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len) | 
|  | { | 
|  | int err; | 
|  |  | 
|  | if (unlikely(!IS_ACCEPTING_CMD(ar))) | 
|  | return 0; | 
|  |  | 
|  | err = ar->exec_cmd(ar, AR9170_CMD_WMEM, len, (u8 *) data, 0, NULL); | 
|  | if (err) | 
|  | printk(KERN_DEBUG "%s: writing memory failed\n", | 
|  | wiphy_name(ar->hw->wiphy)); | 
|  | return err; | 
|  | } | 
|  |  | 
|  | int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val) | 
|  | { | 
|  | __le32 buf[2] = { | 
|  | cpu_to_le32(reg), | 
|  | cpu_to_le32(val), | 
|  | }; | 
|  | int err; | 
|  |  | 
|  | if (unlikely(!IS_ACCEPTING_CMD(ar))) | 
|  | return 0; | 
|  |  | 
|  | err = ar->exec_cmd(ar, AR9170_CMD_WREG, sizeof(buf), | 
|  | (u8 *) buf, 0, NULL); | 
|  | if (err) | 
|  | printk(KERN_DEBUG "%s: writing reg %#x (val %#x) failed\n", | 
|  | wiphy_name(ar->hw->wiphy), reg, val); | 
|  | return err; | 
|  | } | 
|  |  | 
|  | static int ar9170_read_mreg(struct ar9170 *ar, int nregs, | 
|  | const u32 *regs, u32 *out) | 
|  | { | 
|  | int i, err; | 
|  | __le32 *offs, *res; | 
|  |  | 
|  | if (unlikely(!IS_ACCEPTING_CMD(ar))) | 
|  | return 0; | 
|  |  | 
|  | /* abuse "out" for the register offsets, must be same length */ | 
|  | offs = (__le32 *)out; | 
|  | for (i = 0; i < nregs; i++) | 
|  | offs[i] = cpu_to_le32(regs[i]); | 
|  |  | 
|  | /* also use the same buffer for the input */ | 
|  | res = (__le32 *)out; | 
|  |  | 
|  | err = ar->exec_cmd(ar, AR9170_CMD_RREG, | 
|  | 4 * nregs, (u8 *)offs, | 
|  | 4 * nregs, (u8 *)res); | 
|  | if (err) | 
|  | return err; | 
|  |  | 
|  | /* convert result to cpu endian */ | 
|  | for (i = 0; i < nregs; i++) | 
|  | out[i] = le32_to_cpu(res[i]); | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val) | 
|  | { | 
|  | return ar9170_read_mreg(ar, 1, ®, val); | 
|  | } | 
|  |  | 
|  | int ar9170_echo_test(struct ar9170 *ar, u32 v) | 
|  | { | 
|  | __le32 echobuf = cpu_to_le32(v); | 
|  | __le32 echores; | 
|  | int err; | 
|  |  | 
|  | if (unlikely(!IS_ACCEPTING_CMD(ar))) | 
|  | return -ENODEV; | 
|  |  | 
|  | err = ar->exec_cmd(ar, AR9170_CMD_ECHO, | 
|  | 4, (u8 *)&echobuf, | 
|  | 4, (u8 *)&echores); | 
|  | if (err) | 
|  | return err; | 
|  |  | 
|  | if (echobuf != echores) | 
|  | return -EINVAL; | 
|  |  | 
|  | return 0; | 
|  | } |