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 /* Translate the OS dependent error_code to RTW_STATUS_CODE */
RTW_STATUS_CODE(int error_code)10 inline int RTW_STATUS_CODE(int error_code)
11 {
12 if (error_code >= 0)
13 return _SUCCESS;
14 return _FAIL;
15 }
16
_rtw_netif_rx(struct net_device * ndev,struct sk_buff * skb)17 inline int _rtw_netif_rx(struct net_device *ndev, struct sk_buff *skb)
18 {
19 skb->dev = ndev;
20 return netif_rx(skb);
21 }
22
rtw_alloc_etherdev_with_old_priv(int sizeof_priv,void * old_priv)23 struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv)
24 {
25 struct net_device *pnetdev;
26 struct rtw_netdev_priv_indicator *pnpi;
27
28 pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
29 if (!pnetdev)
30 goto RETURN;
31
32 pnpi = netdev_priv(pnetdev);
33 pnpi->priv = old_priv;
34 pnpi->sizeof_priv = sizeof_priv;
35
36 RETURN:
37 return pnetdev;
38 }
39
rtw_alloc_etherdev(int sizeof_priv)40 struct net_device *rtw_alloc_etherdev(int sizeof_priv)
41 {
42 struct net_device *pnetdev;
43 struct rtw_netdev_priv_indicator *pnpi;
44
45 pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
46 if (!pnetdev)
47 goto RETURN;
48
49 pnpi = netdev_priv(pnetdev);
50
51 pnpi->priv = vzalloc(sizeof_priv);
52 if (!pnpi->priv) {
53 free_netdev(pnetdev);
54 pnetdev = NULL;
55 goto RETURN;
56 }
57
58 pnpi->sizeof_priv = sizeof_priv;
59 RETURN:
60 return pnetdev;
61 }
62
rtw_free_netdev(struct net_device * netdev)63 void rtw_free_netdev(struct net_device *netdev)
64 {
65 struct rtw_netdev_priv_indicator *pnpi;
66
67 if (!netdev)
68 goto RETURN;
69
70 pnpi = netdev_priv(netdev);
71
72 if (!pnpi->priv)
73 goto RETURN;
74
75 vfree(pnpi->priv);
76 free_netdev(netdev);
77
78 RETURN:
79 return;
80 }
81
rtw_buf_free(u8 ** buf,u32 * buf_len)82 void rtw_buf_free(u8 **buf, u32 *buf_len)
83 {
84 if (!buf || !buf_len)
85 return;
86
87 if (*buf) {
88 *buf_len = 0;
89 kfree(*buf);
90 *buf = NULL;
91 }
92 }
93
rtw_buf_update(u8 ** buf,u32 * buf_len,u8 * src,u32 src_len)94 void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len)
95 {
96 u32 ori_len = 0, dup_len = 0;
97 u8 *ori = NULL;
98 u8 *dup = NULL;
99
100 if (!buf || !buf_len)
101 return;
102
103 if (!src || !src_len)
104 goto keep_ori;
105
106 /* duplicate src */
107 dup = kmemdup(src, src_len, GFP_ATOMIC);
108 if (dup)
109 dup_len = src_len;
110
111 keep_ori:
112 ori = *buf;
113 ori_len = *buf_len;
114
115 /* replace buf with dup */
116 *buf_len = 0;
117 *buf = dup;
118 *buf_len = dup_len;
119
120 /* free ori */
121 if (ori && ori_len > 0)
122 kfree(ori);
123 }
124
125 /**
126 * rtw_cbuf_full - test if cbuf is full
127 * @cbuf: pointer of struct rtw_cbuf
128 *
129 * Returns: true if cbuf is full
130 */
rtw_cbuf_full(struct rtw_cbuf * cbuf)131 inline bool rtw_cbuf_full(struct rtw_cbuf *cbuf)
132 {
133 return (cbuf->write == cbuf->read - 1) ? true : false;
134 }
135
136 /**
137 * rtw_cbuf_empty - test if cbuf is empty
138 * @cbuf: pointer of struct rtw_cbuf
139 *
140 * Returns: true if cbuf is empty
141 */
rtw_cbuf_empty(struct rtw_cbuf * cbuf)142 inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf)
143 {
144 return (cbuf->write == cbuf->read) ? true : false;
145 }
146
147 /**
148 * rtw_cbuf_push - push a pointer into cbuf
149 * @cbuf: pointer of struct rtw_cbuf
150 * @buf: pointer to push in
151 *
152 * Lock free operation, be careful of the use scheme
153 * Returns: true push success
154 */
rtw_cbuf_push(struct rtw_cbuf * cbuf,void * buf)155 bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf)
156 {
157 if (rtw_cbuf_full(cbuf))
158 return _FAIL;
159
160 cbuf->bufs[cbuf->write] = buf;
161 cbuf->write = (cbuf->write + 1) % cbuf->size;
162
163 return _SUCCESS;
164 }
165
166 /**
167 * rtw_cbuf_pop - pop a pointer from cbuf
168 * @cbuf: pointer of struct rtw_cbuf
169 *
170 * Lock free operation, be careful of the use scheme
171 * Returns: pointer popped out
172 */
rtw_cbuf_pop(struct rtw_cbuf * cbuf)173 void *rtw_cbuf_pop(struct rtw_cbuf *cbuf)
174 {
175 void *buf;
176
177 if (rtw_cbuf_empty(cbuf))
178 return NULL;
179
180 buf = cbuf->bufs[cbuf->read];
181 cbuf->read = (cbuf->read + 1) % cbuf->size;
182
183 return buf;
184 }
185
186 /**
187 * rtw_cbuf_alloc - allocate a rtw_cbuf with given size and do initialization
188 * @size: size of pointer
189 *
190 * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure
191 */
rtw_cbuf_alloc(u32 size)192 struct rtw_cbuf *rtw_cbuf_alloc(u32 size)
193 {
194 struct rtw_cbuf *cbuf;
195
196 cbuf = kzalloc_flex(*cbuf, bufs, size);
197 cbuf->size = size;
198
199 return cbuf;
200 }
201