0001
0002
0003
0004
0005
0006 #include "mt76.h"
0007
0008 struct sk_buff *
0009 __mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data,
0010 int len, int data_len, gfp_t gfp)
0011 {
0012 const struct mt76_mcu_ops *ops = dev->mcu_ops;
0013 struct sk_buff *skb;
0014
0015 len = max_t(int, len, data_len);
0016 len = ops->headroom + len + ops->tailroom;
0017
0018 skb = alloc_skb(len, gfp);
0019 if (!skb)
0020 return NULL;
0021
0022 memset(skb->head, 0, len);
0023 skb_reserve(skb, ops->headroom);
0024
0025 if (data && data_len)
0026 skb_put_data(skb, data, data_len);
0027
0028 return skb;
0029 }
0030 EXPORT_SYMBOL_GPL(__mt76_mcu_msg_alloc);
0031
0032 struct sk_buff *mt76_mcu_get_response(struct mt76_dev *dev,
0033 unsigned long expires)
0034 {
0035 unsigned long timeout;
0036
0037 if (!time_is_after_jiffies(expires))
0038 return NULL;
0039
0040 timeout = expires - jiffies;
0041 wait_event_timeout(dev->mcu.wait,
0042 (!skb_queue_empty(&dev->mcu.res_q) ||
0043 test_bit(MT76_MCU_RESET, &dev->phy.state)),
0044 timeout);
0045 return skb_dequeue(&dev->mcu.res_q);
0046 }
0047 EXPORT_SYMBOL_GPL(mt76_mcu_get_response);
0048
0049 void mt76_mcu_rx_event(struct mt76_dev *dev, struct sk_buff *skb)
0050 {
0051 skb_queue_tail(&dev->mcu.res_q, skb);
0052 wake_up(&dev->mcu.wait);
0053 }
0054 EXPORT_SYMBOL_GPL(mt76_mcu_rx_event);
0055
0056 int mt76_mcu_send_and_get_msg(struct mt76_dev *dev, int cmd, const void *data,
0057 int len, bool wait_resp, struct sk_buff **ret_skb)
0058 {
0059 struct sk_buff *skb;
0060
0061 if (dev->mcu_ops->mcu_send_msg)
0062 return dev->mcu_ops->mcu_send_msg(dev, cmd, data, len, wait_resp);
0063
0064 skb = mt76_mcu_msg_alloc(dev, data, len);
0065 if (!skb)
0066 return -ENOMEM;
0067
0068 return mt76_mcu_skb_send_and_get_msg(dev, skb, cmd, wait_resp, ret_skb);
0069 }
0070 EXPORT_SYMBOL_GPL(mt76_mcu_send_and_get_msg);
0071
0072 int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb,
0073 int cmd, bool wait_resp,
0074 struct sk_buff **ret_skb)
0075 {
0076 unsigned long expires;
0077 int ret, seq;
0078
0079 if (ret_skb)
0080 *ret_skb = NULL;
0081
0082 mutex_lock(&dev->mcu.mutex);
0083
0084 ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb, cmd, &seq);
0085 if (ret < 0)
0086 goto out;
0087
0088 if (!wait_resp) {
0089 ret = 0;
0090 goto out;
0091 }
0092
0093 expires = jiffies + dev->mcu.timeout;
0094
0095 do {
0096 skb = mt76_mcu_get_response(dev, expires);
0097 ret = dev->mcu_ops->mcu_parse_response(dev, cmd, skb, seq);
0098 if (!ret && ret_skb)
0099 *ret_skb = skb;
0100 else
0101 dev_kfree_skb(skb);
0102 } while (ret == -EAGAIN);
0103
0104 out:
0105 mutex_unlock(&dev->mcu.mutex);
0106
0107 return ret;
0108 }
0109 EXPORT_SYMBOL_GPL(mt76_mcu_skb_send_and_get_msg);
0110
0111 int __mt76_mcu_send_firmware(struct mt76_dev *dev, int cmd, const void *data,
0112 int len, int max_len)
0113 {
0114 int err, cur_len;
0115
0116 while (len > 0) {
0117 cur_len = min_t(int, max_len, len);
0118
0119 err = mt76_mcu_send_msg(dev, cmd, data, cur_len, false);
0120 if (err)
0121 return err;
0122
0123 data += cur_len;
0124 len -= cur_len;
0125
0126 if (dev->queue_ops->tx_cleanup)
0127 dev->queue_ops->tx_cleanup(dev,
0128 dev->q_mcu[MT_MCUQ_FWDL],
0129 false);
0130 }
0131
0132 return 0;
0133 }
0134 EXPORT_SYMBOL_GPL(__mt76_mcu_send_firmware);