1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 #include <drv_types.h>
8 
9 /*
10 * Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE
11 * @return: one of RTW_STATUS_CODE
12 */
RTW_STATUS_CODE(int error_code)13 inline int RTW_STATUS_CODE(int error_code)
14 {
15 	if (error_code >= 0)
16 		return _SUCCESS;
17 	return _FAIL;
18 }
19 
_rtw_malloc(u32 sz)20 void *_rtw_malloc(u32 sz)
21 {
22 	return kmalloc(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
23 }
24 
_rtw_zmalloc(u32 sz)25 void *_rtw_zmalloc(u32 sz)
26 {
27 	void *pbuf = _rtw_malloc(sz);
28 
29 	if (pbuf)
30 		memset(pbuf, 0, sz);
31 
32 	return pbuf;
33 }
34 
_rtw_skb_alloc(u32 sz)35 inline struct sk_buff *_rtw_skb_alloc(u32 sz)
36 {
37 	return __dev_alloc_skb(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
38 }
39 
_rtw_skb_copy(const struct sk_buff * skb)40 inline struct sk_buff *_rtw_skb_copy(const struct sk_buff *skb)
41 {
42 	return skb_copy(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
43 }
44 
_rtw_netif_rx(struct net_device * ndev,struct sk_buff * skb)45 inline int _rtw_netif_rx(struct net_device *ndev, struct sk_buff *skb)
46 {
47 	skb->dev = ndev;
48 	return netif_rx(skb);
49 }
50 
rtw_alloc_etherdev_with_old_priv(int sizeof_priv,void * old_priv)51 struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv)
52 {
53 	struct net_device *pnetdev;
54 	struct rtw_netdev_priv_indicator *pnpi;
55 
56 	pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
57 	if (!pnetdev)
58 		goto RETURN;
59 
60 	pnpi = netdev_priv(pnetdev);
61 	pnpi->priv = old_priv;
62 	pnpi->sizeof_priv = sizeof_priv;
63 
64 RETURN:
65 	return pnetdev;
66 }
67 
rtw_alloc_etherdev(int sizeof_priv)68 struct net_device *rtw_alloc_etherdev(int sizeof_priv)
69 {
70 	struct net_device *pnetdev;
71 	struct rtw_netdev_priv_indicator *pnpi;
72 
73 	pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
74 	if (!pnetdev)
75 		goto RETURN;
76 
77 	pnpi = netdev_priv(pnetdev);
78 
79 	pnpi->priv = vzalloc(sizeof_priv);
80 	if (!pnpi->priv) {
81 		free_netdev(pnetdev);
82 		pnetdev = NULL;
83 		goto RETURN;
84 	}
85 
86 	pnpi->sizeof_priv = sizeof_priv;
87 RETURN:
88 	return pnetdev;
89 }
90 
rtw_free_netdev(struct net_device * netdev)91 void rtw_free_netdev(struct net_device *netdev)
92 {
93 	struct rtw_netdev_priv_indicator *pnpi;
94 
95 	if (!netdev)
96 		goto RETURN;
97 
98 	pnpi = netdev_priv(netdev);
99 
100 	if (!pnpi->priv)
101 		goto RETURN;
102 
103 	vfree(pnpi->priv);
104 	free_netdev(netdev);
105 
106 RETURN:
107 	return;
108 }
109 
rtw_buf_free(u8 ** buf,u32 * buf_len)110 void rtw_buf_free(u8 **buf, u32 *buf_len)
111 {
112 	if (!buf || !buf_len)
113 		return;
114 
115 	if (*buf) {
116 		*buf_len = 0;
117 		kfree(*buf);
118 		*buf = NULL;
119 	}
120 }
121 
rtw_buf_update(u8 ** buf,u32 * buf_len,u8 * src,u32 src_len)122 void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len)
123 {
124 	u32 ori_len = 0, dup_len = 0;
125 	u8 *ori = NULL;
126 	u8 *dup = NULL;
127 
128 	if (!buf || !buf_len)
129 		return;
130 
131 	if (!src || !src_len)
132 		goto keep_ori;
133 
134 	/* duplicate src */
135 	dup = rtw_malloc(src_len);
136 	if (dup) {
137 		dup_len = src_len;
138 		memcpy(dup, src, dup_len);
139 	}
140 
141 keep_ori:
142 	ori = *buf;
143 	ori_len = *buf_len;
144 
145 	/* replace buf with dup */
146 	*buf_len = 0;
147 	*buf = dup;
148 	*buf_len = dup_len;
149 
150 	/* free ori */
151 	if (ori && ori_len > 0)
152 		kfree(ori);
153 }
154 
155 
156 /**
157  * rtw_cbuf_full - test if cbuf is full
158  * @cbuf: pointer of struct rtw_cbuf
159  *
160  * Returns: true if cbuf is full
161  */
rtw_cbuf_full(struct rtw_cbuf * cbuf)162 inline bool rtw_cbuf_full(struct rtw_cbuf *cbuf)
163 {
164 	return (cbuf->write == cbuf->read - 1) ? true : false;
165 }
166 
167 /**
168  * rtw_cbuf_empty - test if cbuf is empty
169  * @cbuf: pointer of struct rtw_cbuf
170  *
171  * Returns: true if cbuf is empty
172  */
rtw_cbuf_empty(struct rtw_cbuf * cbuf)173 inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf)
174 {
175 	return (cbuf->write == cbuf->read) ? true : false;
176 }
177 
178 /**
179  * rtw_cbuf_push - push a pointer into cbuf
180  * @cbuf: pointer of struct rtw_cbuf
181  * @buf: pointer to push in
182  *
183  * Lock free operation, be careful of the use scheme
184  * Returns: true push success
185  */
rtw_cbuf_push(struct rtw_cbuf * cbuf,void * buf)186 bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf)
187 {
188 	if (rtw_cbuf_full(cbuf))
189 		return _FAIL;
190 
191 	cbuf->bufs[cbuf->write] = buf;
192 	cbuf->write = (cbuf->write + 1) % cbuf->size;
193 
194 	return _SUCCESS;
195 }
196 
197 /**
198  * rtw_cbuf_pop - pop a pointer from cbuf
199  * @cbuf: pointer of struct rtw_cbuf
200  *
201  * Lock free operation, be careful of the use scheme
202  * Returns: pointer popped out
203  */
rtw_cbuf_pop(struct rtw_cbuf * cbuf)204 void *rtw_cbuf_pop(struct rtw_cbuf *cbuf)
205 {
206 	void *buf;
207 	if (rtw_cbuf_empty(cbuf))
208 		return NULL;
209 
210 	buf = cbuf->bufs[cbuf->read];
211 	cbuf->read = (cbuf->read + 1) % cbuf->size;
212 
213 	return buf;
214 }
215 
216 /**
217  * rtw_cbuf_alloc - allocate a rtw_cbuf with given size and do initialization
218  * @size: size of pointer
219  *
220  * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure
221  */
rtw_cbuf_alloc(u32 size)222 struct rtw_cbuf *rtw_cbuf_alloc(u32 size)
223 {
224 	struct rtw_cbuf *cbuf;
225 
226 	cbuf = rtw_malloc(struct_size(cbuf, bufs, size));
227 
228 	if (cbuf) {
229 		cbuf->write = cbuf->read = 0;
230 		cbuf->size = size;
231 	}
232 
233 	return cbuf;
234 }
235