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