Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Atheros CARL9170 driver
0003  *
0004  * Basic HW register/memory/command access functions
0005  *
0006  * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
0007  * Copyright 2010, Christian Lamparter <chunkeey@googlemail.com>
0008  *
0009  * This program is free software; you can redistribute it and/or modify
0010  * it under the terms of the GNU General Public License as published by
0011  * the Free Software Foundation; either version 2 of the License, or
0012  * (at your option) any later version.
0013  *
0014  * This program is distributed in the hope that it will be useful,
0015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0017  * GNU General Public License for more details.
0018  *
0019  * You should have received a copy of the GNU General Public License
0020  * along with this program; see the file COPYING.  If not, see
0021  * http://www.gnu.org/licenses/.
0022  *
0023  * This file incorporates work covered by the following copyright and
0024  * permission notice:
0025  *    Copyright (c) 2007-2008 Atheros Communications, Inc.
0026  *
0027  *    Permission to use, copy, modify, and/or distribute this software for any
0028  *    purpose with or without fee is hereby granted, provided that the above
0029  *    copyright notice and this permission notice appear in all copies.
0030  *
0031  *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
0032  *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
0033  *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
0034  *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
0035  *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
0036  *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
0037  *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0038  */
0039 #ifndef __CMD_H
0040 #define __CMD_H
0041 
0042 #include "carl9170.h"
0043 
0044 /* basic HW access */
0045 int carl9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val);
0046 int carl9170_read_reg(struct ar9170 *ar, const u32 reg, u32 *val);
0047 int carl9170_read_mreg(struct ar9170 *ar, const int nregs,
0048                const u32 *regs, u32 *out);
0049 int carl9170_echo_test(struct ar9170 *ar, u32 v);
0050 int carl9170_reboot(struct ar9170 *ar);
0051 int carl9170_mac_reset(struct ar9170 *ar);
0052 int carl9170_powersave(struct ar9170 *ar, const bool power_on);
0053 int carl9170_collect_tally(struct ar9170 *ar);
0054 int carl9170_bcn_ctrl(struct ar9170 *ar, const unsigned int vif_id,
0055                const u32 mode, const u32 addr, const u32 len);
0056 
0057 static inline int carl9170_flush_cab(struct ar9170 *ar,
0058                      const unsigned int vif_id)
0059 {
0060     return carl9170_bcn_ctrl(ar, vif_id, CARL9170_BCN_CTRL_DRAIN, 0, 0);
0061 }
0062 
0063 static inline int carl9170_rx_filter(struct ar9170 *ar,
0064                      const unsigned int _rx_filter)
0065 {
0066     __le32 rx_filter = cpu_to_le32(_rx_filter);
0067 
0068     return carl9170_exec_cmd(ar, CARL9170_CMD_RX_FILTER,
0069                 sizeof(rx_filter), (u8 *)&rx_filter,
0070                 0, NULL);
0071 }
0072 
0073 struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar,
0074     const enum carl9170_cmd_oids cmd, const unsigned int len);
0075 
0076 /*
0077  * Macros to facilitate writing multiple registers in a single
0078  * write-combining USB command. Note that when the first group
0079  * fails the whole thing will fail without any others attempted,
0080  * but you won't know which write in the group failed.
0081  */
0082 #define carl9170_regwrite_begin(ar)                 \
0083 do {                                    \
0084     int __nreg = 0, __err = 0;                  \
0085     struct ar9170 *__ar = ar;
0086 
0087 #define carl9170_regwrite(r, v) do {                    \
0088     __ar->cmd_buf[2 * __nreg + 1] = cpu_to_le32(r);         \
0089     __ar->cmd_buf[2 * __nreg + 2] = cpu_to_le32(v);         \
0090     __nreg++;                           \
0091     if ((__nreg >= PAYLOAD_MAX / 2)) {              \
0092         if (IS_ACCEPTING_CMD(__ar))             \
0093             __err = carl9170_exec_cmd(__ar,         \
0094                 CARL9170_CMD_WREG, 8 * __nreg,      \
0095                 (u8 *) &__ar->cmd_buf[1], 0, NULL); \
0096         else                            \
0097             goto __regwrite_out;                \
0098                                     \
0099         __nreg = 0;                     \
0100         if (__err)                      \
0101             goto __regwrite_out;                \
0102     }                               \
0103 } while (0)
0104 
0105 #define carl9170_regwrite_finish()                  \
0106 __regwrite_out :                            \
0107     if (__err == 0 && __nreg) {                 \
0108         if (IS_ACCEPTING_CMD(__ar))             \
0109             __err = carl9170_exec_cmd(__ar,         \
0110                 CARL9170_CMD_WREG, 8 * __nreg,      \
0111                 (u8 *) &__ar->cmd_buf[1], 0, NULL); \
0112         __nreg = 0;                     \
0113     }
0114 
0115 #define carl9170_regwrite_result()                  \
0116     __err;                              \
0117 } while (0)
0118 
0119 
0120 #define carl9170_async_regwrite_get_buf()               \
0121 do {                                    \
0122     __nreg = 0;                         \
0123     __cmd = carl9170_cmd_buf(__carl, CARL9170_CMD_WREG_ASYNC,   \
0124                  CARL9170_MAX_CMD_PAYLOAD_LEN);     \
0125     if (__cmd == NULL) {                        \
0126         __err = -ENOMEM;                    \
0127         goto __async_regwrite_out;              \
0128     }                               \
0129 } while (0)
0130 
0131 #define carl9170_async_regwrite_begin(carl)             \
0132 do {                                    \
0133     struct ar9170 *__carl = carl;                   \
0134     struct carl9170_cmd *__cmd;                 \
0135     unsigned int __nreg;                        \
0136     int  __err = 0;                         \
0137     carl9170_async_regwrite_get_buf();              \
0138 
0139 #define carl9170_async_regwrite_flush()                 \
0140 do {                                    \
0141     if (__cmd == NULL || __nreg == 0)               \
0142         break;                          \
0143                                     \
0144     if (IS_ACCEPTING_CMD(__carl) && __nreg) {           \
0145         __cmd->hdr.len = 8 * __nreg;                \
0146         __err = __carl9170_exec_cmd(__carl, __cmd, true);   \
0147         __cmd = NULL;                       \
0148         break;                          \
0149     }                               \
0150     goto __async_regwrite_out;                  \
0151 } while (0)
0152 
0153 #define carl9170_async_regwrite(r, v) do {              \
0154     if (__cmd == NULL)                      \
0155         carl9170_async_regwrite_get_buf();          \
0156     __cmd->wreg.regs[__nreg].addr = cpu_to_le32(r);         \
0157     __cmd->wreg.regs[__nreg].val = cpu_to_le32(v);          \
0158     __nreg++;                           \
0159     if ((__nreg >= PAYLOAD_MAX / 2))                \
0160         carl9170_async_regwrite_flush();            \
0161 } while (0)
0162 
0163 #define carl9170_async_regwrite_finish() do {               \
0164 __async_regwrite_out:                           \
0165     if (__cmd != NULL && __err == 0)                \
0166         carl9170_async_regwrite_flush();            \
0167     kfree(__cmd);                           \
0168 } while (0)                             \
0169 
0170 #define carl9170_async_regwrite_result()                \
0171     __err;                              \
0172 } while (0)
0173 
0174 #endif /* __CMD_H */