From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
To: Ricardo Martinez <ricardo.martinez@linux.intel.com>
Cc: netdev@vger.kernel.org, linux-wireless@vger.kernel.org,
"Jakub Kicinski" <kuba@kernel.org>,
"David Miller" <davem@davemloft.net>,
"Johannes Berg" <johannes@sipsolutions.net>,
"Loic Poulain" <loic.poulain@linaro.org>,
"M Chetan Kumar" <m.chetan.kumar@intel.com>,
chandrashekar.devegowda@intel.com,
"Intel Corporation" <linuxwwan@intel.com>,
chiranjeevi.rapolu@linux.intel.com,
"Haijun Liu (刘海军)" <haijun.liu@mediatek.com>,
amir.hanania@intel.com,
"Andy Shevchenko" <andriy.shevchenko@linux.intel.com>,
dinesh.sharma@intel.com, eliot.lee@intel.com,
ilpo.johannes.jarvinen@intel.com, moises.veleta@intel.com,
pierre-louis.bossart@intel.com,
muralidharan.sethuraman@intel.com,
Soumya.Prakash.Mishra@intel.com, sreehari.kancharla@intel.com,
madhusmita.sahu@intel.com
Subject: Re: [PATCH net-next v5 05/13] net: wwan: t7xx: Add control port
Date: Mon, 7 Mar 2022 05:55:15 +0300 [thread overview]
Message-ID: <CAHNKnsTUSfieWKuw5WOFPidezoVWDKkLqQV6xnDs560QAGXiCQ@mail.gmail.com> (raw)
In-Reply-To: <20220223223326.28021-6-ricardo.martinez@linux.intel.com>
On Thu, Feb 24, 2022 at 1:35 AM Ricardo Martinez
<ricardo.martinez@linux.intel.com> wrote:
> From: Haijun Liu <haijun.liu@mediatek.com>
>
> Control Port implements driver control messages such as modem-host
> handshaking, controls port enumeration, and handles exception messages.
>
> The handshaking process between the driver and the modem happens during
> the init sequence. The process involves the exchange of a list of
> supported runtime features to make sure that modem and host are ready
> to provide proper feature lists including port enumeration. Further
> features can be enabled and controlled in this handshaking process.
[skipped]
> +struct feature_query {
> + __le32 head_pattern;
> + u8 feature_set[FEATURE_COUNT];
> + __le32 tail_pattern;
> +};
> +
> +static void t7xx_prepare_host_rt_data_query(struct t7xx_sys_info *core)
> +{
> + struct t7xx_port_static *port_static = core->ctl_port->port_static;
> + struct ctrl_msg_header *ctrl_msg_h;
> + struct feature_query *ft_query;
> + struct ccci_header *ccci_h;
> + struct sk_buff *skb;
> + size_t packet_size;
> +
> + packet_size = sizeof(*ccci_h) + sizeof(*ctrl_msg_h) + sizeof(*ft_query);
> + skb = __dev_alloc_skb(packet_size, GFP_KERNEL);
> + if (!skb)
> + return;
> +
> + skb_put(skb, packet_size);
> +
> + ccci_h = (struct ccci_header *)skb->data;
> + t7xx_ccci_header_init(ccci_h, 0, packet_size, port_static->tx_ch, 0);
> + ccci_h->status &= cpu_to_le32(~CCCI_H_SEQ_FLD);
> +
> + ctrl_msg_h = (struct ctrl_msg_header *)(skb->data + sizeof(*ccci_h));
> + t7xx_ctrl_msg_header_init(ctrl_msg_h, CTL_ID_HS1_MSG, 0, sizeof(*ft_query));
> +
> + ft_query = (struct feature_query *)(skb->data + sizeof(*ccci_h) + sizeof(*ctrl_msg_h));
> + ft_query->head_pattern = cpu_to_le32(MD_FEATURE_QUERY_ID);
> + memcpy(ft_query->feature_set, core->feature_set, FEATURE_COUNT);
> + ft_query->tail_pattern = cpu_to_le32(MD_FEATURE_QUERY_ID);
> +
> + /* Send HS1 message to device */
> + t7xx_port_proxy_send_skb(core->ctl_port, skb);
> +}
I do not care too much, but this code and many other places could be
greatly simplified. It looks like the modem communication protocol has
a layered design, skb and its API are also designed to handle layered
protocols. It just needs to rearrange the code a bit.
For example, to avoid manual accounting of each header in the stack,
skb allocation can be implemented using a stack of allocation
functions:
struct sk_buff *t7xx_port_alloc_skb(int payload)
{
struct sk_buff *skb = alloc_skb(payload + sizeof(struct ccci_header), ...);
if (skb)
skb_reserve(skb, sizeof(struct ccci_header));
return skb;
}
struct sk_buff *t7xx_ctrl_alloc_skb(int payload)
{
struct sk_buff *skb = t7xx_port_alloc_skb(payload + sizeof(struct
ctlr_msg_header), ...);
if (skb)
skb_reserve(skb, sizeof(struct ctrl_msg_header));
return skb;
}
Message sending operation can also be perfectly stacked:
int t7xx_port_proxy_send_skb(*port, *skb)
{
struct ccci_header *ccci_h = skb_push(skb, sizeof(*ccci_h));
/* Build CCCI header (including seqno assignment) */
ccci_h->packet_len = cpu_to_le32(skb->len);
res = cldma_send_skb(..., skb, ...);
if (res)
return res;
/* Update seqno counter here */
return 0;
}
int t7xx_ctrl_send_msg(port, msg_id, skb)
{
int len = skb->len; /* Preserve payload len */
struct ctrl_msg_header *ctrl_msg_h = skb_push(skb, sizeof(*ctrl_msg_h));
/* Build ctrl msg header here */
ctrl_msg_h->data_length = cpu_to_le32(len);
return t7xx_port_proxy_send_skb(port, skb);
}
So the above features request becomes as simple as:
void t7xx_prepare_host_rt_data_query(struct t7xx_sys_info *core)
{
struct feature_query *ft_query;
struct sk_buff *skb;
skb = t7xx_ctrl_alloc_skb(sizeof(*ft_query));
if (!skb)
return;
ft_query = skb_put(skb, sizeof(*ft_query));
/* Build features request here */
if (t7xx_ctrl_send_msg(core->ctl_port, CTL_ID_HS1_MSG, skb))
kfree_skb(skb);
}
Once the allocation and sending functions are implemented in a stacked
way, many other places can be simplified in a similar way.
[skipped]
> +static void t7xx_core_hk_handler(struct t7xx_modem *md, struct t7xx_fsm_ctl *ctl,
> + enum t7xx_fsm_event_state event_id,
> + enum t7xx_fsm_event_state err_detect)
> +{
> + struct t7xx_sys_info *core_info = &md->core_md;
> + struct device *dev = &md->t7xx_dev->pdev->dev;
> + struct t7xx_fsm_event *event, *event_next;
> + unsigned long flags;
> + void *event_data;
> + int ret;
> +
> + t7xx_prepare_host_rt_data_query(core_info);
> +
> + while (!kthread_should_stop()) {
> + bool event_received = false;
> +
> + spin_lock_irqsave(&ctl->event_lock, flags);
> + list_for_each_entry_safe(event, event_next, &ctl->event_queue, entry) {
> + if (event->event_id == err_detect) {
> + list_del(&event->entry);
> + spin_unlock_irqrestore(&ctl->event_lock, flags);
> + dev_err(dev, "Core handshake error event received\n");
> + goto err_free_event;
> + } else if (event->event_id == event_id) {
> + list_del(&event->entry);
> + event_received = true;
> + break;
> + }
> + }
> + spin_unlock_irqrestore(&ctl->event_lock, flags);
> +
> + if (event_received)
> + break;
> +
> + wait_event_interruptible(ctl->event_wq, !list_empty(&ctl->event_queue) ||
> + kthread_should_stop());
> + if (kthread_should_stop())
> + goto err_free_event;
> + }
> +
> + if (ctl->exp_flg)
> + goto err_free_event;
> +
> + event_data = (void *)event + sizeof(*event);
In the V2, the event structure has a data field. But then it was
dropped and now the attached data offset is manually calculated. Why
did you do this, why event->data is not suitable here?
> + ret = t7xx_parse_host_rt_data(ctl, core_info, dev, event_data, event->length);
> + if (ret) {
> + dev_err(dev, "Host failure parsing runtime data: %d\n", ret);
> + goto err_free_event;
> + }
> +
> + if (ctl->exp_flg)
> + goto err_free_event;
> +
> + ret = t7xx_prepare_device_rt_data(core_info, dev, event_data, event->length);
> + if (ret) {
> + dev_err(dev, "Device failure parsing runtime data: %d", ret);
> + goto err_free_event;
> + }
> +
> + core_info->ready = true;
> + core_info->handshake_ongoing = false;
> + wake_up(&ctl->async_hk_wq);
> +err_free_event:
> + kfree(event);
> +}
[skipped]
> +static int port_ctl_init(struct t7xx_port *port)
> +{
> + struct t7xx_port_static *port_static = port->port_static;
> +
> + port->skb_handler = &control_msg_handler;
& is not necessary here and only misguides readers.
> + port->thread = kthread_run(port_ctl_rx_thread, port, "%s", port_static->name);
> + if (IS_ERR(port->thread)) {
> + dev_err(port->dev, "Failed to start port control thread\n");
> + return PTR_ERR(port->thread);
> + }
> +
> + port->rx_length_th = CTRL_QUEUE_MAXLEN;
> + return 0;
> +}
[skipped]
> -static struct t7xx_port_static t7xx_md_ports[1];
> +static struct t7xx_port_static t7xx_md_ports[] = {
> + {
> + .tx_ch = PORT_CH_CONTROL_TX,
> + .rx_ch = PORT_CH_CONTROL_RX,
> + .txq_index = Q_IDX_CTRL,
> + .rxq_index = Q_IDX_CTRL,
> + .txq_exp_index = 0,
> + .rxq_exp_index = 0,
> + .path_id = CLDMA_ID_MD,
> + .flags = 0,
Zero initializer is not needed here, a static variable is filled with
zeros automatically.
> + .ops = &ctl_port_ops,
> + .name = "t7xx_ctrl",
> + },
> +};
[skipped]
> +void t7xx_port_proxy_send_msg_to_md(struct port_proxy *port_prox, enum port_ch ch,
> + unsigned int msg, unsigned int ex_msg)
This function is called only from the control port code and only with
ch = PORT_CH_CONTROL_TX, so I would like to recommend to move it there
and drop the ch argument.
> +{
> + struct ctrl_msg_header *ctrl_msg_h;
> + struct ccci_header *ccci_h;
> + struct t7xx_port *port;
> + struct sk_buff *skb;
> + int ret;
> +
> + port = t7xx_proxy_get_port_by_ch(port_prox, ch);
> + if (!port)
> + return;
> +
> + skb = __dev_alloc_skb(sizeof(*ccci_h), GFP_KERNEL);
> + if (!skb)
> + return;
> +
> + if (ch == PORT_CH_CONTROL_TX) {
> + ccci_h = (struct ccci_header *)(skb->data);
> + t7xx_ccci_header_init(ccci_h, CCCI_HEADER_NO_DATA,
> + sizeof(*ctrl_msg_h) + sizeof(*ccci_h), ch, 0);
> + ctrl_msg_h = (struct ctrl_msg_header *)(skb->data + sizeof(*ccci_h));
> + t7xx_ctrl_msg_header_init(ctrl_msg_h, msg, ex_msg, 0);
> + skb_put(skb, sizeof(*ccci_h) + sizeof(*ctrl_msg_h));
> + } else {
> + ccci_h = skb_put(skb, sizeof(*ccci_h));
> + t7xx_ccci_header_init(ccci_h, CCCI_HEADER_NO_DATA, msg, ch, ex_msg);
> + }
> +
> + ret = t7xx_port_proxy_send_skb(port, skb);
> + if (ret) {
> + struct t7xx_port_static *port_static = port->port_static;
> +
> + dev_kfree_skb_any(skb);
> + dev_err(port->dev, "port%s send to MD fail\n", port_static->name);
> + }
> +}
--
Sergey
next prev parent reply other threads:[~2022-03-07 2:55 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-23 22:33 [PATCH net-next v5 00/13] net: wwan: t7xx: PCIe driver for MediaTek M.2 modem Ricardo Martinez
2022-02-23 22:33 ` [PATCH net-next v5 01/13] list: Add list_next_entry_circular() and list_prev_entry_circular() Ricardo Martinez
2022-02-23 22:33 ` [PATCH net-next v5 02/13] net: wwan: t7xx: Add control DMA interface Ricardo Martinez
2022-02-25 10:54 ` Ilpo Järvinen
2022-03-08 0:46 ` Martinez, Ricardo
2022-03-07 2:42 ` Sergey Ryazanov
2022-02-23 22:33 ` [PATCH net-next v5 03/13] net: wwan: t7xx: Add core components Ricardo Martinez
2022-02-25 11:10 ` Ilpo Järvinen
2022-03-08 0:47 ` Martinez, Ricardo
2022-03-07 2:44 ` Sergey Ryazanov
2022-02-23 22:33 ` [PATCH net-next v5 04/13] net: wwan: t7xx: Add port proxy infrastructure Ricardo Martinez
2022-02-25 11:47 ` Ilpo Järvinen
2022-03-08 0:48 ` Martinez, Ricardo
2022-03-07 2:52 ` Sergey Ryazanov
2022-03-12 3:45 ` Martinez, Ricardo
2022-02-23 22:33 ` [PATCH net-next v5 05/13] net: wwan: t7xx: Add control port Ricardo Martinez
2022-02-25 12:05 ` Ilpo Järvinen
2022-03-07 2:55 ` Sergey Ryazanov [this message]
2022-03-17 17:59 ` Martinez, Ricardo
2022-02-23 22:33 ` [PATCH net-next v5 06/13] net: wwan: t7xx: Add AT and MBIM WWAN ports Ricardo Martinez
2022-02-25 12:23 ` Ilpo Järvinen
2022-03-07 2:56 ` Sergey Ryazanov
2022-03-09 0:01 ` Martinez, Ricardo
2022-03-10 0:13 ` Sergey Ryazanov
2022-03-11 21:41 ` Martinez, Ricardo
2022-02-23 22:33 ` [PATCH net-next v5 07/13] net: wwan: t7xx: Data path HW layer Ricardo Martinez
2022-02-25 16:18 ` Ilpo Järvinen
2022-02-23 22:33 ` [PATCH net-next v5 08/13] net: wwan: t7xx: Add data path interface Ricardo Martinez
2022-03-01 13:05 ` Ilpo Järvinen
2022-03-07 2:58 ` Sergey Ryazanov
2022-04-04 23:29 ` Martinez, Ricardo
2022-04-04 23:50 ` Sergey Ryazanov
2022-04-05 0:10 ` Martinez, Ricardo
2022-02-23 22:33 ` [PATCH net-next v5 09/13] net: wwan: t7xx: Add WWAN network interface Ricardo Martinez
2022-03-07 2:59 ` Sergey Ryazanov
2022-02-23 22:33 ` [PATCH net-next v5 10/13] net: wwan: t7xx: Introduce power management Ricardo Martinez
2022-03-01 13:26 ` Ilpo Järvinen
2022-03-08 0:54 ` Martinez, Ricardo
2022-02-23 22:33 ` [PATCH net-next v5 11/13] net: wwan: t7xx: Runtime PM Ricardo Martinez
2022-02-23 22:33 ` [PATCH net-next v5 12/13] net: wwan: t7xx: Device deep sleep lock/unlock Ricardo Martinez
2022-03-10 10:21 ` Ilpo Järvinen
2022-03-18 23:49 ` Martinez, Ricardo
2022-03-22 12:31 ` Ilpo Järvinen
2022-02-23 22:33 ` [PATCH net-next v5 13/13] net: wwan: t7xx: Add maintainers and documentation Ricardo Martinez
2022-03-07 3:00 ` [PATCH net-next v5 00/13] net: wwan: t7xx: PCIe driver for MediaTek M.2 modem Sergey Ryazanov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAHNKnsTUSfieWKuw5WOFPidezoVWDKkLqQV6xnDs560QAGXiCQ@mail.gmail.com \
--to=ryazanov.s.a@gmail.com \
--cc=Soumya.Prakash.Mishra@intel.com \
--cc=amir.hanania@intel.com \
--cc=andriy.shevchenko@linux.intel.com \
--cc=chandrashekar.devegowda@intel.com \
--cc=chiranjeevi.rapolu@linux.intel.com \
--cc=davem@davemloft.net \
--cc=dinesh.sharma@intel.com \
--cc=eliot.lee@intel.com \
--cc=haijun.liu@mediatek.com \
--cc=ilpo.johannes.jarvinen@intel.com \
--cc=johannes@sipsolutions.net \
--cc=kuba@kernel.org \
--cc=linux-wireless@vger.kernel.org \
--cc=linuxwwan@intel.com \
--cc=loic.poulain@linaro.org \
--cc=m.chetan.kumar@intel.com \
--cc=madhusmita.sahu@intel.com \
--cc=moises.veleta@intel.com \
--cc=muralidharan.sethuraman@intel.com \
--cc=netdev@vger.kernel.org \
--cc=pierre-louis.bossart@intel.com \
--cc=ricardo.martinez@linux.intel.com \
--cc=sreehari.kancharla@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).