1 // SPDX-License-Identifier: ISC
3 * Copyright (C) 2019 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
9 __mt76_mcu_msg_alloc(struct mt76_dev
*dev
, const void *data
,
10 int len
, int data_len
, gfp_t gfp
)
12 const struct mt76_mcu_ops
*ops
= dev
->mcu_ops
;
15 len
= max_t(int, len
, data_len
);
16 len
= ops
->headroom
+ len
+ ops
->tailroom
;
18 skb
= alloc_skb(len
, gfp
);
22 memset(skb
->head
, 0, len
);
23 skb_reserve(skb
, ops
->headroom
);
26 skb_put_data(skb
, data
, data_len
);
30 EXPORT_SYMBOL_GPL(__mt76_mcu_msg_alloc
);
32 struct sk_buff
*mt76_mcu_get_response(struct mt76_dev
*dev
,
33 unsigned long expires
)
35 unsigned long timeout
;
37 if (!time_is_after_jiffies(expires
))
40 timeout
= expires
- jiffies
;
41 wait_event_timeout(dev
->mcu
.wait
,
42 (!skb_queue_empty(&dev
->mcu
.res_q
) ||
43 test_bit(MT76_MCU_RESET
, &dev
->phy
.state
)),
45 return skb_dequeue(&dev
->mcu
.res_q
);
47 EXPORT_SYMBOL_GPL(mt76_mcu_get_response
);
49 void mt76_mcu_rx_event(struct mt76_dev
*dev
, struct sk_buff
*skb
)
51 skb_queue_tail(&dev
->mcu
.res_q
, skb
);
52 wake_up(&dev
->mcu
.wait
);
54 EXPORT_SYMBOL_GPL(mt76_mcu_rx_event
);
56 int mt76_mcu_send_and_get_msg(struct mt76_dev
*dev
, int cmd
, const void *data
,
57 int len
, bool wait_resp
, struct sk_buff
**ret_skb
)
61 if (dev
->mcu_ops
->mcu_send_msg
)
62 return dev
->mcu_ops
->mcu_send_msg(dev
, cmd
, data
, len
, wait_resp
);
64 skb
= mt76_mcu_msg_alloc(dev
, data
, len
);
68 return mt76_mcu_skb_send_and_get_msg(dev
, skb
, cmd
, wait_resp
, ret_skb
);
70 EXPORT_SYMBOL_GPL(mt76_mcu_send_and_get_msg
);
72 int mt76_mcu_skb_send_and_get_msg(struct mt76_dev
*dev
, struct sk_buff
*skb
,
73 int cmd
, bool wait_resp
,
74 struct sk_buff
**ret_skb
)
76 unsigned int retry
= 0;
77 struct sk_buff
*orig_skb
= NULL
;
78 unsigned long expires
;
84 mutex_lock(&dev
->mcu
.mutex
);
86 if (dev
->mcu_ops
->mcu_skb_prepare_msg
) {
88 ret
= dev
->mcu_ops
->mcu_skb_prepare_msg(dev
, skb
, cmd
, &seq
);
94 /* orig skb might be needed for retry, mcu_skb_send_msg consumes it */
97 ret
= dev
->mcu_ops
->mcu_skb_send_msg(dev
, skb
, cmd
, &seq
);
106 expires
= jiffies
+ dev
->mcu
.timeout
;
109 skb
= mt76_mcu_get_response(dev
, expires
);
110 if (!skb
&& !test_bit(MT76_MCU_RESET
, &dev
->phy
.state
) &&
111 orig_skb
&& retry
++ < dev
->mcu_ops
->max_retry
) {
112 dev_err(dev
->dev
, "Retry message %08x (seq %d)\n",
118 ret
= dev
->mcu_ops
->mcu_parse_response(dev
, cmd
, skb
, seq
);
123 } while (ret
== -EAGAIN
);
127 dev_kfree_skb(orig_skb
);
128 mutex_unlock(&dev
->mcu
.mutex
);
132 EXPORT_SYMBOL_GPL(mt76_mcu_skb_send_and_get_msg
);
134 int __mt76_mcu_send_firmware(struct mt76_dev
*dev
, int cmd
, const void *data
,
135 int len
, int max_len
)
140 cur_len
= min_t(int, max_len
, len
);
142 err
= mt76_mcu_send_msg(dev
, cmd
, data
, cur_len
, false);
149 if (dev
->queue_ops
->tx_cleanup
)
150 dev
->queue_ops
->tx_cleanup(dev
,
151 dev
->q_mcu
[MT_MCUQ_FWDL
],
157 EXPORT_SYMBOL_GPL(__mt76_mcu_send_firmware
);