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"
41 #define Q_IDX_MBIM_MIPC 2
43 #define Q_IDX_AT_CMD 5
45 #define INVALID_SEQ_NUM GENMASK(15, 0)
47 #define for_each_proxy_port(i, p, proxy) \
48 for (i = 0, (p) = &(proxy)->ports[i]; \
49 i < (proxy)->port_count; \
50 i++, (p) = &(proxy)->ports[i])
52 #define T7XX_MAX_POSSIBLE_PORTS_NUM \
53 (max(ARRAY_SIZE(t7xx_port_conf), ARRAY_SIZE(t7xx_early_port_conf)))
55 static const struct t7xx_port_conf t7xx_port_conf[] = {
57 .tx_ch = PORT_CH_UART2_TX,
58 .rx_ch = PORT_CH_UART2_RX,
59 .txq_index = Q_IDX_AT_CMD,
60 .rxq_index = Q_IDX_AT_CMD,
61 .txq_exp_index = 0xff,
62 .rxq_exp_index = 0xff,
63 .path_id = CLDMA_ID_MD,
64 .ops = &wwan_sub_port_ops,
66 .port_type = WWAN_PORT_AT,
68 .tx_ch = PORT_CH_MBIM_TX,
69 .rx_ch = PORT_CH_MBIM_RX,
70 .txq_index = Q_IDX_MBIM_MIPC,
71 .rxq_index = Q_IDX_MBIM_MIPC,
72 .path_id = CLDMA_ID_MD,
73 .ops = &wwan_sub_port_ops,
75 .port_type = WWAN_PORT_MBIM,
77 #ifdef CONFIG_WWAN_DEBUGFS
78 .tx_ch = PORT_CH_MD_LOG_TX,
79 .rx_ch = PORT_CH_MD_LOG_RX,
84 .path_id = CLDMA_ID_MD,
85 .ops = &t7xx_trace_port_ops,
89 .tx_ch = PORT_CH_CONTROL_TX,
90 .rx_ch = PORT_CH_CONTROL_RX,
91 .txq_index = Q_IDX_CTRL,
92 .rxq_index = Q_IDX_CTRL,
93 .path_id = CLDMA_ID_MD,
97 .tx_ch = PORT_CH_AP_CONTROL_TX,
98 .rx_ch = PORT_CH_AP_CONTROL_RX,
99 .txq_index = Q_IDX_CTRL,
100 .rxq_index = Q_IDX_CTRL,
101 .path_id = CLDMA_ID_AP,
102 .ops = &ctl_port_ops,
103 .name = "t7xx_ap_ctrl",
105 .tx_ch = PORT_CH_AP_ADB_TX,
106 .rx_ch = PORT_CH_AP_ADB_RX,
107 .txq_index = Q_IDX_ADB,
108 .rxq_index = Q_IDX_ADB,
109 .path_id = CLDMA_ID_AP,
110 .ops = &wwan_sub_port_ops,
112 .port_type = WWAN_PORT_ADB,
115 .tx_ch = PORT_CH_MIPC_TX,
116 .rx_ch = PORT_CH_MIPC_RX,
117 .txq_index = Q_IDX_MBIM_MIPC,
118 .rxq_index = Q_IDX_MBIM_MIPC,
119 .path_id = CLDMA_ID_MD,
120 .ops = &wwan_sub_port_ops,
122 .port_type = WWAN_PORT_MIPC,
127 static const struct t7xx_port_conf t7xx_early_port_conf[] = {
129 .tx_ch = PORT_CH_UNIMPORTANT,
130 .rx_ch = PORT_CH_UNIMPORTANT,
131 .txq_index = CLDMA_Q_IDX_DUMP,
132 .rxq_index = CLDMA_Q_IDX_DUMP,
133 .txq_exp_index = CLDMA_Q_IDX_DUMP,
134 .rxq_exp_index = CLDMA_Q_IDX_DUMP,
135 .path_id = CLDMA_ID_AP,
136 .ops = &wwan_sub_port_ops,
138 .port_type = WWAN_PORT_FASTBOOT,
142 static struct t7xx_port *t7xx_proxy_get_port_by_ch(struct port_proxy *port_prox, enum port_ch ch)
144 const struct t7xx_port_conf *port_conf;
145 struct t7xx_port *port;
148 for_each_proxy_port(i, port, port_prox) {
149 port_conf = port->port_conf;
150 if (port_conf->rx_ch == ch || port_conf->tx_ch == ch)
157 static u16 t7xx_port_next_rx_seq_num(struct t7xx_port *port, struct ccci_header *ccci_h)
159 u32 status = le32_to_cpu(ccci_h->status);
160 u16 seq_num, next_seq_num;
163 seq_num = FIELD_GET(CCCI_H_SEQ_FLD, status);
164 next_seq_num = (seq_num + 1) & FIELD_MAX(CCCI_H_SEQ_FLD);
165 assert_bit = status & CCCI_H_AST_BIT;
166 if (!assert_bit || port->seq_nums[MTK_RX] == INVALID_SEQ_NUM)
169 if (seq_num != port->seq_nums[MTK_RX])
170 dev_warn_ratelimited(port->dev,
171 "seq num out-of-order %u != %u (header %X, len %X)\n",
172 seq_num, port->seq_nums[MTK_RX],
173 le32_to_cpu(ccci_h->packet_header),
174 le32_to_cpu(ccci_h->packet_len));
179 void t7xx_port_proxy_reset(struct port_proxy *port_prox)
181 struct t7xx_port *port;
184 for_each_proxy_port(i, port, port_prox) {
185 port->seq_nums[MTK_RX] = INVALID_SEQ_NUM;
186 port->seq_nums[MTK_TX] = 0;
190 static int t7xx_port_get_queue_no(struct t7xx_port *port)
192 const struct t7xx_port_conf *port_conf = port->port_conf;
193 struct t7xx_fsm_ctl *ctl = port->t7xx_dev->md->fsm_ctl;
195 return t7xx_fsm_get_md_state(ctl) == MD_STATE_EXCEPTION ?
196 port_conf->txq_exp_index : port_conf->txq_index;
199 static void t7xx_port_struct_init(struct t7xx_port *port)
201 INIT_LIST_HEAD(&port->entry);
202 INIT_LIST_HEAD(&port->queue_entry);
203 skb_queue_head_init(&port->rx_skb_list);
204 init_waitqueue_head(&port->rx_wq);
205 port->seq_nums[MTK_RX] = INVALID_SEQ_NUM;
206 port->seq_nums[MTK_TX] = 0;
207 atomic_set(&port->usage_cnt, 0);
210 struct sk_buff *t7xx_port_alloc_skb(int payload)
212 struct sk_buff *skb = __dev_alloc_skb(payload + sizeof(struct ccci_header), GFP_KERNEL);
215 skb_reserve(skb, sizeof(struct ccci_header));
220 struct sk_buff *t7xx_ctrl_alloc_skb(int payload)
222 struct sk_buff *skb = t7xx_port_alloc_skb(payload + sizeof(struct ctrl_msg_header));
225 skb_reserve(skb, sizeof(struct ctrl_msg_header));
231 * t7xx_port_enqueue_skb() - Enqueue the received skb into the port's rx_skb_list.
232 * @port: port context.
233 * @skb: received skb.
237 * * -ENOBUFS - Not enough buffer space. Caller will try again later, skb is not consumed.
239 int t7xx_port_enqueue_skb(struct t7xx_port *port, struct sk_buff *skb)
243 spin_lock_irqsave(&port->rx_wq.lock, flags);
244 if (port->rx_skb_list.qlen >= port->rx_length_th) {
245 spin_unlock_irqrestore(&port->rx_wq.lock, flags);
249 __skb_queue_tail(&port->rx_skb_list, skb);
250 spin_unlock_irqrestore(&port->rx_wq.lock, flags);
252 wake_up_all(&port->rx_wq);
256 int t7xx_get_port_mtu(struct t7xx_port *port)
258 enum cldma_id path_id = port->port_conf->path_id;
259 int tx_qno = t7xx_port_get_queue_no(port);
260 struct cldma_ctrl *md_ctrl;
262 md_ctrl = port->t7xx_dev->md->md_ctrl[path_id];
263 return md_ctrl->tx_ring[tx_qno].pkt_size;
266 int t7xx_port_send_raw_skb(struct t7xx_port *port, struct sk_buff *skb)
268 enum cldma_id path_id = port->port_conf->path_id;
269 struct cldma_ctrl *md_ctrl;
272 md_ctrl = port->t7xx_dev->md->md_ctrl[path_id];
273 tx_qno = t7xx_port_get_queue_no(port);
274 ret = t7xx_cldma_send_skb(md_ctrl, tx_qno, skb);
276 dev_err(port->dev, "Failed to send skb: %d\n", ret);
281 static int t7xx_port_send_ccci_skb(struct t7xx_port *port, struct sk_buff *skb,
282 unsigned int pkt_header, unsigned int ex_msg)
284 const struct t7xx_port_conf *port_conf = port->port_conf;
285 struct ccci_header *ccci_h;
289 ccci_h = skb_push(skb, sizeof(*ccci_h));
290 status = FIELD_PREP(CCCI_H_CHN_FLD, port_conf->tx_ch) |
291 FIELD_PREP(CCCI_H_SEQ_FLD, port->seq_nums[MTK_TX]) | CCCI_H_AST_BIT;
292 ccci_h->status = cpu_to_le32(status);
293 ccci_h->packet_header = cpu_to_le32(pkt_header);
294 ccci_h->packet_len = cpu_to_le32(skb->len);
295 ccci_h->ex_msg = cpu_to_le32(ex_msg);
297 ret = t7xx_port_send_raw_skb(port, skb);
301 port->seq_nums[MTK_TX]++;
305 int t7xx_port_send_ctl_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int msg,
308 struct ctrl_msg_header *ctrl_msg_h;
309 unsigned int msg_len = skb->len;
312 ctrl_msg_h = skb_push(skb, sizeof(*ctrl_msg_h));
313 ctrl_msg_h->ctrl_msg_id = cpu_to_le32(msg);
314 ctrl_msg_h->ex_msg = cpu_to_le32(ex_msg);
315 ctrl_msg_h->data_length = cpu_to_le32(msg_len);
318 pkt_header = CCCI_HEADER_NO_DATA;
320 return t7xx_port_send_ccci_skb(port, skb, pkt_header, ex_msg);
323 int t7xx_port_send_skb(struct t7xx_port *port, struct sk_buff *skb, unsigned int pkt_header,
326 struct t7xx_fsm_ctl *ctl = port->t7xx_dev->md->fsm_ctl;
327 unsigned int fsm_state;
329 fsm_state = t7xx_fsm_get_ctl_state(ctl);
330 if (fsm_state != FSM_STATE_PRE_START) {
331 const struct t7xx_port_conf *port_conf = port->port_conf;
332 enum md_state md_state = t7xx_fsm_get_md_state(ctl);
335 case MD_STATE_EXCEPTION:
336 if (port_conf->tx_ch != PORT_CH_MD_LOG_TX)
340 case MD_STATE_WAITING_FOR_HS1:
341 case MD_STATE_WAITING_FOR_HS2:
342 case MD_STATE_STOPPED:
343 case MD_STATE_WAITING_TO_STOP:
344 case MD_STATE_INVALID:
352 return t7xx_port_send_ccci_skb(port, skb, pkt_header, ex_msg);
355 static void t7xx_proxy_setup_ch_mapping(struct port_proxy *port_prox)
357 struct t7xx_port *port;
361 for (i = 0; i < ARRAY_SIZE(port_prox->rx_ch_ports); i++)
362 INIT_LIST_HEAD(&port_prox->rx_ch_ports[i]);
364 for (j = 0; j < ARRAY_SIZE(port_prox->queue_ports); j++) {
365 for (i = 0; i < ARRAY_SIZE(port_prox->queue_ports[j]); i++)
366 INIT_LIST_HEAD(&port_prox->queue_ports[j][i]);
369 for_each_proxy_port(i, port, port_prox) {
370 const struct t7xx_port_conf *port_conf = port->port_conf;
371 enum cldma_id path_id = port_conf->path_id;
374 ch_id = FIELD_GET(PORT_CH_ID_MASK, port_conf->rx_ch);
375 list_add_tail(&port->entry, &port_prox->rx_ch_ports[ch_id]);
376 list_add_tail(&port->queue_entry,
377 &port_prox->queue_ports[path_id][port_conf->rxq_index]);
382 * t7xx_port_proxy_recv_skb_from_dedicated_queue() - Dispatch early port received skb.
383 * @queue: CLDMA queue.
384 * @skb: Socket buffer.
387 ** 0 - Packet consumed.
388 ** -ERROR - Failed to process skb.
390 int t7xx_port_proxy_recv_skb_from_dedicated_queue(struct cldma_queue *queue, struct sk_buff *skb)
392 struct t7xx_pci_dev *t7xx_dev = queue->md_ctrl->t7xx_dev;
393 struct port_proxy *port_prox = t7xx_dev->md->port_prox;
394 const struct t7xx_port_conf *port_conf;
395 struct t7xx_port *port;
398 port = &port_prox->ports[0];
399 if (WARN_ON_ONCE(port->port_conf->rxq_index != queue->index)) {
400 dev_kfree_skb_any(skb);
404 port_conf = port->port_conf;
405 ret = port_conf->ops->recv_skb(port, skb);
406 if (ret < 0 && ret != -ENOBUFS) {
407 dev_err(port->dev, "drop on RX ch %d, %d\n", port_conf->rx_ch, ret);
408 dev_kfree_skb_any(skb);
414 static struct t7xx_port *t7xx_port_proxy_find_port(struct t7xx_pci_dev *t7xx_dev,
415 struct cldma_queue *queue, u16 channel)
417 struct port_proxy *port_prox = t7xx_dev->md->port_prox;
418 struct list_head *port_list;
419 struct t7xx_port *port;
422 ch_id = FIELD_GET(PORT_CH_ID_MASK, channel);
423 port_list = &port_prox->rx_ch_ports[ch_id];
424 list_for_each_entry(port, port_list, entry) {
425 const struct t7xx_port_conf *port_conf = port->port_conf;
427 if (queue->md_ctrl->hif_id == port_conf->path_id &&
428 channel == port_conf->rx_ch)
436 * t7xx_port_proxy_recv_skb() - Dispatch received skb.
437 * @queue: CLDMA queue.
438 * @skb: Socket buffer.
441 ** 0 - Packet consumed.
442 ** -ERROR - Failed to process skb.
444 int t7xx_port_proxy_recv_skb(struct cldma_queue *queue, struct sk_buff *skb)
446 struct ccci_header *ccci_h = (struct ccci_header *)skb->data;
447 struct t7xx_pci_dev *t7xx_dev = queue->md_ctrl->t7xx_dev;
448 struct t7xx_fsm_ctl *ctl = t7xx_dev->md->fsm_ctl;
449 struct device *dev = queue->md_ctrl->dev;
450 const struct t7xx_port_conf *port_conf;
451 struct t7xx_port *port;
452 u16 seq_num, channel;
455 channel = FIELD_GET(CCCI_H_CHN_FLD, le32_to_cpu(ccci_h->status));
456 if (t7xx_fsm_get_md_state(ctl) == MD_STATE_INVALID) {
457 dev_err_ratelimited(dev, "Packet drop on channel 0x%x, modem not ready\n", channel);
461 port = t7xx_port_proxy_find_port(t7xx_dev, queue, channel);
463 dev_err_ratelimited(dev, "Packet drop on channel 0x%x, port not found\n", channel);
467 seq_num = t7xx_port_next_rx_seq_num(port, ccci_h);
468 port_conf = port->port_conf;
469 skb_pull(skb, sizeof(*ccci_h));
471 ret = port_conf->ops->recv_skb(port, skb);
472 /* Error indicates to try again later */
474 skb_push(skb, sizeof(*ccci_h));
478 port->seq_nums[MTK_RX] = seq_num;
482 dev_kfree_skb_any(skb);
487 * t7xx_port_proxy_md_status_notify() - Notify all ports of state.
488 *@port_prox: The port_proxy pointer.
491 * Called by t7xx_fsm. Used to dispatch modem status for all ports,
492 * which want to know MD state transition.
494 void t7xx_port_proxy_md_status_notify(struct port_proxy *port_prox, unsigned int state)
496 struct t7xx_port *port;
499 for_each_proxy_port(i, port, port_prox) {
500 const struct t7xx_port_conf *port_conf = port->port_conf;
502 if (port_conf->ops->md_state_notify)
503 port_conf->ops->md_state_notify(port, state);
507 static void t7xx_proxy_init_all_ports(struct t7xx_modem *md)
509 struct port_proxy *port_prox = md->port_prox;
510 struct t7xx_port *port;
513 for_each_proxy_port(i, port, port_prox) {
514 const struct t7xx_port_conf *port_conf = port->port_conf;
516 t7xx_port_struct_init(port);
518 if (port_conf->tx_ch == PORT_CH_CONTROL_TX)
519 md->core_md.ctl_port = port;
521 if (port_conf->tx_ch == PORT_CH_AP_CONTROL_TX)
522 md->core_ap.ctl_port = port;
524 port->t7xx_dev = md->t7xx_dev;
525 port->dev = &md->t7xx_dev->pdev->dev;
526 spin_lock_init(&port->port_update_lock);
527 port->chan_enable = false;
529 if (!port_conf->debug &&
531 port_conf->ops->init)
532 port_conf->ops->init(port);
535 t7xx_proxy_setup_ch_mapping(port_prox);
538 void t7xx_proxy_debug_ports_show(struct t7xx_pci_dev *t7xx_dev, bool show)
540 struct port_proxy *port_prox = t7xx_dev->md->port_prox;
541 struct t7xx_port *port;
544 for_each_proxy_port(i, port, port_prox) {
545 const struct t7xx_port_conf *port_conf = port->port_conf;
547 if (port_conf->debug && port_conf->ops) {
548 if (show && port_conf->ops->init)
549 port_conf->ops->init(port);
550 else if (!show && port_conf->ops->uninit)
551 port_conf->ops->uninit(port);
556 void t7xx_port_proxy_set_cfg(struct t7xx_modem *md, enum port_cfg_id cfg_id)
558 struct port_proxy *port_prox = md->port_prox;
559 const struct t7xx_port_conf *port_conf;
563 t7xx_port_proxy_uninit(port_prox);
565 if (cfg_id == PORT_CFG_ID_EARLY) {
566 port_conf = t7xx_early_port_conf;
567 port_count = ARRAY_SIZE(t7xx_early_port_conf);
569 port_conf = t7xx_port_conf;
570 port_count = ARRAY_SIZE(t7xx_port_conf);
573 for (i = 0; i < port_count; i++)
574 port_prox->ports[i].port_conf = &port_conf[i];
576 port_prox->cfg_id = cfg_id;
577 port_prox->port_count = port_count;
579 t7xx_proxy_init_all_ports(md);
582 static int t7xx_proxy_alloc(struct t7xx_modem *md)
584 struct device *dev = &md->t7xx_dev->pdev->dev;
585 struct port_proxy *port_prox;
587 port_prox = devm_kzalloc(dev,
588 struct_size(port_prox,
590 T7XX_MAX_POSSIBLE_PORTS_NUM),
595 md->port_prox = port_prox;
596 port_prox->dev = dev;
602 * t7xx_port_proxy_init() - Initialize ports.
605 * Create all port instances.
609 * * -ERROR - Error code from failure sub-initializations.
611 int t7xx_port_proxy_init(struct t7xx_modem *md)
615 ret = t7xx_proxy_alloc(md);
622 void t7xx_port_proxy_uninit(struct port_proxy *port_prox)
624 struct t7xx_port *port;
627 for_each_proxy_port(i, port, port_prox) {
628 const struct t7xx_port_conf *port_conf = port->port_conf;
630 if (port_conf->ops && port_conf->ops->uninit)
631 port_conf->ops->uninit(port);
635 int t7xx_port_proxy_chl_enable_disable(struct port_proxy *port_prox, unsigned int ch_id,
638 struct t7xx_port *port = t7xx_proxy_get_port_by_ch(port_prox, ch_id);
639 const struct t7xx_port_conf *port_conf;
644 port_conf = port->port_conf;
647 if (port_conf->ops->enable_chl)
648 port_conf->ops->enable_chl(port);
650 if (port_conf->ops->disable_chl)
651 port_conf->ops->disable_chl(port);