1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2007 - 2011 Realtek Corporation. */
3 
4 #include "../include/rtw_iol.h"
5 
rtw_IOL_accquire_xmit_frame(struct adapter * adapter)6 struct xmit_frame	*rtw_IOL_accquire_xmit_frame(struct adapter  *adapter)
7 {
8 	struct xmit_frame	*xmit_frame;
9 	struct xmit_buf	*xmitbuf;
10 	struct pkt_attrib	*pattrib;
11 	struct xmit_priv	*pxmitpriv = &adapter->xmitpriv;
12 
13 	xmit_frame = rtw_alloc_xmitframe(pxmitpriv);
14 	if (!xmit_frame) {
15 		DBG_88E("%s rtw_alloc_xmitframe return null\n", __func__);
16 		goto exit;
17 	}
18 
19 	xmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
20 	if (!xmitbuf) {
21 		DBG_88E("%s rtw_alloc_xmitbuf return null\n", __func__);
22 		rtw_free_xmitframe(pxmitpriv, xmit_frame);
23 		xmit_frame = NULL;
24 		goto exit;
25 	}
26 
27 	xmit_frame->frame_tag = MGNT_FRAMETAG;
28 	xmit_frame->pxmitbuf = xmitbuf;
29 	xmit_frame->buf_addr = xmitbuf->pbuf;
30 	xmitbuf->priv_data = xmit_frame;
31 
32 	pattrib = &xmit_frame->attrib;
33 	update_mgntframe_attrib(adapter, pattrib);
34 	pattrib->qsel = 0x10;/* Beacon */
35 	pattrib->subtype = WIFI_BEACON;
36 	pattrib->pktlen = 0;
37 	pattrib->last_txcmdsz = 0;
38 exit:
39 	return xmit_frame;
40 }
41 
rtw_IOL_append_cmds(struct xmit_frame * xmit_frame,u8 * IOL_cmds,u32 cmd_len)42 int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len)
43 {
44 	struct pkt_attrib	*pattrib = &xmit_frame->attrib;
45 	u16 buf_offset;
46 	u32 ori_len;
47 
48 	buf_offset = TXDESC_OFFSET;
49 	ori_len = buf_offset + pattrib->pktlen;
50 
51 	/* check if the io_buf can accommodate new cmds */
52 	if (ori_len + cmd_len + 8 > MAX_XMITBUF_SZ) {
53 		DBG_88E("%s %u is large than MAX_XMITBUF_SZ:%u, can't accommodate new cmds\n",
54 			__func__, ori_len + cmd_len + 8, MAX_XMITBUF_SZ);
55 		return _FAIL;
56 	}
57 
58 	memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, IOL_cmds, cmd_len);
59 	pattrib->pktlen += cmd_len;
60 	pattrib->last_txcmdsz += cmd_len;
61 
62 	return _SUCCESS;
63 }
64 
rtw_IOL_applied(struct adapter * adapter)65 bool rtw_IOL_applied(struct adapter  *adapter)
66 {
67 	if (1 == adapter->registrypriv.fw_iol)
68 		return true;
69 
70 	if ((2 == adapter->registrypriv.fw_iol) && (!adapter_to_dvobj(adapter)->ishighspeed))
71 		return true;
72 	return false;
73 }
74 
rtw_IOL_exec_cmds_sync(struct adapter * adapter,struct xmit_frame * xmit_frame,u32 max_wating_ms,u32 bndy_cnt)75 int rtw_IOL_exec_cmds_sync(struct adapter  *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt)
76 {
77 	return rtw_hal_iol_cmd(adapter, xmit_frame, max_wating_ms, bndy_cnt);
78 }
79 
rtw_IOL_append_LLT_cmd(struct xmit_frame * xmit_frame,u8 page_boundary)80 int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary)
81 {
82 	return _SUCCESS;
83 }
84 
_rtw_IOL_append_WB_cmd(struct xmit_frame * xmit_frame,u16 addr,u8 value,u8 mask)85 int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8 mask)
86 {
87 	struct ioreg_cfg cmd = {8, IOREG_CMD_WB_REG, 0x0, 0x0, 0x0};
88 
89 	cmd.address = cpu_to_le16(addr);
90 	cmd.data = cpu_to_le32(value);
91 
92 	if (mask != 0xFF) {
93 		cmd.length = 12;
94 		cmd.mask = cpu_to_le32(mask);
95 	}
96 	return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
97 }
98 
_rtw_IOL_append_WW_cmd(struct xmit_frame * xmit_frame,u16 addr,u16 value,u16 mask)99 int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, u16 mask)
100 {
101 	struct ioreg_cfg cmd = {8, IOREG_CMD_WW_REG, 0x0, 0x0, 0x0};
102 
103 	cmd.address = cpu_to_le16(addr);
104 	cmd.data = cpu_to_le32(value);
105 
106 	if (mask != 0xFFFF) {
107 		cmd.length = 12;
108 		cmd.mask =  cpu_to_le32(mask);
109 	}
110 	return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
111 }
112 
_rtw_IOL_append_WD_cmd(struct xmit_frame * xmit_frame,u16 addr,u32 value,u32 mask)113 int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, u32 mask)
114 {
115 	struct ioreg_cfg cmd = {8, IOREG_CMD_WD_REG, 0x0, 0x0, 0x0};
116 
117 	cmd.address = cpu_to_le16(addr);
118 	cmd.data = cpu_to_le32(value);
119 
120 	if (mask != 0xFFFFFFFF) {
121 		cmd.length = 12;
122 		cmd.mask =  cpu_to_le32(mask);
123 	}
124 	return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
125 }
126 
_rtw_IOL_append_WRF_cmd(struct xmit_frame * xmit_frame,u8 rf_path,u16 addr,u32 value,u32 mask)127 int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr, u32 value, u32 mask)
128 {
129 	struct ioreg_cfg cmd = {8, IOREG_CMD_W_RF, 0x0, 0x0, 0x0};
130 
131 	cmd.address = cpu_to_le16((rf_path << 8) | ((addr) & 0xFF));
132 	cmd.data = cpu_to_le32(value);
133 
134 	if (mask != 0x000FFFFF) {
135 		cmd.length = 12;
136 		cmd.mask =  cpu_to_le32(mask);
137 	}
138 	return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
139 }
140 
rtw_IOL_append_DELAY_US_cmd(struct xmit_frame * xmit_frame,u16 us)141 int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us)
142 {
143 	struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0};
144 	cmd.address = cpu_to_le16(us);
145 
146 	return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
147 }
148 
rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame * xmit_frame,u16 ms)149 int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms)
150 {
151 	struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0};
152 
153 	cmd.address = cpu_to_le16(ms);
154 	return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
155 }
156 
rtw_IOL_append_END_cmd(struct xmit_frame * xmit_frame)157 int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame)
158 {
159 	struct ioreg_cfg cmd = {4, IOREG_CMD_END, cpu_to_le16(0xFFFF), cpu_to_le32(0xFF), 0x0};
160 
161 	return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
162 }
163 
rtw_IOL_cmd_boundary_handle(struct xmit_frame * pxmit_frame)164 u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame)
165 {
166 	u8 is_cmd_bndy = false;
167 	if (((pxmit_frame->attrib.pktlen + 32) % 256) + 8 >= 256) {
168 		rtw_IOL_append_END_cmd(pxmit_frame);
169 		pxmit_frame->attrib.pktlen = ((((pxmit_frame->attrib.pktlen + 32) / 256) + 1) * 256);
170 
171 		pxmit_frame->attrib.last_txcmdsz = pxmit_frame->attrib.pktlen;
172 		is_cmd_bndy = true;
173 	}
174 	return is_cmd_bndy;
175 }
176 
rtw_IOL_cmd_buf_dump(struct adapter * Adapter,int buf_len,u8 * pbuf)177 void rtw_IOL_cmd_buf_dump(struct adapter  *Adapter, int buf_len, u8 *pbuf)
178 {
179 	int i;
180 	int j = 1;
181 
182 	pr_info("###### %s ######\n", __func__);
183 	for (i = 0; i < buf_len; i++) {
184 		printk("%02x-", *(pbuf + i));
185 
186 		if (j % 32 == 0)
187 			printk("\n");
188 		j++;
189 	}
190 	printk("\n");
191 	pr_info("=============ioreg_cmd len=%d===============\n", buf_len);
192 }
193