1/* 2 * Atheros AR9170 driver 3 * 4 * Basic HW register/memory/command access functions 5 * 6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; see the file COPYING. If not, see 20 * http://www.gnu.org/licenses/. 21 * 22 * This file incorporates work covered by the following copyright and 23 * permission notice: 24 * Copyright (c) 2007-2008 Atheros Communications, Inc. 25 * 26 * Permission to use, copy, modify, and/or distribute this software for any 27 * purpose with or without fee is hereby granted, provided that the above 28 * copyright notice and this permission notice appear in all copies. 29 * 30 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 31 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 32 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 33 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 34 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 35 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 36 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 37 */ 38 39#include "ar9170.h" 40#include "cmd.h" 41 42int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len) 43{ 44 int err; 45 46 if (unlikely(!IS_ACCEPTING_CMD(ar))) 47 return 0; 48 49 err = ar->exec_cmd(ar, AR9170_CMD_WMEM, len, (u8 *) data, 0, NULL); 50 if (err) 51 wiphy_debug(ar->hw->wiphy, "writing memory failed\n"); 52 return err; 53} 54 55int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val) 56{ 57 __le32 buf[2] = { 58 cpu_to_le32(reg), 59 cpu_to_le32(val), 60 }; 61 int err; 62 63 if (unlikely(!IS_ACCEPTING_CMD(ar))) 64 return 0; 65 66 err = ar->exec_cmd(ar, AR9170_CMD_WREG, sizeof(buf), 67 (u8 *) buf, 0, NULL); 68 if (err) 69 wiphy_debug(ar->hw->wiphy, "writing reg %#x (val %#x) failed\n", 70 reg, val); 71 return err; 72} 73 74int ar9170_read_mreg(struct ar9170 *ar, int nregs, const u32 *regs, u32 *out) 75{ 76 int i, err; 77 __le32 *offs, *res; 78 79 if (unlikely(!IS_ACCEPTING_CMD(ar))) 80 return 0; 81 82 /* abuse "out" for the register offsets, must be same length */ 83 offs = (__le32 *)out; 84 for (i = 0; i < nregs; i++) 85 offs[i] = cpu_to_le32(regs[i]); 86 87 /* also use the same buffer for the input */ 88 res = (__le32 *)out; 89 90 err = ar->exec_cmd(ar, AR9170_CMD_RREG, 91 4 * nregs, (u8 *)offs, 92 4 * nregs, (u8 *)res); 93 if (err) 94 return err; 95 96 /* convert result to cpu endian */ 97 for (i = 0; i < nregs; i++) 98 out[i] = le32_to_cpu(res[i]); 99 100 return 0; 101} 102 103int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val) 104{ 105 return ar9170_read_mreg(ar, 1, ®, val); 106} 107 108int ar9170_echo_test(struct ar9170 *ar, u32 v) 109{ 110 __le32 echobuf = cpu_to_le32(v); 111 __le32 echores; 112 int err; 113 114 if (unlikely(!IS_ACCEPTING_CMD(ar))) 115 return -ENODEV; 116 117 err = ar->exec_cmd(ar, AR9170_CMD_ECHO, 118 4, (u8 *)&echobuf, 119 4, (u8 *)&echores); 120 if (err) 121 return err; 122 123 if (echobuf != echores) 124 return -EINVAL; 125 126 return 0; 127} 128