/* * Atheros AR9170 driver * * Basic HW register/memory/command access functions * * Copyright 2008, Johannes Berg * * 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; }