18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: ISC 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2019 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include "mt76.h" 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_cistruct sk_buff * 98c2ecf20Sopenharmony_cimt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data, 108c2ecf20Sopenharmony_ci int data_len) 118c2ecf20Sopenharmony_ci{ 128c2ecf20Sopenharmony_ci const struct mt76_mcu_ops *ops = dev->mcu_ops; 138c2ecf20Sopenharmony_ci int length = ops->headroom + data_len + ops->tailroom; 148c2ecf20Sopenharmony_ci struct sk_buff *skb; 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci skb = alloc_skb(length, GFP_KERNEL); 178c2ecf20Sopenharmony_ci if (!skb) 188c2ecf20Sopenharmony_ci return NULL; 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci memset(skb->head, 0, length); 218c2ecf20Sopenharmony_ci skb_reserve(skb, ops->headroom); 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci if (data && data_len) 248c2ecf20Sopenharmony_ci skb_put_data(skb, data, data_len); 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci return skb; 278c2ecf20Sopenharmony_ci} 288c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(mt76_mcu_msg_alloc); 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_cistruct sk_buff *mt76_mcu_get_response(struct mt76_dev *dev, 318c2ecf20Sopenharmony_ci unsigned long expires) 328c2ecf20Sopenharmony_ci{ 338c2ecf20Sopenharmony_ci unsigned long timeout; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci if (!time_is_after_jiffies(expires)) 368c2ecf20Sopenharmony_ci return NULL; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci timeout = expires - jiffies; 398c2ecf20Sopenharmony_ci wait_event_timeout(dev->mcu.wait, 408c2ecf20Sopenharmony_ci (!skb_queue_empty(&dev->mcu.res_q) || 418c2ecf20Sopenharmony_ci test_bit(MT76_MCU_RESET, &dev->phy.state)), 428c2ecf20Sopenharmony_ci timeout); 438c2ecf20Sopenharmony_ci return skb_dequeue(&dev->mcu.res_q); 448c2ecf20Sopenharmony_ci} 458c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(mt76_mcu_get_response); 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_civoid mt76_mcu_rx_event(struct mt76_dev *dev, struct sk_buff *skb) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci skb_queue_tail(&dev->mcu.res_q, skb); 508c2ecf20Sopenharmony_ci wake_up(&dev->mcu.wait); 518c2ecf20Sopenharmony_ci} 528c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(mt76_mcu_rx_event); 53