1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2021, MediaTek Inc.
4 * Copyright (c) 2021-2022, Intel Corporation.
20 #include <linux/bits.h>
21 #include <linux/bitfield.h>
22 #include <linux/device.h>
23 #include <linux/gfp.h>
24 #include <linux/kernel.h>
25 #include <linux/kthread.h>
26 #include <linux/list.h>
27 #include <linux/mutex.h>
28 #include <linux/netdevice.h>
29 #include <linux/skbuff.h>
30 #include <linux/spinlock.h>
31 #include <linux/wait.h>
32 #include <linux/wwan.h>
34 #include "t7xx_hif_cldma.h"
35 #include "t7xx_modem_ops.h"
36 #include "t7xx_port.h"
37 #include "t7xx_port_proxy.h"
38 #include "t7xx_state_monitor.h"
42 #define Q_IDX_AT_CMD 5
44 #define INVALID_SEQ_NUM GENMASK(15, 0)
46 #define for_each_proxy_port(i, p, proxy) \
47 for (i = 0, (p) = &(proxy)->ports[i]; \
48 i < (proxy)->port_count; \
49 i++, (p) = &(proxy)->ports[i])
51 static const struct t7xx_port_conf t7xx_md_port_conf[] = {
53 .tx_ch = PORT_CH_UART2_TX,
54 .rx_ch = PORT_CH_UART2_RX,
55 .txq_index = Q_IDX_AT_CMD,
56 .rxq_index = Q_IDX_AT_CMD,
57 .txq_exp_index = 0xff,
58 .rxq_exp_index = 0xff,
59 .path_id = CLDMA_ID_MD,
60 .ops = &wwan_sub_port_ops,
62 .port_type = WWAN_PORT_AT,
64 .tx_ch = PORT_CH_MBIM_TX,
65 .rx_ch = PORT_CH_MBIM_RX,
66 .txq_index = Q_IDX_MBIM,
67 .rxq_index = Q_IDX_MBIM,
68 .path_id = CLDMA_ID_MD,
69 .ops = &wwan_sub_port_ops,
71 .port_type = WWAN_PORT_MBIM,
73 #ifdef CONFIG_WWAN_DEBUGFS
74 .tx_ch = PORT_CH_MD_LOG_TX,
75 .rx_ch = PORT_CH_MD_LOG_RX,
80 .path_id = CLDMA_ID_MD,
81 .ops = &t7xx_trace_port_ops,
85 .tx_ch = PORT_CH_CONTROL_TX,
86 .rx_ch = PORT_CH_CONTROL_RX,
87 .txq_index = Q_IDX_CTRL,
88 .rxq_index = Q_IDX_CTRL,
89 .path_id = CLDMA_ID_MD,
95 static struct t7xx_port *t7xx_proxy_get_port_by_ch(struct port_proxy *port_prox, enum port_ch ch)
97 const struct t7xx_port_conf *port_conf;
98 struct t7xx_port *port;
101 for_each_proxy_port(i, port, port_prox) {
102 port_conf = port->port_conf;
103 if (port_conf->rx_ch == ch || port_conf->tx_ch == ch)
110 static u16 t7xx_port_next_rx_seq_num(struct t7xx_port *port, struct ccci_header *ccci_h)
112 u32 status = le32_to_cpu(ccci_h->status);
113 u16 seq_num, next_seq_num;
116 seq_num = FIELD_GET(CCCI_H_SEQ_FLD, status);
117 next_seq_num = (seq_num + 1) & FIELD_MAX(CCCI_H_SEQ_FLD);
118 assert_bit = status & CCCI_H_AST_BIT;
119 if (!assert_bit || port->seq_nums[MTK_RX] == INVALID_SEQ_NUM)
122 if (seq_num != port->seq_nums[MTK_RX])
123 dev_warn_ratelimited(port->dev,
124 "seq num out-of-order %u != %u (header %X, len %X)\n",
125 seq_num, port->seq_nums[MTK_RX],
126 le32_to_cpu(ccci_h->packet_header),
127 le32_to_cpu(ccci_h->packet_len));
132 void t7xx_port_proxy_reset(struct port_proxy *port_prox)
134 struct t7xx_port *port;
137 for_each_proxy_port(i, port, port_prox) {
138 port->seq_nums[MTK_RX] = INVALID_SEQ_NUM;
139 port->seq_nums[MTK_TX] = 0;
143 static int t7xx_port_get_queue_no(struct t7xx_port *port)
145 const struct t7xx_port_conf *port_conf = port->port_conf;
146 struct t7xx_fsm_ctl *ctl = port->t7xx_dev->md->fsm_ctl;
148 return t7xx_fsm_get_md_state(ctl) == MD_STATE_EXCEPTION ?
149 port_conf->txq_exp_index : port_conf->txq_index;
152 static void t7xx_port_struct_init(struct t7xx_port *port)
154 INIT_LIST_HEAD(&port->entry);
155 INIT_LIST_HEAD(&port->queue_entry);
156 skb_queue_head_init(&port->rx_skb_list);
157 init_waitqueue_head(&port->rx_wq);
158 port->seq_nums[MTK_RX] = INVALID_SEQ_NUM;
159 port->seq_nums[MTK_TX] = 0;
160 atomic_set(&port->usage_cnt, 0);
163 struct sk_buff *t7xx_port_alloc_skb(int payload)
165 struct sk_buff *skb = __dev_alloc_skb(payload + sizeof(struct ccci_header), GFP_KERNEL);
168 skb_reserve(skb, sizeof(struct ccci_header));
173 struct sk_buff *t7xx_ctrl_alloc_skb(int payload)
175 struct sk_buff *skb = t7xx_port_alloc_skb(payload + sizeof(struct ctrl_msg_header));
178 skb_reserve(skb, sizeof(struct ctrl_msg_header));
184 * t7xx_port_enqueue_skb() - Enqueue the received skb into the port's rx_skb_list.
185 * @port: port context.
186 * @skb: received skb.
190 * * -ENOBUFS - Not enough buffer space. Caller will try again later, skb is not consumed.
192 int t7xx_port_enqueue_skb(struct t7xx_port *port, struct sk_buff *skb)
196 spin_lock_irqsave(&port->rx_wq.lock, flags);
197 if (port->rx_skb_list.qlen >= port->rx_length_th) {
198 spin_unlock_irqrestore(&port->rx_wq.lock, flags);
202 __skb_queue_tail(&port->rx_skb_list, skb);
203 spin_unlock_irqrestore(&port->rx_wq.lock, flags);
205 wake_up_all(&port->rx_wq);
209 static int t7xx_port_send_raw_skb(struct t7xx_port *port, struct sk_buff *skb)
211 enum cldma_id path_id = port->port_conf->path_id;
212 struct cldma_ctrl *md_ctrl;
215 md_ctrl = port->t7xx_dev->md->md_ctrl[path_id];
216 tx_qno = t7xx_port_get_queue_no(port);
217 ret = t7xx_cldma_send_skb(md_ctrl, tx_qno, skb);
219 dev_err(port->dev, "Failed to send skb: %d\n", ret);
224 static int t7xx_port_send_ccci_skb(struct t7xx_port *port, struct sk_buff *skb,
225 unsigned int pkt_header, unsigned int ex_msg)
227 const struct t7xx_port_conf *port_conf = port->port_conf;
228 struct ccci_header *ccci_h;
232 ccci_h = skb_push(skb, sizeof(*ccci_h));
233 status = FIELD_PREP(CCCI_H_CHN_FLD, port_conf->tx_ch) |
234 FIELD_PREP(CCCI_H_SEQ_FLD, port->seq_nums[MTK_TX]) | CCCI_H_AST_BIT;
235 ccci_h->status = cpu_to_le32(status);
236 ccci_h->packet_header = cpu_to_le32(pkt_header);
237 ccci_h->packet_len = cpu_to_le32(skb->len);
238 ccci_h->ex_msg = cpu_to_le32(ex_msg);
240 ret = t7xx_port_send_raw_skb(port, skb);
244 port->seq_nums[MTK_TX]++;
248 int t7xx_port_send_ctl_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int msg,
251 struct ctrl_msg_header *ctrl_msg_h;
252 unsigned int msg_len = skb->len;
255 ctrl_msg_h = skb_push(skb, sizeof(*ctrl_msg_h));
256 ctrl_msg_h->ctrl_msg_id = cpu_to_le32(msg);
257 ctrl_msg_h->ex_msg = cpu_to_le32(ex_msg);
258 ctrl_msg_h->data_length = cpu_to_le32(msg_len);
261 pkt_header = CCCI_HEADER_NO_DATA;
263 return t7xx_port_send_ccci_skb(port, skb, pkt_header, ex_msg);
266 int t7xx_port_send_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int pkt_header,
269 struct t7xx_fsm_ctl *ctl = port->t7xx_dev->md->fsm_ctl;
270 unsigned int fsm_state;
272 fsm_state = t7xx_fsm_get_ctl_state(ctl);
273 if (fsm_state != FSM_STATE_PRE_START) {
274 const struct t7xx_port_conf *port_conf = port->port_conf;
275 enum md_state md_state = t7xx_fsm_get_md_state(ctl);
278 case MD_STATE_EXCEPTION:
279 if (port_conf->tx_ch != PORT_CH_MD_LOG_TX)
283 case MD_STATE_WAITING_FOR_HS1:
284 case MD_STATE_WAITING_FOR_HS2:
285 case MD_STATE_STOPPED:
286 case MD_STATE_WAITING_TO_STOP:
287 case MD_STATE_INVALID:
295 return t7xx_port_send_ccci_skb(port, skb, pkt_header, ex_msg);
298 static void t7xx_proxy_setup_ch_mapping(struct port_proxy *port_prox)
300 struct t7xx_port *port;
304 for (i = 0; i < ARRAY_SIZE(port_prox->rx_ch_ports); i++)
305 INIT_LIST_HEAD(&port_prox->rx_ch_ports[i]);
307 for (j = 0; j < ARRAY_SIZE(port_prox->queue_ports); j++) {
308 for (i = 0; i < ARRAY_SIZE(port_prox->queue_ports[j]); i++)
309 INIT_LIST_HEAD(&port_prox->queue_ports[j][i]);
312 for_each_proxy_port(i, port, port_prox) {
313 const struct t7xx_port_conf *port_conf = port->port_conf;
314 enum cldma_id path_id = port_conf->path_id;
317 ch_id = FIELD_GET(PORT_CH_ID_MASK, port_conf->rx_ch);
318 list_add_tail(&port->entry, &port_prox->rx_ch_ports[ch_id]);
319 list_add_tail(&port->queue_entry,
320 &port_prox->queue_ports[path_id][port_conf->rxq_index]);
324 static struct t7xx_port *t7xx_port_proxy_find_port(struct t7xx_pci_dev *t7xx_dev,
325 struct cldma_queue *queue, u16 channel)
327 struct port_proxy *port_prox = t7xx_dev->md->port_prox;
328 struct list_head *port_list;
329 struct t7xx_port *port;
332 ch_id = FIELD_GET(PORT_CH_ID_MASK, channel);
333 port_list = &port_prox->rx_ch_ports[ch_id];
334 list_for_each_entry(port, port_list, entry) {
335 const struct t7xx_port_conf *port_conf = port->port_conf;
337 if (queue->md_ctrl->hif_id == port_conf->path_id &&
338 channel == port_conf->rx_ch)
346 * t7xx_port_proxy_recv_skb() - Dispatch received skb.
347 * @queue: CLDMA queue.
348 * @skb: Socket buffer.
351 ** 0 - Packet consumed.
352 ** -ERROR - Failed to process skb.
354 static int t7xx_port_proxy_recv_skb(struct cldma_queue *queue, struct sk_buff *skb)
356 struct ccci_header *ccci_h = (struct ccci_header *)skb->data;
357 struct t7xx_pci_dev *t7xx_dev = queue->md_ctrl->t7xx_dev;
358 struct t7xx_fsm_ctl *ctl = t7xx_dev->md->fsm_ctl;
359 struct device *dev = queue->md_ctrl->dev;
360 const struct t7xx_port_conf *port_conf;
361 struct t7xx_port *port;
362 u16 seq_num, channel;
365 channel = FIELD_GET(CCCI_H_CHN_FLD, le32_to_cpu(ccci_h->status));
366 if (t7xx_fsm_get_md_state(ctl) == MD_STATE_INVALID) {
367 dev_err_ratelimited(dev, "Packet drop on channel 0x%x, modem not ready\n", channel);
371 port = t7xx_port_proxy_find_port(t7xx_dev, queue, channel);
373 dev_err_ratelimited(dev, "Packet drop on channel 0x%x, port not found\n", channel);
377 seq_num = t7xx_port_next_rx_seq_num(port, ccci_h);
378 port_conf = port->port_conf;
379 skb_pull(skb, sizeof(*ccci_h));
381 ret = port_conf->ops->recv_skb(port, skb);
382 /* Error indicates to try again later */
384 skb_push(skb, sizeof(*ccci_h));
388 port->seq_nums[MTK_RX] = seq_num;
392 dev_kfree_skb_any(skb);
397 * t7xx_port_proxy_md_status_notify() - Notify all ports of state.
398 *@port_prox: The port_proxy pointer.
401 * Called by t7xx_fsm. Used to dispatch modem status for all ports,
402 * which want to know MD state transition.
404 void t7xx_port_proxy_md_status_notify(struct port_proxy *port_prox, unsigned int state)
406 struct t7xx_port *port;
409 for_each_proxy_port(i, port, port_prox) {
410 const struct t7xx_port_conf *port_conf = port->port_conf;
412 if (port_conf->ops->md_state_notify)
413 port_conf->ops->md_state_notify(port, state);
417 static void t7xx_proxy_init_all_ports(struct t7xx_modem *md)
419 struct port_proxy *port_prox = md->port_prox;
420 struct t7xx_port *port;
423 for_each_proxy_port(i, port, port_prox) {
424 const struct t7xx_port_conf *port_conf = port->port_conf;
426 t7xx_port_struct_init(port);
428 if (port_conf->tx_ch == PORT_CH_CONTROL_TX)
429 md->core_md.ctl_port = port;
431 port->t7xx_dev = md->t7xx_dev;
432 port->dev = &md->t7xx_dev->pdev->dev;
433 spin_lock_init(&port->port_update_lock);
434 port->chan_enable = false;
436 if (port_conf->ops->init)
437 port_conf->ops->init(port);
440 t7xx_proxy_setup_ch_mapping(port_prox);
443 static int t7xx_proxy_alloc(struct t7xx_modem *md)
445 unsigned int port_count = ARRAY_SIZE(t7xx_md_port_conf);
446 struct device *dev = &md->t7xx_dev->pdev->dev;
447 struct port_proxy *port_prox;
450 port_prox = devm_kzalloc(dev, sizeof(*port_prox) + sizeof(struct t7xx_port) * port_count,
455 md->port_prox = port_prox;
456 port_prox->dev = dev;
458 for (i = 0; i < port_count; i++)
459 port_prox->ports[i].port_conf = &t7xx_md_port_conf[i];
461 port_prox->port_count = port_count;
462 t7xx_proxy_init_all_ports(md);
467 * t7xx_port_proxy_init() - Initialize ports.
470 * Create all port instances.
474 * * -ERROR - Error code from failure sub-initializations.
476 int t7xx_port_proxy_init(struct t7xx_modem *md)
480 ret = t7xx_proxy_alloc(md);
484 t7xx_cldma_set_recv_skb(md->md_ctrl[CLDMA_ID_MD], t7xx_port_proxy_recv_skb);
488 void t7xx_port_proxy_uninit(struct port_proxy *port_prox)
490 struct t7xx_port *port;
493 for_each_proxy_port(i, port, port_prox) {
494 const struct t7xx_port_conf *port_conf = port->port_conf;
496 if (port_conf->ops->uninit)
497 port_conf->ops->uninit(port);
501 int t7xx_port_proxy_chl_enable_disable(struct port_proxy *port_prox, unsigned int ch_id,
504 struct t7xx_port *port = t7xx_proxy_get_port_by_ch(port_prox, ch_id);
505 const struct t7xx_port_conf *port_conf;
510 port_conf = port->port_conf;
513 if (port_conf->ops->enable_chl)
514 port_conf->ops->enable_chl(port);
516 if (port_conf->ops->disable_chl)
517 port_conf->ops->disable_chl(port);