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 #include <rtw_debug.h> 9 10 /* 11 * Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE 12 * @return: one of RTW_STATUS_CODE 13 */ 14 inline int RTW_STATUS_CODE(int error_code) 15 { 16 if (error_code >= 0) 17 return _SUCCESS; 18 return _FAIL; 19 } 20 21 void *_rtw_malloc(u32 sz) 22 { 23 return kmalloc(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); 24 } 25 26 void *_rtw_zmalloc(u32 sz) 27 { 28 void *pbuf = _rtw_malloc(sz); 29 30 if (pbuf) 31 memset(pbuf, 0, sz); 32 33 return pbuf; 34 } 35 36 inline struct sk_buff *_rtw_skb_alloc(u32 sz) 37 { 38 return __dev_alloc_skb(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); 39 } 40 41 inline struct sk_buff *_rtw_skb_copy(const struct sk_buff *skb) 42 { 43 return skb_copy(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); 44 } 45 46 inline int _rtw_netif_rx(struct net_device *ndev, struct sk_buff *skb) 47 { 48 skb->dev = ndev; 49 return netif_rx(skb); 50 } 51 52 void _rtw_init_queue(struct __queue *pqueue) 53 { 54 INIT_LIST_HEAD(&(pqueue->queue)); 55 56 spin_lock_init(&(pqueue->lock)); 57 } 58 59 struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv) 60 { 61 struct net_device *pnetdev; 62 struct rtw_netdev_priv_indicator *pnpi; 63 64 pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4); 65 if (!pnetdev) 66 goto RETURN; 67 68 pnpi = netdev_priv(pnetdev); 69 pnpi->priv = old_priv; 70 pnpi->sizeof_priv = sizeof_priv; 71 72 RETURN: 73 return pnetdev; 74 } 75 76 struct net_device *rtw_alloc_etherdev(int sizeof_priv) 77 { 78 struct net_device *pnetdev; 79 struct rtw_netdev_priv_indicator *pnpi; 80 81 pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4); 82 if (!pnetdev) 83 goto RETURN; 84 85 pnpi = netdev_priv(pnetdev); 86 87 pnpi->priv = vzalloc(sizeof_priv); 88 if (!pnpi->priv) { 89 free_netdev(pnetdev); 90 pnetdev = NULL; 91 goto RETURN; 92 } 93 94 pnpi->sizeof_priv = sizeof_priv; 95 RETURN: 96 return pnetdev; 97 } 98 99 void rtw_free_netdev(struct net_device *netdev) 100 { 101 struct rtw_netdev_priv_indicator *pnpi; 102 103 if (!netdev) 104 goto RETURN; 105 106 pnpi = netdev_priv(netdev); 107 108 if (!pnpi->priv) 109 goto RETURN; 110 111 vfree(pnpi->priv); 112 free_netdev(netdev); 113 114 RETURN: 115 return; 116 } 117 118 int rtw_change_ifname(struct adapter *padapter, const char *ifname) 119 { 120 struct net_device *pnetdev; 121 struct net_device *cur_pnetdev; 122 struct rereg_nd_name_data *rereg_priv; 123 int ret; 124 125 if (!padapter) 126 goto error; 127 128 cur_pnetdev = padapter->pnetdev; 129 rereg_priv = &padapter->rereg_nd_name_priv; 130 131 /* free the old_pnetdev */ 132 if (rereg_priv->old_pnetdev) { 133 free_netdev(rereg_priv->old_pnetdev); 134 rereg_priv->old_pnetdev = NULL; 135 } 136 137 if (!rtnl_is_locked()) 138 unregister_netdev(cur_pnetdev); 139 else 140 unregister_netdevice(cur_pnetdev); 141 142 rereg_priv->old_pnetdev = cur_pnetdev; 143 144 pnetdev = rtw_init_netdev(padapter); 145 if (!pnetdev) 146 goto error; 147 148 SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter))); 149 150 rtw_init_netdev_name(pnetdev, ifname); 151 152 memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN); 153 154 if (!rtnl_is_locked()) 155 ret = register_netdev(pnetdev); 156 else 157 ret = register_netdevice(pnetdev); 158 159 if (ret != 0) 160 goto error; 161 162 return 0; 163 164 error: 165 return -1; 166 } 167 168 void rtw_buf_free(u8 **buf, u32 *buf_len) 169 { 170 if (!buf || !buf_len) 171 return; 172 173 if (*buf) { 174 *buf_len = 0; 175 kfree(*buf); 176 *buf = NULL; 177 } 178 } 179 180 void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len) 181 { 182 u32 ori_len = 0, dup_len = 0; 183 u8 *ori = NULL; 184 u8 *dup = NULL; 185 186 if (!buf || !buf_len) 187 return; 188 189 if (!src || !src_len) 190 goto keep_ori; 191 192 /* duplicate src */ 193 dup = rtw_malloc(src_len); 194 if (dup) { 195 dup_len = src_len; 196 memcpy(dup, src, dup_len); 197 } 198 199 keep_ori: 200 ori = *buf; 201 ori_len = *buf_len; 202 203 /* replace buf with dup */ 204 *buf_len = 0; 205 *buf = dup; 206 *buf_len = dup_len; 207 208 /* free ori */ 209 if (ori && ori_len > 0) 210 kfree(ori); 211 } 212 213 214 /** 215 * rtw_cbuf_full - test if cbuf is full 216 * @cbuf: pointer of struct rtw_cbuf 217 * 218 * Returns: true if cbuf is full 219 */ 220 inline bool rtw_cbuf_full(struct rtw_cbuf *cbuf) 221 { 222 return (cbuf->write == cbuf->read - 1) ? true : false; 223 } 224 225 /** 226 * rtw_cbuf_empty - test if cbuf is empty 227 * @cbuf: pointer of struct rtw_cbuf 228 * 229 * Returns: true if cbuf is empty 230 */ 231 inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf) 232 { 233 return (cbuf->write == cbuf->read) ? true : false; 234 } 235 236 /** 237 * rtw_cbuf_push - push a pointer into cbuf 238 * @cbuf: pointer of struct rtw_cbuf 239 * @buf: pointer to push in 240 * 241 * Lock free operation, be careful of the use scheme 242 * Returns: true push success 243 */ 244 bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf) 245 { 246 if (rtw_cbuf_full(cbuf)) 247 return _FAIL; 248 249 cbuf->bufs[cbuf->write] = buf; 250 cbuf->write = (cbuf->write + 1) % cbuf->size; 251 252 return _SUCCESS; 253 } 254 255 /** 256 * rtw_cbuf_pop - pop a pointer from cbuf 257 * @cbuf: pointer of struct rtw_cbuf 258 * 259 * Lock free operation, be careful of the use scheme 260 * Returns: pointer popped out 261 */ 262 void *rtw_cbuf_pop(struct rtw_cbuf *cbuf) 263 { 264 void *buf; 265 if (rtw_cbuf_empty(cbuf)) 266 return NULL; 267 268 buf = cbuf->bufs[cbuf->read]; 269 cbuf->read = (cbuf->read + 1) % cbuf->size; 270 271 return buf; 272 } 273 274 /** 275 * rtw_cbuf_alloc - allocate a rtw_cbuf with given size and do initialization 276 * @size: size of pointer 277 * 278 * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure 279 */ 280 struct rtw_cbuf *rtw_cbuf_alloc(u32 size) 281 { 282 struct rtw_cbuf *cbuf; 283 284 cbuf = rtw_malloc(sizeof(*cbuf) + sizeof(void *) * size); 285 286 if (cbuf) { 287 cbuf->write = cbuf->read = 0; 288 cbuf->size = size; 289 } 290 291 return cbuf; 292 } 293