Linux-libre 3.14.34-gnu
[librecmc/linux-libre.git] / drivers / staging / rtl8188eu / core / rtw_iol.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20
21 #include<rtw_iol.h>
22
23 struct xmit_frame       *rtw_IOL_accquire_xmit_frame(struct adapter  *adapter)
24 {
25         struct xmit_frame       *xmit_frame;
26         struct xmit_buf *xmitbuf;
27         struct pkt_attrib       *pattrib;
28         struct xmit_priv        *pxmitpriv = &(adapter->xmitpriv);
29
30         xmit_frame = rtw_alloc_xmitframe(pxmitpriv);
31         if (xmit_frame == NULL) {
32                 DBG_88E("%s rtw_alloc_xmitframe return null\n", __func__);
33                 goto exit;
34         }
35
36         xmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
37         if (xmitbuf == NULL) {
38                 DBG_88E("%s rtw_alloc_xmitbuf return null\n", __func__);
39                 rtw_free_xmitframe(pxmitpriv, xmit_frame);
40                 xmit_frame = NULL;
41                 goto exit;
42         }
43
44         xmit_frame->frame_tag = MGNT_FRAMETAG;
45         xmit_frame->pxmitbuf = xmitbuf;
46         xmit_frame->buf_addr = xmitbuf->pbuf;
47         xmitbuf->priv_data = xmit_frame;
48
49         pattrib = &xmit_frame->attrib;
50         update_mgntframe_attrib(adapter, pattrib);
51         pattrib->qsel = 0x10;/* Beacon */
52         pattrib->subtype = WIFI_BEACON;
53         pattrib->pktlen = 0;
54         pattrib->last_txcmdsz = 0;
55 exit:
56         return xmit_frame;
57 }
58
59 int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len)
60 {
61         struct pkt_attrib       *pattrib = &xmit_frame->attrib;
62         u16 buf_offset;
63         u32 ori_len;
64
65         buf_offset = TXDESC_OFFSET;
66         ori_len = buf_offset+pattrib->pktlen;
67
68         /* check if the io_buf can accommodate new cmds */
69         if (ori_len + cmd_len + 8 > MAX_XMITBUF_SZ) {
70                 DBG_88E("%s %u is large than MAX_XMITBUF_SZ:%u, can't accommodate new cmds\n",
71                         __func__ , ori_len + cmd_len + 8, MAX_XMITBUF_SZ);
72                 return _FAIL;
73         }
74
75         memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, IOL_cmds, cmd_len);
76         pattrib->pktlen += cmd_len;
77         pattrib->last_txcmdsz += cmd_len;
78
79         return _SUCCESS;
80 }
81
82 bool rtw_IOL_applied(struct adapter  *adapter)
83 {
84         if (1 == adapter->registrypriv.fw_iol)
85                 return true;
86
87         if ((2 == adapter->registrypriv.fw_iol) && (!adapter_to_dvobj(adapter)->ishighspeed))
88                 return true;
89         return false;
90 }
91
92 int rtw_IOL_exec_cmds_sync(struct adapter  *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt)
93 {
94         return rtw_hal_iol_cmd(adapter, xmit_frame, max_wating_ms, bndy_cnt);
95 }
96
97 int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary)
98 {
99         return _SUCCESS;
100 }
101
102 int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8 mask)
103 {
104         struct ioreg_cfg cmd = {8, IOREG_CMD_WB_REG, 0x0, 0x0, 0x0};
105
106         cmd.address = cpu_to_le16(addr);
107         cmd.data = cpu_to_le32(value);
108
109         if (mask != 0xFF) {
110                 cmd.length = 12;
111                 cmd.mask = cpu_to_le32(mask);
112         }
113         return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
114 }
115
116 int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, u16 mask)
117 {
118         struct ioreg_cfg cmd = {8, IOREG_CMD_WW_REG, 0x0, 0x0, 0x0};
119
120         cmd.address = cpu_to_le16(addr);
121         cmd.data = cpu_to_le32(value);
122
123         if (mask != 0xFFFF) {
124                 cmd.length = 12;
125                 cmd.mask =  cpu_to_le32(mask);
126         }
127         return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
128 }
129
130 int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, u32 mask)
131 {
132         struct ioreg_cfg cmd = {8, IOREG_CMD_WD_REG, 0x0, 0x0, 0x0};
133
134         cmd.address = cpu_to_le16(addr);
135         cmd.data = cpu_to_le32(value);
136
137         if (mask != 0xFFFFFFFF) {
138                 cmd.length = 12;
139                 cmd.mask =  cpu_to_le32(mask);
140         }
141         return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
142 }
143
144 int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr, u32 value, u32 mask)
145 {
146         struct ioreg_cfg cmd = {8, IOREG_CMD_W_RF, 0x0, 0x0, 0x0};
147
148         cmd.address = cpu_to_le16((rf_path<<8) | ((addr) & 0xFF));
149         cmd.data = cpu_to_le32(value);
150
151         if (mask != 0x000FFFFF) {
152                 cmd.length = 12;
153                 cmd.mask =  cpu_to_le32(mask);
154         }
155         return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
156 }
157
158 int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us)
159 {
160         struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0};
161         cmd.address = cpu_to_le16(us);
162
163         return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
164 }
165
166 int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms)
167 {
168         struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0};
169
170         cmd.address = cpu_to_le16(ms);
171         return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
172 }
173
174 int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame)
175 {
176         struct ioreg_cfg cmd = {4, IOREG_CMD_END, cpu_to_le16(0xFFFF), cpu_to_le32(0xFF), 0x0};
177
178         return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
179 }
180
181 u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame)
182 {
183         u8 is_cmd_bndy = false;
184         if (((pxmit_frame->attrib.pktlen+32)%256) + 8 >= 256) {
185                 rtw_IOL_append_END_cmd(pxmit_frame);
186                 pxmit_frame->attrib.pktlen = ((((pxmit_frame->attrib.pktlen+32)/256)+1)*256);
187
188                 pxmit_frame->attrib.last_txcmdsz = pxmit_frame->attrib.pktlen;
189                 is_cmd_bndy = true;
190         }
191         return is_cmd_bndy;
192 }
193
194 void rtw_IOL_cmd_buf_dump(struct adapter  *Adapter, int buf_len, u8 *pbuf)
195 {
196         int i;
197         int j = 1;
198
199         pr_info("###### %s ######\n", __func__);
200         for (i = 0; i < buf_len; i++) {
201                 printk("%02x-", *(pbuf+i));
202
203                 if (j%32 == 0)
204                         printk("\n");
205                 j++;
206         }
207         printk("\n");
208         pr_info("=============ioreg_cmd len=%d===============\n", buf_len);
209 }