sfc: Don't use enums as a bitmask.
[zen-stable.git] / drivers / net / wireless / ath / carl9170 / cmd.c
blobcdfc94c371b41930e0fd50aca0119e877a6d0f10
1 /*
2 * Atheros CARL9170 driver
4 * Basic HW register/memory/command access functions
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
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.
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.
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/.
22 * This file incorporates work covered by the following copyright and
23 * permission notice:
24 * Copyright (c) 2007-2008 Atheros Communications, Inc.
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.
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.
39 #include "carl9170.h"
40 #include "cmd.h"
42 int carl9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
44 const __le32 buf[2] = {
45 cpu_to_le32(reg),
46 cpu_to_le32(val),
48 int err;
50 err = carl9170_exec_cmd(ar, CARL9170_CMD_WREG, sizeof(buf),
51 (u8 *) buf, 0, NULL);
52 if (err) {
53 if (net_ratelimit()) {
54 wiphy_err(ar->hw->wiphy, "writing reg %#x "
55 "(val %#x) failed (%d)\n", reg, val, err);
58 return err;
61 int carl9170_read_mreg(struct ar9170 *ar, const int nregs,
62 const u32 *regs, u32 *out)
64 int i, err;
65 __le32 *offs, *res;
67 /* abuse "out" for the register offsets, must be same length */
68 offs = (__le32 *)out;
69 for (i = 0; i < nregs; i++)
70 offs[i] = cpu_to_le32(regs[i]);
72 /* also use the same buffer for the input */
73 res = (__le32 *)out;
75 err = carl9170_exec_cmd(ar, CARL9170_CMD_RREG,
76 4 * nregs, (u8 *)offs,
77 4 * nregs, (u8 *)res);
78 if (err) {
79 if (net_ratelimit()) {
80 wiphy_err(ar->hw->wiphy, "reading regs failed (%d)\n",
81 err);
83 return err;
86 /* convert result to cpu endian */
87 for (i = 0; i < nregs; i++)
88 out[i] = le32_to_cpu(res[i]);
90 return 0;
93 int carl9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val)
95 return carl9170_read_mreg(ar, 1, &reg, val);
98 int carl9170_echo_test(struct ar9170 *ar, const u32 v)
100 u32 echores;
101 int err;
103 err = carl9170_exec_cmd(ar, CARL9170_CMD_ECHO,
104 4, (u8 *)&v,
105 4, (u8 *)&echores);
106 if (err)
107 return err;
109 if (v != echores) {
110 wiphy_info(ar->hw->wiphy, "wrong echo %x != %x", v, echores);
111 return -EINVAL;
114 return 0;
117 struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar,
118 const enum carl9170_cmd_oids cmd, const unsigned int len)
120 struct carl9170_cmd *tmp;
122 tmp = kzalloc(sizeof(struct carl9170_cmd_head) + len, GFP_ATOMIC);
123 if (tmp) {
124 tmp->hdr.cmd = cmd;
125 tmp->hdr.len = len;
128 return tmp;
131 int carl9170_reboot(struct ar9170 *ar)
133 struct carl9170_cmd *cmd;
134 int err;
136 cmd = carl9170_cmd_buf(ar, CARL9170_CMD_REBOOT_ASYNC, 0);
137 if (!cmd)
138 return -ENOMEM;
140 err = __carl9170_exec_cmd(ar, (struct carl9170_cmd *)cmd, true);
141 return err;
144 int carl9170_mac_reset(struct ar9170 *ar)
146 return carl9170_exec_cmd(ar, CARL9170_CMD_SWRST,
147 0, NULL, 0, NULL);
150 int carl9170_bcn_ctrl(struct ar9170 *ar, const unsigned int vif_id,
151 const u32 mode, const u32 addr, const u32 len)
153 struct carl9170_cmd *cmd;
155 cmd = carl9170_cmd_buf(ar, CARL9170_CMD_BCN_CTRL_ASYNC,
156 sizeof(struct carl9170_bcn_ctrl_cmd));
157 if (!cmd)
158 return -ENOMEM;
160 cmd->bcn_ctrl.vif_id = cpu_to_le32(vif_id);
161 cmd->bcn_ctrl.mode = cpu_to_le32(mode);
162 cmd->bcn_ctrl.bcn_addr = cpu_to_le32(addr);
163 cmd->bcn_ctrl.bcn_len = cpu_to_le32(len);
165 return __carl9170_exec_cmd(ar, cmd, true);
168 int carl9170_powersave(struct ar9170 *ar, const bool ps)
170 struct carl9170_cmd *cmd;
171 u32 state;
173 cmd = carl9170_cmd_buf(ar, CARL9170_CMD_PSM_ASYNC,
174 sizeof(struct carl9170_psm));
175 if (!cmd)
176 return -ENOMEM;
178 if (ps) {
179 /* Sleep until next TBTT */
180 state = CARL9170_PSM_SLEEP | 1;
181 } else {
182 /* wake up immediately */
183 state = 1;
186 cmd->psm.state = cpu_to_le32(state);
187 return __carl9170_exec_cmd(ar, cmd, true);