1 // SPDX-License-Identifier: ISC 2 /* 3 * Copyright (C) 2019 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 */ 5 6 #include "mt76.h" 7 8 struct sk_buff * 9 mt76_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 } 28 EXPORT_SYMBOL_GPL(mt76_mcu_msg_alloc); 29 30 struct 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 } 45 EXPORT_SYMBOL_GPL(mt76_mcu_get_response); 46 47 void 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 } 52 EXPORT_SYMBOL_GPL(mt76_mcu_rx_event); 53