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 struct sk_buff *_rtw_skb_clone(struct sk_buff *skb) 51 { 52 return skb_clone(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); 53 } 54 55 inline int _rtw_netif_rx(_nic_hdl ndev, struct sk_buff *skb) 56 { 57 skb->dev = ndev; 58 return netif_rx(skb); 59 } 60 61 void _rtw_init_queue(struct __queue *pqueue) 62 { 63 INIT_LIST_HEAD(&(pqueue->queue)); 64 65 spin_lock_init(&(pqueue->lock)); 66 } 67 68 /* 69 * Open a file with the specific @param path, @param flag, @param mode 70 * @param fpp the pointer of struct file pointer to get struct file pointer while file opening is success 71 * @param path the path of the file to open 72 * @param flag file operation flags, please refer to linux document 73 * @param mode please refer to linux document 74 * @return Linux specific error code 75 */ 76 static int openFile(struct file **fpp, char *path, int flag, int mode) 77 { 78 struct file *fp; 79 80 fp =filp_open(path, flag, mode); 81 if (IS_ERR(fp)) { 82 *fpp = NULL; 83 return PTR_ERR(fp); 84 } 85 else { 86 *fpp =fp; 87 return 0; 88 } 89 } 90 91 /* 92 * Close the file with the specific @param fp 93 * @param fp the pointer of struct file to close 94 * @return always 0 95 */ 96 static int closeFile(struct file *fp) 97 { 98 filp_close(fp, NULL); 99 return 0; 100 } 101 102 static int readFile(struct file *fp, char *buf, int len) 103 { 104 int rlen = 0, sum = 0; 105 106 if (!fp->f_op || !fp->f_op->read) 107 return -EPERM; 108 109 while (sum<len) { 110 rlen =fp->f_op->read(fp, (char __force __user *)buf+sum, len-sum, &fp->f_pos); 111 if (rlen>0) 112 sum+=rlen; 113 else if (0 != rlen) 114 return rlen; 115 else 116 break; 117 } 118 119 return sum; 120 121 } 122 123 /* 124 * Test if the specifi @param path is a file and readable 125 * @param path the path of the file to test 126 * @return Linux specific error code 127 */ 128 static int isFileReadable(char *path) 129 { 130 struct file *fp; 131 int ret = 0; 132 mm_segment_t oldfs; 133 char buf; 134 135 fp =filp_open(path, O_RDONLY, 0); 136 if (IS_ERR(fp)) { 137 ret = PTR_ERR(fp); 138 } 139 else { 140 oldfs = get_fs(); set_fs(get_ds()); 141 142 if (1!=readFile(fp, &buf, 1)) 143 ret = -EINVAL; 144 145 set_fs(oldfs); 146 filp_close(fp, NULL); 147 } 148 return ret; 149 } 150 151 /* 152 * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most 153 * @param path the path of the file to open and read 154 * @param buf the starting address of the buffer to store file content 155 * @param sz how many bytes to read at most 156 * @return the byte we've read, or Linux specific error code 157 */ 158 static int retriveFromFile(char *path, u8 *buf, u32 sz) 159 { 160 int ret =-1; 161 mm_segment_t oldfs; 162 struct file *fp; 163 164 if (path && buf) { 165 if (0 == (ret =openFile(&fp, path, O_RDONLY, 0))) { 166 DBG_871X("%s openFile path:%s fp =%p\n", __func__, path , fp); 167 168 oldfs = get_fs(); set_fs(get_ds()); 169 ret =readFile(fp, buf, sz); 170 set_fs(oldfs); 171 closeFile(fp); 172 173 DBG_871X("%s readFile, ret:%d\n", __func__, ret); 174 175 } else { 176 DBG_871X("%s openFile path:%s Fail, ret:%d\n", __func__, path, ret); 177 } 178 } else { 179 DBG_871X("%s NULL pointer\n", __func__); 180 ret = -EINVAL; 181 } 182 return ret; 183 } 184 185 /* 186 * Test if the specifi @param path is a file and readable 187 * @param path the path of the file to test 188 * @return true or false 189 */ 190 int rtw_is_file_readable(char *path) 191 { 192 if (isFileReadable(path) == 0) 193 return true; 194 else 195 return false; 196 } 197 198 /* 199 * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most 200 * @param path the path of the file to open and read 201 * @param buf the starting address of the buffer to store file content 202 * @param sz how many bytes to read at most 203 * @return the byte we've read 204 */ 205 int rtw_retrive_from_file(char *path, u8 *buf, u32 sz) 206 { 207 int ret =retriveFromFile(path, buf, sz); 208 return ret>= 0?ret:0; 209 } 210 211 struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv) 212 { 213 struct net_device *pnetdev; 214 struct rtw_netdev_priv_indicator *pnpi; 215 216 pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4); 217 if (!pnetdev) 218 goto RETURN; 219 220 pnpi = netdev_priv(pnetdev); 221 pnpi->priv =old_priv; 222 pnpi->sizeof_priv =sizeof_priv; 223 224 RETURN: 225 return pnetdev; 226 } 227 228 struct net_device *rtw_alloc_etherdev(int sizeof_priv) 229 { 230 struct net_device *pnetdev; 231 struct rtw_netdev_priv_indicator *pnpi; 232 233 pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4); 234 if (!pnetdev) 235 goto RETURN; 236 237 pnpi = netdev_priv(pnetdev); 238 239 pnpi->priv = vzalloc(sizeof_priv); 240 if (!pnpi->priv) { 241 free_netdev(pnetdev); 242 pnetdev = NULL; 243 goto RETURN; 244 } 245 246 pnpi->sizeof_priv =sizeof_priv; 247 RETURN: 248 return pnetdev; 249 } 250 251 void rtw_free_netdev(struct net_device * netdev) 252 { 253 struct rtw_netdev_priv_indicator *pnpi; 254 255 if (!netdev) 256 goto RETURN; 257 258 pnpi = netdev_priv(netdev); 259 260 if (!pnpi->priv) 261 goto RETURN; 262 263 vfree(pnpi->priv); 264 free_netdev(netdev); 265 266 RETURN: 267 return; 268 } 269 270 int rtw_change_ifname(struct adapter *padapter, const char *ifname) 271 { 272 struct net_device *pnetdev; 273 struct net_device *cur_pnetdev; 274 struct rereg_nd_name_data *rereg_priv; 275 int ret; 276 277 if (!padapter) 278 goto error; 279 280 cur_pnetdev = padapter->pnetdev; 281 rereg_priv = &padapter->rereg_nd_name_priv; 282 283 /* free the old_pnetdev */ 284 if (rereg_priv->old_pnetdev) { 285 free_netdev(rereg_priv->old_pnetdev); 286 rereg_priv->old_pnetdev = NULL; 287 } 288 289 if (!rtnl_is_locked()) 290 unregister_netdev(cur_pnetdev); 291 else 292 unregister_netdevice(cur_pnetdev); 293 294 rereg_priv->old_pnetdev =cur_pnetdev; 295 296 pnetdev = rtw_init_netdev(padapter); 297 if (!pnetdev) { 298 ret = -1; 299 goto error; 300 } 301 302 SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter))); 303 304 rtw_init_netdev_name(pnetdev, ifname); 305 306 memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN); 307 308 if (!rtnl_is_locked()) 309 ret = register_netdev(pnetdev); 310 else 311 ret = register_netdevice(pnetdev); 312 313 if (ret != 0) { 314 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("register_netdev() failed\n")); 315 goto error; 316 } 317 318 return 0; 319 320 error: 321 322 return -1; 323 324 } 325 326 u64 rtw_modular64(u64 x, u64 y) 327 { 328 return do_div(x, y); 329 } 330 331 void rtw_buf_free(u8 **buf, u32 *buf_len) 332 { 333 u32 ori_len; 334 335 if (!buf || !buf_len) 336 return; 337 338 ori_len = *buf_len; 339 340 if (*buf) { 341 *buf_len = 0; 342 kfree(*buf); 343 *buf = NULL; 344 } 345 } 346 347 void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len) 348 { 349 u32 ori_len = 0, dup_len = 0; 350 u8 *ori = NULL; 351 u8 *dup = NULL; 352 353 if (!buf || !buf_len) 354 return; 355 356 if (!src || !src_len) 357 goto keep_ori; 358 359 /* duplicate src */ 360 dup = rtw_malloc(src_len); 361 if (dup) { 362 dup_len = src_len; 363 memcpy(dup, src, dup_len); 364 } 365 366 keep_ori: 367 ori = *buf; 368 ori_len = *buf_len; 369 370 /* replace buf with dup */ 371 *buf_len = 0; 372 *buf = dup; 373 *buf_len = dup_len; 374 375 /* free ori */ 376 if (ori && ori_len > 0) 377 kfree(ori); 378 } 379 380 381 /** 382 * rtw_cbuf_full - test if cbuf is full 383 * @cbuf: pointer of struct rtw_cbuf 384 * 385 * Returns: true if cbuf is full 386 */ 387 inline bool rtw_cbuf_full(struct rtw_cbuf *cbuf) 388 { 389 return (cbuf->write == cbuf->read-1)? true : false; 390 } 391 392 /** 393 * rtw_cbuf_empty - test if cbuf is empty 394 * @cbuf: pointer of struct rtw_cbuf 395 * 396 * Returns: true if cbuf is empty 397 */ 398 inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf) 399 { 400 return (cbuf->write == cbuf->read)? true : false; 401 } 402 403 /** 404 * rtw_cbuf_push - push a pointer into cbuf 405 * @cbuf: pointer of struct rtw_cbuf 406 * @buf: pointer to push in 407 * 408 * Lock free operation, be careful of the use scheme 409 * Returns: true push success 410 */ 411 bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf) 412 { 413 if (rtw_cbuf_full(cbuf)) 414 return _FAIL; 415 416 DBG_871X("%s on %u\n", __func__, cbuf->write); 417 cbuf->bufs[cbuf->write] = buf; 418 cbuf->write = (cbuf->write+1)%cbuf->size; 419 420 return _SUCCESS; 421 } 422 423 /** 424 * rtw_cbuf_pop - pop a pointer from cbuf 425 * @cbuf: pointer of struct rtw_cbuf 426 * 427 * Lock free operation, be careful of the use scheme 428 * Returns: pointer popped out 429 */ 430 void *rtw_cbuf_pop(struct rtw_cbuf *cbuf) 431 { 432 void *buf; 433 if (rtw_cbuf_empty(cbuf)) 434 return NULL; 435 436 DBG_871X("%s on %u\n", __func__, cbuf->read); 437 buf = cbuf->bufs[cbuf->read]; 438 cbuf->read = (cbuf->read+1)%cbuf->size; 439 440 return buf; 441 } 442 443 /** 444 * rtw_cbuf_alloc - allocte a rtw_cbuf with given size and do initialization 445 * @size: size of pointer 446 * 447 * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure 448 */ 449 struct rtw_cbuf *rtw_cbuf_alloc(u32 size) 450 { 451 struct rtw_cbuf *cbuf; 452 453 cbuf = rtw_malloc(sizeof(*cbuf) + sizeof(void *) * size); 454 455 if (cbuf) { 456 cbuf->write = cbuf->read = 0; 457 cbuf->size = size; 458 } 459 460 return cbuf; 461 } 462