linux/drivers/staging/r8188eu/os_dep/osdep_service.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright(c) 2007 - 2012 Realtek Corporation. */
   3
   4#define _OSDEP_SERVICE_C_
   5
   6#include "../include/osdep_service.h"
   7#include "../include/drv_types.h"
   8#include "../include/recv_osdep.h"
   9#include "../include/rtw_ioctl_set.h"
  10
  11/*
  12* Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE
  13* @return: one of RTW_STATUS_CODE
  14*/
  15inline int RTW_STATUS_CODE(int error_code)
  16{
  17        if (error_code >= 0)
  18                return _SUCCESS;
  19        return _FAIL;
  20}
  21
  22u32 rtw_atoi(u8 *s)
  23{
  24        int num = 0, flag = 0;
  25        int i;
  26        for (i = 0; i <= strlen(s); i++) {
  27                if (s[i] >= '0' && s[i] <= '9')
  28                        num = num * 10 + s[i] - '0';
  29                else if (s[0] == '-' && i == 0)
  30                        flag = 1;
  31                else
  32                        break;
  33        }
  34        if (flag == 1)
  35                num = num * -1;
  36        return num;
  37}
  38
  39void *rtw_malloc2d(int h, int w, int size)
  40{
  41        int j;
  42
  43        void **a = kzalloc(h * sizeof(void *) + h * w * size, GFP_KERNEL);
  44        if (!a)
  45                return NULL;
  46
  47        for (j = 0; j < h; j++)
  48                a[j] = ((char *)(a + h)) + j * w * size;
  49
  50        return a;
  51}
  52
  53/*
  54For the following list_xxx operations,
  55caller must guarantee the atomic context.
  56Otherwise, there will be racing condition.
  57*/
  58/*
  59Caller must check if the list is empty before calling rtw_list_delete
  60*/
  61
  62u32 _rtw_down_sema(struct semaphore *sema)
  63{
  64        if (down_interruptible(sema))
  65                return _FAIL;
  66        else
  67                return _SUCCESS;
  68}
  69
  70void    _rtw_mutex_init(struct mutex *pmutex)
  71{
  72        mutex_init(pmutex);
  73}
  74
  75void    _rtw_mutex_free(struct mutex *pmutex)
  76{
  77        mutex_destroy(pmutex);
  78}
  79
  80void    _rtw_init_queue(struct __queue *pqueue)
  81{
  82        INIT_LIST_HEAD(&pqueue->queue);
  83        spin_lock_init(&pqueue->lock);
  84}
  85
  86inline u32 rtw_systime_to_ms(u32 systime)
  87{
  88        return systime * 1000 / HZ;
  89}
  90
  91inline u32 rtw_ms_to_systime(u32 ms)
  92{
  93        return ms * HZ / 1000;
  94}
  95
  96/*  the input parameter start use the same unit as jiffies */
  97inline s32 rtw_get_passing_time_ms(u32 start)
  98{
  99        return rtw_systime_to_ms(jiffies - start);
 100}
 101
 102void rtw_usleep_os(int us)
 103{
 104        if (1 < (us / 1000))
 105                msleep(1);
 106        else
 107                msleep((us / 1000) + 1);
 108}
 109
 110#define RTW_SUSPEND_LOCK_NAME "rtw_wifi"
 111
 112static const struct device_type wlan_type = {
 113        .name = "wlan",
 114};
 115
 116struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv,
 117                                                    void *old_priv)
 118{
 119        struct net_device *pnetdev;
 120        struct rtw_netdev_priv_indicator *pnpi;
 121
 122        pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
 123        if (!pnetdev)
 124                goto RETURN;
 125
 126        pnetdev->dev.type = &wlan_type;
 127        pnpi = netdev_priv(pnetdev);
 128        pnpi->priv = old_priv;
 129        pnpi->sizeof_priv = sizeof_priv;
 130
 131RETURN:
 132        return pnetdev;
 133}
 134
 135struct net_device *rtw_alloc_etherdev(int sizeof_priv)
 136{
 137        struct net_device *pnetdev;
 138        struct rtw_netdev_priv_indicator *pnpi;
 139
 140        pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
 141        if (!pnetdev)
 142                goto RETURN;
 143
 144        pnpi = netdev_priv(pnetdev);
 145
 146        pnpi->priv = vzalloc(sizeof_priv);
 147        if (!pnpi->priv) {
 148                free_netdev(pnetdev);
 149                pnetdev = NULL;
 150                goto RETURN;
 151        }
 152
 153        pnpi->sizeof_priv = sizeof_priv;
 154RETURN:
 155        return pnetdev;
 156}
 157
 158void rtw_free_netdev(struct net_device *netdev)
 159{
 160        struct rtw_netdev_priv_indicator *pnpi;
 161
 162        if (!netdev)
 163                goto RETURN;
 164
 165        pnpi = netdev_priv(netdev);
 166
 167        if (!pnpi->priv)
 168                goto RETURN;
 169
 170        vfree(pnpi->priv);
 171        free_netdev(netdev);
 172
 173RETURN:
 174        return;
 175}
 176
 177int rtw_change_ifname(struct adapter *padapter, const char *ifname)
 178{
 179        struct net_device *pnetdev;
 180        struct net_device *cur_pnetdev;
 181        struct rereg_nd_name_data *rereg_priv;
 182        int ret;
 183
 184        if (!padapter)
 185                goto error;
 186
 187        cur_pnetdev = padapter->pnetdev;
 188        rereg_priv = &padapter->rereg_nd_name_priv;
 189
 190        /* free the old_pnetdev */
 191        if (rereg_priv->old_pnetdev) {
 192                free_netdev(rereg_priv->old_pnetdev);
 193                rereg_priv->old_pnetdev = NULL;
 194        }
 195
 196        if (!rtnl_is_locked())
 197                unregister_netdev(cur_pnetdev);
 198        else
 199                unregister_netdevice(cur_pnetdev);
 200
 201        rtw_proc_remove_one(cur_pnetdev);
 202
 203        rereg_priv->old_pnetdev = cur_pnetdev;
 204
 205        pnetdev = rtw_init_netdev(padapter);
 206        if (!pnetdev)  {
 207                ret = -1;
 208                goto error;
 209        }
 210
 211        SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter)));
 212
 213        rtw_init_netdev_name(pnetdev, ifname);
 214
 215        memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN);
 216
 217        if (!rtnl_is_locked())
 218                ret = register_netdev(pnetdev);
 219        else
 220                ret = register_netdevice(pnetdev);
 221        if (ret != 0)
 222                goto error;
 223
 224        rtw_proc_init_one(pnetdev);
 225        return 0;
 226error:
 227        return -1;
 228}
 229
 230void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len)
 231{
 232        u32 dup_len = 0;
 233        u8 *ori = NULL;
 234        u8 *dup = NULL;
 235
 236        if (!buf || !buf_len)
 237                return;
 238
 239        if (!src || !src_len)
 240                goto keep_ori;
 241
 242        /* duplicate src */
 243        dup = kmalloc(src_len, GFP_ATOMIC);
 244        if (dup) {
 245                dup_len = src_len;
 246                memcpy(dup, src, dup_len);
 247        }
 248
 249keep_ori:
 250        ori = *buf;
 251
 252        /* replace buf with dup */
 253        *buf_len = 0;
 254        *buf = dup;
 255        *buf_len = dup_len;
 256
 257        /* free ori */
 258        kfree(ori);
 259}
 260
 261/**
 262 * rtw_cbuf_full - test if cbuf is full
 263 * @cbuf: pointer of struct rtw_cbuf
 264 *
 265 * Returns: true if cbuf is full
 266 */
 267inline bool rtw_cbuf_full(struct rtw_cbuf *cbuf)
 268{
 269        return (cbuf->write == cbuf->read - 1) ? true : false;
 270}
 271
 272/**
 273 * rtw_cbuf_empty - test if cbuf is empty
 274 * @cbuf: pointer of struct rtw_cbuf
 275 *
 276 * Returns: true if cbuf is empty
 277 */
 278inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf)
 279{
 280        return (cbuf->write == cbuf->read) ? true : false;
 281}
 282
 283/**
 284 * rtw_cbuf_push - push a pointer into cbuf
 285 * @cbuf: pointer of struct rtw_cbuf
 286 * @buf: pointer to push in
 287 *
 288 * Lock free operation, be careful of the use scheme
 289 * Returns: true push success
 290 */
 291bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf)
 292{
 293        if (rtw_cbuf_full(cbuf))
 294                return _FAIL;
 295
 296        if (0)
 297                DBG_88E("%s on %u\n", __func__, cbuf->write);
 298        cbuf->bufs[cbuf->write] = buf;
 299        cbuf->write = (cbuf->write + 1) % cbuf->size;
 300
 301        return _SUCCESS;
 302}
 303
 304/**
 305 * rtw_cbuf_pop - pop a pointer from cbuf
 306 * @cbuf: pointer of struct rtw_cbuf
 307 *
 308 * Lock free operation, be careful of the use scheme
 309 * Returns: pointer popped out
 310 */
 311void *rtw_cbuf_pop(struct rtw_cbuf *cbuf)
 312{
 313        void *buf;
 314        if (rtw_cbuf_empty(cbuf))
 315                return NULL;
 316
 317        if (0)
 318                DBG_88E("%s on %u\n", __func__, cbuf->read);
 319        buf = cbuf->bufs[cbuf->read];
 320        cbuf->read = (cbuf->read + 1) % cbuf->size;
 321
 322        return buf;
 323}
 324
 325/**
 326 * rtw_cbuf_alloc - allocate a rtw_cbuf with given size and do initialization
 327 * @size: size of pointer
 328 *
 329 * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure
 330 */
 331struct rtw_cbuf *rtw_cbuf_alloc(u32 size)
 332{
 333        struct rtw_cbuf *cbuf;
 334
 335        cbuf = kmalloc(sizeof(*cbuf) + sizeof(void *) * size, GFP_KERNEL);
 336
 337        if (cbuf) {
 338                cbuf->write = 0;
 339                cbuf->read = 0;
 340                cbuf->size = size;
 341        }
 342        return cbuf;
 343}
 344