0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 #include <asm/div64.h>
0040 #include "carl9170.h"
0041 #include "cmd.h"
0042
0043 int carl9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
0044 {
0045 const __le32 buf[2] = {
0046 cpu_to_le32(reg),
0047 cpu_to_le32(val),
0048 };
0049 int err;
0050
0051 err = carl9170_exec_cmd(ar, CARL9170_CMD_WREG, sizeof(buf),
0052 (u8 *) buf, 0, NULL);
0053 if (err) {
0054 if (net_ratelimit()) {
0055 wiphy_err(ar->hw->wiphy, "writing reg %#x "
0056 "(val %#x) failed (%d)\n", reg, val, err);
0057 }
0058 }
0059 return err;
0060 }
0061
0062 int carl9170_read_mreg(struct ar9170 *ar, const int nregs,
0063 const u32 *regs, u32 *out)
0064 {
0065 int i, err;
0066 __le32 *offs, *res;
0067
0068
0069 offs = (__le32 *)out;
0070 for (i = 0; i < nregs; i++)
0071 offs[i] = cpu_to_le32(regs[i]);
0072
0073
0074 res = (__le32 *)out;
0075
0076 err = carl9170_exec_cmd(ar, CARL9170_CMD_RREG,
0077 4 * nregs, (u8 *)offs,
0078 4 * nregs, (u8 *)res);
0079 if (err) {
0080 if (net_ratelimit()) {
0081 wiphy_err(ar->hw->wiphy, "reading regs failed (%d)\n",
0082 err);
0083 }
0084 return err;
0085 }
0086
0087
0088 for (i = 0; i < nregs; i++)
0089 out[i] = le32_to_cpu(res[i]);
0090
0091 return 0;
0092 }
0093
0094 int carl9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val)
0095 {
0096 return carl9170_read_mreg(ar, 1, ®, val);
0097 }
0098
0099 int carl9170_echo_test(struct ar9170 *ar, const u32 v)
0100 {
0101 u32 echores;
0102 int err;
0103
0104 err = carl9170_exec_cmd(ar, CARL9170_CMD_ECHO,
0105 4, (u8 *)&v,
0106 4, (u8 *)&echores);
0107 if (err)
0108 return err;
0109
0110 if (v != echores) {
0111 wiphy_info(ar->hw->wiphy, "wrong echo %x != %x", v, echores);
0112 return -EINVAL;
0113 }
0114
0115 return 0;
0116 }
0117
0118 struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar,
0119 const enum carl9170_cmd_oids cmd, const unsigned int len)
0120 {
0121 struct carl9170_cmd *tmp;
0122
0123 tmp = kzalloc(sizeof(struct carl9170_cmd_head) + len, GFP_ATOMIC);
0124 if (tmp) {
0125 tmp->hdr.cmd = cmd;
0126 tmp->hdr.len = len;
0127 }
0128
0129 return tmp;
0130 }
0131
0132 int carl9170_reboot(struct ar9170 *ar)
0133 {
0134 struct carl9170_cmd *cmd;
0135 int err;
0136
0137 cmd = carl9170_cmd_buf(ar, CARL9170_CMD_REBOOT_ASYNC, 0);
0138 if (!cmd)
0139 return -ENOMEM;
0140
0141 err = __carl9170_exec_cmd(ar, cmd, true);
0142 return err;
0143 }
0144
0145 int carl9170_mac_reset(struct ar9170 *ar)
0146 {
0147 return carl9170_exec_cmd(ar, CARL9170_CMD_SWRST,
0148 0, NULL, 0, NULL);
0149 }
0150
0151 int carl9170_bcn_ctrl(struct ar9170 *ar, const unsigned int vif_id,
0152 const u32 mode, const u32 addr, const u32 len)
0153 {
0154 struct carl9170_cmd *cmd;
0155
0156 cmd = carl9170_cmd_buf(ar, CARL9170_CMD_BCN_CTRL_ASYNC,
0157 sizeof(struct carl9170_bcn_ctrl_cmd));
0158 if (!cmd)
0159 return -ENOMEM;
0160
0161 cmd->bcn_ctrl.vif_id = cpu_to_le32(vif_id);
0162 cmd->bcn_ctrl.mode = cpu_to_le32(mode);
0163 cmd->bcn_ctrl.bcn_addr = cpu_to_le32(addr);
0164 cmd->bcn_ctrl.bcn_len = cpu_to_le32(len);
0165
0166 return __carl9170_exec_cmd(ar, cmd, true);
0167 }
0168
0169 int carl9170_collect_tally(struct ar9170 *ar)
0170 {
0171 struct carl9170_tally_rsp tally;
0172 struct survey_info *info;
0173 unsigned int tick;
0174 int err;
0175
0176 err = carl9170_exec_cmd(ar, CARL9170_CMD_TALLY, 0, NULL,
0177 sizeof(tally), (u8 *)&tally);
0178 if (err)
0179 return err;
0180
0181 tick = le32_to_cpu(tally.tick);
0182 if (tick) {
0183 ar->tally.active += le32_to_cpu(tally.active) / tick;
0184 ar->tally.cca += le32_to_cpu(tally.cca) / tick;
0185 ar->tally.tx_time += le32_to_cpu(tally.tx_time) / tick;
0186 ar->tally.rx_total += le32_to_cpu(tally.rx_total);
0187 ar->tally.rx_overrun += le32_to_cpu(tally.rx_overrun);
0188
0189 if (ar->channel) {
0190 info = &ar->survey[ar->channel->hw_value];
0191 info->time = ar->tally.active;
0192 info->time_busy = ar->tally.cca;
0193 info->time_tx = ar->tally.tx_time;
0194 do_div(info->time, 1000);
0195 do_div(info->time_busy, 1000);
0196 do_div(info->time_tx, 1000);
0197 }
0198 }
0199 return 0;
0200 }
0201
0202 int carl9170_powersave(struct ar9170 *ar, const bool ps)
0203 {
0204 struct carl9170_cmd *cmd;
0205 u32 state;
0206
0207 cmd = carl9170_cmd_buf(ar, CARL9170_CMD_PSM_ASYNC,
0208 sizeof(struct carl9170_psm));
0209 if (!cmd)
0210 return -ENOMEM;
0211
0212 if (ps) {
0213
0214 state = CARL9170_PSM_SLEEP | 1;
0215 } else {
0216
0217 state = 1;
0218 }
0219
0220 cmd->psm.state = cpu_to_le32(state);
0221 return __carl9170_exec_cmd(ar, cmd, true);
0222 }