linux/drivers/net/wireless/mediatek/mt76/mcu.c
<<
>>
Prefs
   1// SPDX-License-Identifier: ISC
   2/*
   3 * Copyright (C) 2019 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
   4 */
   5
   6#include "mt76.h"
   7
   8struct sk_buff *
   9mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data,
  10                   int data_len)
  11{
  12        const struct mt76_mcu_ops *ops = dev->mcu_ops;
  13        int length = ops->headroom + data_len + ops->tailroom;
  14        struct sk_buff *skb;
  15
  16        skb = alloc_skb(length, GFP_KERNEL);
  17        if (!skb)
  18                return NULL;
  19
  20        memset(skb->head, 0, length);
  21        skb_reserve(skb, ops->headroom);
  22
  23        if (data && data_len)
  24                skb_put_data(skb, data, data_len);
  25
  26        return skb;
  27}
  28EXPORT_SYMBOL_GPL(mt76_mcu_msg_alloc);
  29
  30struct sk_buff *mt76_mcu_get_response(struct mt76_dev *dev,
  31                                      unsigned long expires)
  32{
  33        unsigned long timeout;
  34
  35        if (!time_is_after_jiffies(expires))
  36                return NULL;
  37
  38        timeout = expires - jiffies;
  39        wait_event_timeout(dev->mcu.wait,
  40                           (!skb_queue_empty(&dev->mcu.res_q) ||
  41                            test_bit(MT76_MCU_RESET, &dev->phy.state)),
  42                           timeout);
  43        return skb_dequeue(&dev->mcu.res_q);
  44}
  45EXPORT_SYMBOL_GPL(mt76_mcu_get_response);
  46
  47void mt76_mcu_rx_event(struct mt76_dev *dev, struct sk_buff *skb)
  48{
  49        skb_queue_tail(&dev->mcu.res_q, skb);
  50        wake_up(&dev->mcu.wait);
  51}
  52EXPORT_SYMBOL_GPL(mt76_mcu_rx_event);
  53