]>
git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - drivers/net/wireless/realtek/rtl8192cu/core/rtw_iol.c
1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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.
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
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
19 ******************************************************************************/
24 struct xmit_frame
*rtw_IOL_accquire_xmit_frame(ADAPTER
*adapter
)
26 struct xmit_frame
*xmit_frame
;
27 struct xmit_buf
*xmitbuf
;
28 struct pkt_attrib
*pattrib
;
29 struct xmit_priv
*pxmitpriv
= &(adapter
->xmitpriv
);
32 if ((xmit_frame
= rtw_alloc_xmitframe(pxmitpriv
)) == NULL
)
34 DBG_871X("%s rtw_alloc_xmitframe return null\n", __FUNCTION__
);
38 if ((xmitbuf
= rtw_alloc_xmitbuf(pxmitpriv
)) == NULL
)
40 DBG_871X("%s rtw_alloc_xmitbuf return null\n", __FUNCTION__
);
41 rtw_free_xmitframe(pxmitpriv
, xmit_frame
);
46 xmit_frame
->frame_tag
= MGNT_FRAMETAG
;
47 xmit_frame
->pxmitbuf
= xmitbuf
;
48 xmit_frame
->buf_addr
= xmitbuf
->pbuf
;
49 xmitbuf
->priv_data
= xmit_frame
;
51 pattrib
= &xmit_frame
->attrib
;
52 update_mgntframe_attrib(adapter
, pattrib
);
54 pattrib
->pktlen
= pattrib
->last_txcmdsz
= 0;
57 if ((xmit_frame
= alloc_mgtxmitframe(pxmitpriv
)) == NULL
)
59 DBG_871X("%s alloc_mgtxmitframe return null\n", __FUNCTION__
);
62 pattrib
= &xmit_frame
->attrib
;
63 update_mgntframe_attrib(adapter
, pattrib
);
65 pattrib
->pktlen
= pattrib
->last_txcmdsz
= 0;
74 int rtw_IOL_append_cmds(struct xmit_frame
*xmit_frame
, u8
*IOL_cmds
, u32 cmd_len
)
76 struct pkt_attrib
*pattrib
= &xmit_frame
->attrib
;
80 //Todo: bulkout without this offset
82 buf_offset
= TXDESC_OFFSET
;
87 ori_len
= buf_offset
+pattrib
->pktlen
;
89 //check if the io_buf can accommodate new cmds
90 if(ori_len
+ cmd_len
+ 8 > MAX_XMITBUF_SZ
) {
91 DBG_871X("%s %u is large than MAX_XMITBUF_SZ:%u, can't accommodate new cmds\n", __FUNCTION__
92 , ori_len
+ cmd_len
+ 8, MAX_XMITBUF_SZ
);
96 _rtw_memcpy(xmit_frame
->buf_addr
+ buf_offset
+ pattrib
->pktlen
, IOL_cmds
, cmd_len
);
97 pattrib
->pktlen
+= cmd_len
;
98 pattrib
->last_txcmdsz
+= cmd_len
;
100 //DBG_871X("%s ori:%u + cmd_len:%u = %u\n", __FUNCTION__, ori_len, cmd_len, buf_offset+pattrib->pktlen);
105 int rtw_IOL_append_LLT_cmd(struct xmit_frame
*xmit_frame
, u8 page_boundary
)
107 IOL_CMD cmd
= {0x0, IOL_CMD_LLT
, 0x0, 0x0};
109 RTW_PUT_BE32((u8
*)&cmd
.value
, (u32
)page_boundary
);
111 return rtw_IOL_append_cmds(xmit_frame
, (u8
*)&cmd
, 8);
114 int _rtw_IOL_append_WB_cmd(struct xmit_frame
*xmit_frame
, u16 addr
, u8 value
)
116 IOL_CMD cmd
= {0x0, IOL_CMD_WB_REG
, 0x0, 0x0};
118 RTW_PUT_BE16((u8
*)&cmd
.address
, (u16
)addr
);
119 RTW_PUT_BE32((u8
*)&cmd
.value
, (u32
)value
);
121 return rtw_IOL_append_cmds(xmit_frame
, (u8
*)&cmd
, 8);
124 int _rtw_IOL_append_WW_cmd(struct xmit_frame
*xmit_frame
, u16 addr
, u16 value
)
126 IOL_CMD cmd
= {0x0, IOL_CMD_WW_REG
, 0x0, 0x0};
128 RTW_PUT_BE16((u8
*)&cmd
.address
, (u16
)addr
);
129 RTW_PUT_BE32((u8
*)&cmd
.value
, (u32
)value
);
131 return rtw_IOL_append_cmds(xmit_frame
, (u8
*)&cmd
, 8);
134 int _rtw_IOL_append_WD_cmd(struct xmit_frame
*xmit_frame
, u16 addr
, u32 value
)
136 IOL_CMD cmd
= {0x0, IOL_CMD_WD_REG
, 0x0, 0x0};
137 u8
* pos
= (u8
*)&cmd
;
139 RTW_PUT_BE16((u8
*)&cmd
.address
, (u16
)addr
);
140 RTW_PUT_BE32((u8
*)&cmd
.value
, (u32
)value
);
142 return rtw_IOL_append_cmds(xmit_frame
, (u8
*)&cmd
, 8);
146 int dbg_rtw_IOL_append_WB_cmd(struct xmit_frame
*xmit_frame
, u16 addr
, u8 value
, const char *caller
, const int line
)
148 if (match_write_sniff_ranges(addr
, 1))
149 DBG_871X("DBG_IO %s:%d IOL_WB(0x%04x, 0x%02x)\n", caller
, line
, addr
, value
);
151 return _rtw_IOL_append_WB_cmd(xmit_frame
, addr
, value
);
154 int dbg_rtw_IOL_append_WW_cmd(struct xmit_frame
*xmit_frame
, u16 addr
, u16 value
, const char *caller
, const int line
)
156 if (match_write_sniff_ranges(addr
, 2))
157 DBG_871X("DBG_IO %s:%d IOL_WW(0x%04x, 0x%04x)\n", caller
, line
, addr
, value
);
159 return _rtw_IOL_append_WW_cmd(xmit_frame
, addr
, value
);
162 int dbg_rtw_IOL_append_WD_cmd(struct xmit_frame
*xmit_frame
, u16 addr
, u32 value
, const char *caller
, const int line
)
164 if (match_write_sniff_ranges(addr
, 4))
165 DBG_871X("DBG_IO %s:%d IOL_WD(0x%04x, 0x%08x)\n", caller
, line
, addr
, value
);
167 return _rtw_IOL_append_WD_cmd(xmit_frame
, addr
, value
);
171 int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame
*xmit_frame
, u16 us
)
173 IOL_CMD cmd
= {0x0, IOL_CMD_DELAY_US
, 0x0, 0x0};
175 RTW_PUT_BE32((u8
*)&cmd
.value
, (u32
)us
);
177 //DBG_871X("%s %u\n", __FUNCTION__, us);
179 return rtw_IOL_append_cmds(xmit_frame
, (u8
*)&cmd
, 8);
182 int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame
*xmit_frame
, u16 ms
)
184 IOL_CMD cmd
= {0x0, IOL_CMD_DELAY_MS
, 0x0, 0x0};
186 RTW_PUT_BE32((u8
*)&cmd
.value
, (u32
)ms
);
188 //DBG_871X("%s %u\n", __FUNCTION__, ms);
190 return rtw_IOL_append_cmds(xmit_frame
, (u8
*)&cmd
, 8);
193 int rtw_IOL_append_END_cmd(struct xmit_frame
*xmit_frame
)
195 struct pkt_attrib
*pattrib
= &xmit_frame
->attrib
;
198 IOL_CMD end_cmd
= {0x0, IOL_CMD_END
, 0x0, 0x0};
200 //Todo: bulkout without this offset
201 #ifdef CONFIG_USB_HCI
202 buf_offset
= TXDESC_OFFSET
;
207 ori_len
= buf_offset
+pattrib
->pktlen
;
209 //check if the io_buf can accommodate new cmds
210 if(ori_len
+ 8 > MAX_XMITBUF_SZ
) {
211 DBG_871X("%s %u is large than MAX_XMITBUF_SZ:%u, can't accommodate end cmd\n", __FUNCTION__
212 , ori_len
+ 8, MAX_XMITBUF_SZ
);
216 _rtw_memcpy(xmit_frame
->buf_addr
+ buf_offset
+ pattrib
->pktlen
, (u8
*)&end_cmd
, 8);
217 pattrib
->pktlen
+= 8;
218 pattrib
->last_txcmdsz
+= 8;
220 //DBG_871X("%s ori:%u + 8 = %u\n", __FUNCTION__ , ori_len, buf_offset+pattrib->pktlen);
225 int rtw_IOL_exec_cmds_sync(ADAPTER
*adapter
, struct xmit_frame
*xmit_frame
, u32 max_wating_ms
)
227 return rtw_hal_iol_cmd(adapter
, xmit_frame
, max_wating_ms
);
230 int rtw_IOL_exec_cmd_array_sync(PADAPTER adapter
, u8
*IOL_cmds
, u32 cmd_num
, u32 max_wating_ms
)
232 struct xmit_frame
*xmit_frame
;
234 if((xmit_frame
=rtw_IOL_accquire_xmit_frame(adapter
)) == NULL
)
237 if(rtw_IOL_append_cmds(xmit_frame
, IOL_cmds
, cmd_num
<<3) == _FAIL
)
240 return rtw_IOL_exec_cmds_sync(adapter
, xmit_frame
, max_wating_ms
);
243 int rtw_IOL_exec_empty_cmds_sync(ADAPTER
*adapter
, u32 max_wating_ms
)
245 IOL_CMD end_cmd
= {0x0, IOL_CMD_END
, 0x0, 0x0};
246 return rtw_IOL_exec_cmd_array_sync(adapter
, (u8
*)&end_cmd
, 1, max_wating_ms
);
249 bool rtw_IOL_applied(ADAPTER
*adapter
)
251 if(adapter
->registrypriv
.force_iol
)
254 #ifdef CONFIG_USB_HCI
255 if(!adapter_to_dvobj(adapter
)->ishighspeed
)