OSDN Git Service

Make certain that if, for, while, do, and switch have a space before an open paren
[android-x86/external-modules-rtl8723au.git] / os_dep / osdep_service.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20
21
22 #define _OSDEP_SERVICE_C_
23
24 #include <drv_conf.h>
25 #include <osdep_service.h>
26 #include <drv_types.h>
27 #include <recv_osdep.h>
28 #include <linux/vmalloc.h>
29
30 #define RT_TAG  '1178'
31
32 /*
33 * Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE
34 * @return: one of RTW_STATUS_CODE
35 */
36 inline int RTW_STATUS_CODE(int error_code){
37         if (error_code >=0)
38                 return _SUCCESS;
39
40         switch (error_code) {
41                 //case -ETIMEDOUT:
42                 //      return RTW_STATUS_TIMEDOUT;
43                 default:
44                         return _FAIL;
45         }
46 }
47
48 u32 rtw_atoi(u8* s)
49 {
50         int num=0,flag=0;
51         int i;
52         for (i=0;i<=strlen(s);i++)
53         {
54           if (s[i] >= '0' && s[i] <= '9')
55                  num = num * 10 + s[i] -'0';
56           else if (s[0] == '-' && i==0)
57                  flag =1;
58           else
59                   break;
60          }
61
62         if (flag == 1)
63            num = num * -1;
64
65          return(num);
66
67 }
68
69 inline u8* _rtw_vmalloc(u32 sz)
70 {
71         u8      *pbuf;
72         pbuf = vmalloc(sz);
73
74         return pbuf;
75 }
76
77 inline u8* _rtw_zvmalloc(u32 sz)
78 {
79         u8      *pbuf;
80         pbuf = _rtw_vmalloc(sz);
81         if (pbuf != NULL)
82                 memset(pbuf, 0, sz);
83         return pbuf;
84 }
85
86 inline void _rtw_vmfree(u8 *pbuf, u32 sz)
87 {
88         vfree(pbuf);
89 }
90
91 u8* _rtw_malloc(u32 sz)
92 {
93
94         u8      *pbuf=NULL;
95
96         pbuf = kmalloc(sz,in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
97         return pbuf;
98 }
99
100 u8* _rtw_zmalloc(u32 sz)
101 {
102         u8      *pbuf = _rtw_malloc(sz);
103
104         if (pbuf != NULL)
105                 memset(pbuf, 0, sz);
106         return pbuf;
107 }
108
109 void    _rtw_mfree(u8 *pbuf, u32 sz)
110 {
111         kfree(pbuf);
112 }
113
114 void* rtw_malloc2d(int h, int w, int size)
115 {
116         int j;
117
118         void **a = (void **) rtw_zmalloc( h*sizeof(void *) + h*w*size );
119         if (a == NULL)
120         {
121                 DBG_871X("%s: alloc memory fail!\n", __FUNCTION__);
122                 return NULL;
123         }
124
125         for ( j=0; j<h; j++ )
126                 a[j] = ((char *)(a+h)) + j*w*size;
127
128         return a;
129 }
130
131 void rtw_mfree2d(void *pbuf, int h, int w, int size)
132 {
133         rtw_mfree((u8 *)pbuf, h*sizeof(void*) + w*h*size);
134 }
135
136 int     _rtw_memcmp(void *dst, void *src, u32 sz)
137 {
138 //under Linux/GNU/GLibc, the return value of memcmp for two same mem. chunk is 0
139         if (!(memcmp(dst, src, sz)))
140                 return true;
141         else
142                 return false;
143 }
144
145 void _rtw_init_listhead(_list *list)
146 {
147         INIT_LIST_HEAD(list);
148 }
149
150 /*
151 For the following list_xxx operations,
152 caller must guarantee the atomic context.
153 Otherwise, there will be racing condition.
154 */
155 u32     rtw_is_list_empty(_list *phead)
156 {
157         if (list_empty(phead))
158                 return true;
159         else
160                 return false;
161 }
162
163 void rtw_list_insert_head(_list *plist, _list *phead)
164 {
165         list_add(plist, phead);
166 }
167
168 void rtw_list_insert_tail(_list *plist, _list *phead)
169 {
170         list_add_tail(plist, phead);
171 }
172
173 /*
174
175 Caller must check if the list is empty before calling rtw_list_delete
176
177 */
178
179
180 void _rtw_init_sema(_sema       *sema, int init_val)
181 {
182         sema_init(sema, init_val);
183 }
184
185 void _rtw_free_sema(_sema       *sema)
186 {
187 }
188
189 void _rtw_up_sema(_sema *sema)
190 {
191         up(sema);
192 }
193
194 u32 _rtw_down_sema(_sema *sema)
195 {
196         if (down_interruptible(sema))
197                 return _FAIL;
198         else
199                 return _SUCCESS;
200 }
201
202 void    _rtw_mutex_init(_mutex *pmutex)
203 {
204 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
205         mutex_init(pmutex);
206 #else
207         init_MUTEX(pmutex);
208 #endif
209 }
210
211 void    _rtw_mutex_free(_mutex *pmutex)
212 {
213 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
214         mutex_destroy(pmutex);
215 #endif
216 }
217
218 void    _rtw_spinlock_init(_lock *plock)
219 {
220         spin_lock_init(plock);
221 }
222
223 void    _rtw_spinlock_free(_lock *plock)
224 {
225 }
226
227 void    _rtw_spinlock(_lock     *plock)
228 {
229         spin_lock(plock);
230 }
231
232 void    _rtw_spinunlock(_lock *plock)
233 {
234         spin_unlock(plock);
235 }
236
237 void    _rtw_spinlock_ex(_lock  *plock)
238 {
239         spin_lock(plock);
240 }
241
242 void    _rtw_spinunlock_ex(_lock *plock)
243 {
244         spin_unlock(plock);
245 }
246
247 void    _rtw_init_queue(_queue  *pqueue)
248 {
249         _rtw_init_listhead(&(pqueue->queue));
250
251         _rtw_spinlock_init(&(pqueue->lock));
252 }
253
254 u32       _rtw_queue_empty(_queue       *pqueue)
255 {
256         return (rtw_is_list_empty(&(pqueue->queue)));
257 }
258
259
260 u32 rtw_end_of_queue_search(_list *head, _list *plist)
261 {
262         if (head == plist)
263                 return true;
264         else
265                 return false;
266 }
267
268 u32     rtw_get_current_time(void)
269 {
270         return jiffies;
271 }
272
273 inline u32 rtw_systime_to_ms(u32 systime)
274 {
275         return systime * 1000 / HZ;
276 }
277
278 inline u32 rtw_ms_to_systime(u32 ms)
279 {
280         return ms * HZ / 1000;
281 }
282
283 // the input parameter start use the same unit as returned by rtw_get_current_time
284 inline s32 rtw_get_passing_time_ms(u32 start)
285 {
286         return rtw_systime_to_ms(jiffies-start);
287 }
288
289 inline s32 rtw_get_time_interval_ms(u32 start, u32 end)
290 {
291         return rtw_systime_to_ms(end-start);
292 }
293
294 void rtw_sleep_schedulable(int ms)
295 {
296     u32 delta;
297
298     delta = (ms * HZ)/1000;//(ms)
299     if (delta == 0) {
300         delta = 1;// 1 ms
301     }
302     set_current_state(TASK_INTERRUPTIBLE);
303     if (schedule_timeout(delta) != 0) {
304         return ;
305     }
306     return;
307 }
308
309 void rtw_msleep_os(int ms)
310 {
311         msleep((unsigned int)ms);
312 }
313
314 void rtw_usleep_os(int us)
315 {
316       // msleep((unsigned int)us);
317       if ( 1 < (us/1000) )
318                 msleep(1);
319       else
320                 msleep( (us/1000) + 1);
321 }
322
323 #ifdef DBG_DELAY_OS
324 void _rtw_mdelay_os(int ms, const char *func, const int line)
325 {
326         DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, ms);
327
328         mdelay((unsigned long)ms);
329 }
330
331 void _rtw_udelay_os(int us, const char *func, const int line)
332 {
333         DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, us);
334
335       udelay((unsigned long)us);
336 }
337 #else
338 void rtw_mdelay_os(int ms)
339 {
340         mdelay((unsigned long)ms);
341 }
342 void rtw_udelay_os(int us)
343 {
344       udelay((unsigned long)us);
345 }
346 #endif
347
348 void rtw_yield_os()
349 {
350         yield();
351 }
352
353 #define RTW_SUSPEND_LOCK_NAME "rtw_wifi"
354
355 #ifdef CONFIG_WAKELOCK
356 static struct wake_lock rtw_suspend_lock;
357 #elif defined(CONFIG_ANDROID_POWER)
358 static android_suspend_lock_t rtw_suspend_lock ={
359         .name = RTW_SUSPEND_LOCK_NAME
360 };
361 #endif
362
363 inline void rtw_suspend_lock_init()
364 {
365         #ifdef CONFIG_WAKELOCK
366         wake_lock_init(&rtw_suspend_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_LOCK_NAME);
367         #elif defined(CONFIG_ANDROID_POWER)
368         android_init_suspend_lock(&rtw_suspend_lock);
369         #endif
370 }
371
372 inline void rtw_suspend_lock_uninit()
373 {
374         #ifdef CONFIG_WAKELOCK
375         wake_lock_destroy(&rtw_suspend_lock);
376         #elif defined(CONFIG_ANDROID_POWER)
377         android_uninit_suspend_lock(&rtw_suspend_lock);
378         #endif
379 }
380
381 inline void rtw_lock_suspend()
382 {
383         #ifdef CONFIG_WAKELOCK
384         wake_lock(&rtw_suspend_lock);
385         #elif defined(CONFIG_ANDROID_POWER)
386         android_lock_suspend(&rtw_suspend_lock);
387         #endif
388
389         #if  defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
390         //DBG_871X("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count);
391         #endif
392 }
393
394 inline void rtw_unlock_suspend()
395 {
396         #ifdef CONFIG_WAKELOCK
397         wake_unlock(&rtw_suspend_lock);
398         #elif defined(CONFIG_ANDROID_POWER)
399         android_unlock_suspend(&rtw_suspend_lock);
400         #endif
401
402         #if  defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
403         //DBG_871X("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count);
404         #endif
405 }
406
407 #ifdef CONFIG_WOWLAN
408 inline void rtw_lock_suspend_timeout(long timeout)
409 {
410         #ifdef CONFIG_WAKELOCK
411         wake_lock_timeout(&rtw_suspend_lock, timeout);
412         #elif defined(CONFIG_ANDROID_POWER)
413         android_lock_suspend_auto_expire(&rtw_suspend_lock, timeout);
414         #endif
415 }
416 #endif //CONFIG_WOWLAN
417
418 inline void ATOMIC_SET(ATOMIC_T *v, int i)
419 {
420         atomic_set(v,i);
421 }
422
423 inline int ATOMIC_READ(ATOMIC_T *v)
424 {
425         return atomic_read(v);
426 }
427
428 inline void ATOMIC_ADD(ATOMIC_T *v, int i)
429 {
430         atomic_add(i,v);
431 }
432 inline void ATOMIC_SUB(ATOMIC_T *v, int i)
433 {
434         atomic_sub(i,v);
435 }
436
437 inline void ATOMIC_INC(ATOMIC_T *v)
438 {
439         atomic_inc(v);
440 }
441
442 inline void ATOMIC_DEC(ATOMIC_T *v)
443 {
444         atomic_dec(v);
445 }
446
447 inline int ATOMIC_ADD_RETURN(ATOMIC_T *v, int i)
448 {
449         return atomic_add_return(i,v);
450 }
451
452 inline int ATOMIC_SUB_RETURN(ATOMIC_T *v, int i)
453 {
454         return atomic_sub_return(i,v);
455 }
456
457 inline int ATOMIC_INC_RETURN(ATOMIC_T *v)
458 {
459         return atomic_inc_return(v);
460 }
461
462 inline int ATOMIC_DEC_RETURN(ATOMIC_T *v)
463 {
464         return atomic_dec_return(v);
465 }
466
467 /*
468 * Open a file with the specific @param path, @param flag, @param mode
469 * @param fpp the pointer of struct file pointer to get struct file pointer while file opening is success
470 * @param path the path of the file to open
471 * @param flag file operation flags, please refer to linux document
472 * @param mode please refer to linux document
473 * @return Linux specific error code
474 */
475 static int openFile(struct file **fpp, char *path, int flag, int mode)
476 {
477         struct file *fp;
478
479         fp=filp_open(path, flag, mode);
480         if (IS_ERR(fp)) {
481                 *fpp=NULL;
482                 return PTR_ERR(fp);
483         }
484         else {
485                 *fpp=fp;
486                 return 0;
487         }
488 }
489
490 /*
491 * Close the file with the specific @param fp
492 * @param fp the pointer of struct file to close
493 * @return always 0
494 */
495 static int closeFile(struct file *fp)
496 {
497         filp_close(fp,NULL);
498         return 0;
499 }
500
501 static int readFile(struct file *fp,char *buf,int len)
502 {
503         int rlen=0, sum=0;
504
505         if (!fp->f_op || !fp->f_op->read)
506                 return -EPERM;
507
508         while (sum<len) {
509                 rlen=fp->f_op->read(fp,buf+sum,len-sum, &fp->f_pos);
510                 if (rlen>0)
511                         sum+=rlen;
512                 else if (0 != rlen)
513                         return rlen;
514                 else
515                         break;
516         }
517
518         return  sum;
519
520 }
521
522 static int writeFile(struct file *fp,char *buf,int len)
523 {
524         int wlen=0, sum=0;
525
526         if (!fp->f_op || !fp->f_op->write)
527                 return -EPERM;
528
529         while (sum<len) {
530                 wlen=fp->f_op->write(fp,buf+sum,len-sum, &fp->f_pos);
531                 if (wlen>0)
532                         sum+=wlen;
533                 else if (0 != wlen)
534                         return wlen;
535                 else
536                         break;
537         }
538
539         return sum;
540
541 }
542
543 /*
544 * Test if the specifi @param path is a file and readable
545 * @param path the path of the file to test
546 * @return Linux specific error code
547 */
548 static int isFileReadable(char *path)
549 {
550         struct file *fp;
551         int ret = 0;
552         mm_segment_t oldfs;
553         char buf;
554
555         fp=filp_open(path, O_RDONLY, 0);
556         if (IS_ERR(fp)) {
557                 ret = PTR_ERR(fp);
558         }
559         else {
560                 oldfs = get_fs(); set_fs(get_ds());
561
562                 if (1!=readFile(fp, &buf, 1))
563                         ret = PTR_ERR(fp);
564
565                 set_fs(oldfs);
566                 filp_close(fp,NULL);
567         }
568         return ret;
569 }
570
571 /*
572 * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most
573 * @param path the path of the file to open and read
574 * @param buf the starting address of the buffer to store file content
575 * @param sz how many bytes to read at most
576 * @return the byte we've read, or Linux specific error code
577 */
578 static int retriveFromFile(char *path, u8* buf, u32 sz)
579 {
580         int ret =-1;
581         mm_segment_t oldfs;
582         struct file *fp;
583
584         if (path && buf) {
585                 if ( 0 == (ret=openFile(&fp,path, O_RDONLY, 0)) ){
586                         DBG_871X("%s openFile path:%s fp=%p\n",__FUNCTION__, path ,fp);
587
588                         oldfs = get_fs(); set_fs(get_ds());
589                         ret=readFile(fp, buf, sz);
590                         set_fs(oldfs);
591                         closeFile(fp);
592
593                         DBG_871X("%s readFile, ret:%d\n",__FUNCTION__, ret);
594
595                 } else {
596                         DBG_871X("%s openFile path:%s Fail, ret:%d\n",__FUNCTION__, path, ret);
597                 }
598         } else {
599                 DBG_871X("%s NULL pointer\n",__FUNCTION__);
600                 ret =  -EINVAL;
601         }
602         return ret;
603 }
604
605 /*
606 * Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file
607 * @param path the path of the file to open and write
608 * @param buf the starting address of the data to write into file
609 * @param sz how many bytes to write at most
610 * @return the byte we've written, or Linux specific error code
611 */
612 static int storeToFile(char *path, u8* buf, u32 sz)
613 {
614         int ret =0;
615         mm_segment_t oldfs;
616         struct file *fp;
617
618         if (path && buf) {
619                 if ( 0 == (ret=openFile(&fp, path, O_CREAT|O_WRONLY, 0666)) ) {
620                         DBG_871X("%s openFile path:%s fp=%p\n",__FUNCTION__, path ,fp);
621
622                         oldfs = get_fs(); set_fs(get_ds());
623                         ret=writeFile(fp, buf, sz);
624                         set_fs(oldfs);
625                         closeFile(fp);
626
627                         DBG_871X("%s writeFile, ret:%d\n",__FUNCTION__, ret);
628
629                 } else {
630                         DBG_871X("%s openFile path:%s Fail, ret:%d\n",__FUNCTION__, path, ret);
631                 }
632         } else {
633                 DBG_871X("%s NULL pointer\n",__FUNCTION__);
634                 ret =  -EINVAL;
635         }
636         return ret;
637 }
638
639 /*
640 * Test if the specifi @param path is a file and readable
641 * @param path the path of the file to test
642 * @return true or false
643 */
644 int rtw_is_file_readable(char *path)
645 {
646         if (isFileReadable(path) == 0)
647                 return true;
648         else
649                 return false;
650 }
651
652 /*
653 * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most
654 * @param path the path of the file to open and read
655 * @param buf the starting address of the buffer to store file content
656 * @param sz how many bytes to read at most
657 * @return the byte we've read
658 */
659 int rtw_retrive_from_file(char *path, u8* buf, u32 sz)
660 {
661         int ret =retriveFromFile(path, buf, sz);
662         return ret>=0?ret:0;
663 }
664
665 /*
666 * Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file
667 * @param path the path of the file to open and write
668 * @param buf the starting address of the data to write into file
669 * @param sz how many bytes to write at most
670 * @return the byte we've written
671 */
672 int rtw_store_to_file(char *path, u8* buf, u32 sz)
673 {
674         int ret =storeToFile(path, buf, sz);
675         return ret>=0?ret:0;
676 }
677
678 #if 1 //#ifdef MEM_ALLOC_REFINE_ADAPTOR
679 struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv)
680 {
681         struct net_device *pnetdev;
682         struct rtw_netdev_priv_indicator *pnpi;
683
684 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
685         pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
686 #else
687         pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
688 #endif
689         if (!pnetdev)
690                 goto RETURN;
691
692         pnpi = netdev_priv(pnetdev);
693         pnpi->priv=old_priv;
694         pnpi->sizeof_priv=sizeof_priv;
695
696 RETURN:
697         return pnetdev;
698 }
699
700 struct net_device *rtw_alloc_etherdev(int sizeof_priv)
701 {
702         struct net_device *pnetdev;
703         struct rtw_netdev_priv_indicator *pnpi;
704
705 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
706         pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
707 #else
708         pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
709 #endif
710         if (!pnetdev)
711                 goto RETURN;
712
713         pnpi = netdev_priv(pnetdev);
714
715         pnpi->priv = rtw_zvmalloc(sizeof_priv);
716         if (!pnpi->priv) {
717                 free_netdev(pnetdev);
718                 pnetdev = NULL;
719                 goto RETURN;
720         }
721
722         pnpi->sizeof_priv=sizeof_priv;
723 RETURN:
724         return pnetdev;
725 }
726
727 void rtw_free_netdev(struct net_device * netdev)
728 {
729         struct rtw_netdev_priv_indicator *pnpi;
730
731         if (!netdev)
732                 goto RETURN;
733
734         pnpi = netdev_priv(netdev);
735
736         if (!pnpi->priv)
737                 goto RETURN;
738
739         rtw_vmfree(pnpi->priv, pnpi->sizeof_priv);
740         free_netdev(netdev);
741
742 RETURN:
743         return;
744 }
745
746 /*
747 * Jeff: this function should be called under ioctl (rtnl_lock is accquired) while
748 * LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
749 */
750 int rtw_change_ifname(_adapter *padapter, const char *ifname)
751 {
752         struct net_device *pnetdev;
753         struct net_device *cur_pnetdev = padapter->pnetdev;
754         struct rereg_nd_name_data *rereg_priv;
755         int ret;
756
757         if (!padapter)
758                 goto error;
759
760         rereg_priv = &padapter->rereg_nd_name_priv;
761
762         //free the old_pnetdev
763         if (rereg_priv->old_pnetdev) {
764                 free_netdev(rereg_priv->old_pnetdev);
765                 rereg_priv->old_pnetdev = NULL;
766         }
767
768 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
769         if (!rtnl_is_locked())
770                 unregister_netdev(cur_pnetdev);
771         else
772 #endif
773                 unregister_netdevice(cur_pnetdev);
774
775         rtw_proc_remove_one(cur_pnetdev);
776
777         rereg_priv->old_pnetdev=cur_pnetdev;
778
779         pnetdev = rtw_init_netdev(padapter);
780         if (!pnetdev)  {
781                 ret = -1;
782                 goto error;
783         }
784
785         SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter)));
786
787         rtw_init_netdev_name(pnetdev, ifname);
788
789         memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN);
790
791 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
792         if (!rtnl_is_locked())
793                 ret = register_netdev(pnetdev);
794         else
795 #endif
796                 ret = register_netdevice(pnetdev);
797
798         if ( ret != 0) {
799                 RT_TRACE(_module_hci_intfs_c_,_drv_err_,("register_netdev() failed\n"));
800                 goto error;
801         }
802
803         rtw_proc_init_one(pnetdev);
804
805         return 0;
806
807 error:
808
809         return -1;
810
811 }
812 #endif //MEM_ALLOC_REFINE_ADAPTOR
813
814 u64 rtw_modular64(u64 x, u64 y)
815 {
816         return do_div(x, y);
817 }
818
819 u64 rtw_division64(u64 x, u64 y)
820 {
821         do_div(x, y);
822         return x;
823 }
824
825 void rtw_buf_free(u8 **buf, u32 *buf_len)
826 {
827         u32 ori_len;
828
829         if (!buf || !buf_len)
830                 return;
831
832         ori_len = *buf_len;
833
834         if (*buf) {
835                 *buf_len = 0;
836                 _rtw_mfree(*buf, *buf_len);
837                 *buf = NULL;
838         }
839 }
840
841 void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len)
842 {
843         u32 ori_len = 0, dup_len = 0;
844         u8 *ori = NULL;
845         u8 *dup = NULL;
846
847         if (!buf || !buf_len)
848                 return;
849
850         if (!src || !src_len)
851                 goto keep_ori;
852
853         /* duplicate src */
854         dup = rtw_malloc(src_len);
855         if (dup) {
856                 dup_len = src_len;
857                 memcpy(dup, src, dup_len);
858         }
859
860 keep_ori:
861         ori = *buf;
862         ori_len = *buf_len;
863
864         /* replace buf with dup */
865         *buf_len = 0;
866         *buf = dup;
867         *buf_len = dup_len;
868
869         /* free ori */
870         if (ori && ori_len > 0)
871                 _rtw_mfree(ori, ori_len);
872 }