linux/drivers/staging/rtl8723bs/os_dep/osdep_service.c
<<
>>
Prefs
   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*/
  14inline int RTW_STATUS_CODE(int error_code)
  15{
  16        if (error_code >= 0)
  17                return _SUCCESS;
  18        return _FAIL;
  19}
  20
  21void *_rtw_malloc(u32 sz)
  22{
  23        return kmalloc(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
  24}
  25
  26void *_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
  36inline struct sk_buff *_rtw_skb_alloc(u32 sz)
  37{
  38        return __dev_alloc_skb(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
  39}
  40
  41inline 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
  46inline int _rtw_netif_rx(struct net_device *ndev, struct sk_buff *skb)
  47{
  48        skb->dev = ndev;
  49        return netif_rx(skb);
  50}
  51
  52void _rtw_init_queue(struct __queue *pqueue)
  53{
  54        INIT_LIST_HEAD(&(pqueue->queue));
  55
  56        spin_lock_init(&(pqueue->lock));
  57}
  58
  59struct 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
  72RETURN:
  73        return pnetdev;
  74}
  75
  76struct 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;
  95RETURN:
  96        return pnetdev;
  97}
  98
  99void 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
 114RETURN:
 115        return;
 116}
 117
 118int 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
 164error:
 165        return -1;
 166}
 167
 168void 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
 180void 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
 199keep_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 */
 220inline 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 */
 231inline 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 */
 244bool 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 */
 262void *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 */
 280struct 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