Linux USB
 help / color / mirror / Atom feed
* [RFC] usb: gadget: ncm: Add support to configure wMaSegmentSize
@ 2023-02-12 17:56 Krishna Kurapati
  2023-02-13 21:47 ` Maciej Żenczykowski
  0 siblings, 1 reply; 5+ messages in thread
From: Krishna Kurapati @ 2023-02-12 17:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Maciej Żenczykowski
  Cc: linux-usb, linux-kernel, quic_ppratap, quic_jackp,
	Krishna Kurapati

Currently the NCM driver restricts wMasxSegmentSize that indicates
the datagram size coming from network layer to 1514. However the
spec doesn't have any limitation.

Add support to configure this value before configfs symlink is
created. Also since the NTB Out/In buffer sizes are fixed at 16384
bytes, limit the segment size to an upper cap of 8192 bytes so that
at least 2 packets can be aggregated.

Signed-off-by: Krishna Kurapati <quic_kriskura@quicinc.com>
---
 drivers/usb/gadget/function/f_ncm.c | 55 +++++++++++++++++++++++++++++
 drivers/usb/gadget/function/u_ncm.h |  1 +
 2 files changed, 56 insertions(+)

diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c
index 424bb3b666db..1969e276017f 100644
--- a/drivers/usb/gadget/function/f_ncm.c
+++ b/drivers/usb/gadget/function/f_ncm.c
@@ -118,6 +118,12 @@ static inline unsigned ncm_bitrate(struct usb_gadget *g)
 /* Delay for the transmit to wait before sending an unfilled NTB frame. */
 #define TX_TIMEOUT_NSECS	300000
 
+/*
+ * Currently the max NTB Buffer size is set to 16384. For atleast 2 packets
+ * to be aggregated, the size of datagram must at max be 8192.
+ */
+#define MAX_DATAGRAM_SIZE	8192
+
 #define FORMATS_SUPPORTED	(USB_CDC_NCM_NTB16_SUPPORTED |	\
 				 USB_CDC_NCM_NTB32_SUPPORTED)
 
@@ -1440,6 +1446,7 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f)
 	 */
 	if (!ncm_opts->bound) {
 		mutex_lock(&ncm_opts->lock);
+		ncm_opts->net->mtu = (ncm_opts->max_segment_size - 14);
 		gether_set_gadget(ncm_opts->net, cdev->gadget);
 		status = gether_register_netdev(ncm_opts->net);
 		mutex_unlock(&ncm_opts->lock);
@@ -1484,6 +1491,8 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f)
 
 	status = -ENODEV;
 
+	ecm_desc.wMaxSegmentSize = ncm_opts->max_segment_size;
+
 	/* allocate instance-specific endpoints */
 	ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_in_desc);
 	if (!ep)
@@ -1586,11 +1595,56 @@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(ncm);
 /* f_ncm_opts_ifname */
 USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(ncm);
 
+static ssize_t ncm_opts_max_segment_size_show(struct config_item *item,
+						char *page)
+{
+	struct f_ncm_opts *opts = to_f_ncm_opts(item);
+	u32 segment_size;
+
+	mutex_lock(&opts->lock);
+	segment_size = opts->max_segment_size;
+	mutex_unlock(&opts->lock);
+
+	return sprintf(page, "%u\n", segment_size);
+}
+
+static ssize_t ncm_opts_max_segment_size_store(struct config_item *item,
+						const char *page, size_t len)
+{
+	struct f_ncm_opts *opts = to_f_ncm_opts(item);
+	int ret;
+	u32 segment_size;
+
+	mutex_lock(&opts->lock);
+	if (opts->refcnt) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	ret = kstrtou32(page, 0, &segment_size);
+	if (ret)
+		goto out;
+
+	if (segment_size > MAX_DATAGRAM_SIZE) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	opts->max_segment_size = segment_size;
+	ret = len;
+out:
+	mutex_unlock(&opts->lock);
+	return ret;
+}
+
+CONFIGFS_ATTR(ncm_opts_, max_segment_size);
+
 static struct configfs_attribute *ncm_attrs[] = {
 	&ncm_opts_attr_dev_addr,
 	&ncm_opts_attr_host_addr,
 	&ncm_opts_attr_qmult,
 	&ncm_opts_attr_ifname,
+	&ncm_opts_attr_max_segment_size,
 	NULL,
 };
 
@@ -1633,6 +1687,7 @@ static struct usb_function_instance *ncm_alloc_inst(void)
 		kfree(opts);
 		return ERR_CAST(net);
 	}
+	opts->max_segment_size = cpu_to_le16(ETH_FRAME_LEN);
 	INIT_LIST_HEAD(&opts->ncm_os_desc.ext_prop);
 
 	descs[0] = &opts->ncm_os_desc;
diff --git a/drivers/usb/gadget/function/u_ncm.h b/drivers/usb/gadget/function/u_ncm.h
index 5408854d8407..fab99d997476 100644
--- a/drivers/usb/gadget/function/u_ncm.h
+++ b/drivers/usb/gadget/function/u_ncm.h
@@ -31,6 +31,7 @@ struct f_ncm_opts {
 	 */
 	struct mutex			lock;
 	int				refcnt;
+	u32				max_segment_size;
 };
 
 #endif /* U_NCM_H */
-- 
2.39.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-02-17 14:40 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-02-12 17:56 [RFC] usb: gadget: ncm: Add support to configure wMaSegmentSize Krishna Kurapati
2023-02-13 21:47 ` Maciej Żenczykowski
2023-02-14  1:11   ` Krishna Kurapati PSSNV
2023-02-14  1:27   ` Krishna Kurapati PSSNV
2023-02-17 14:40     ` Krishna Kurapati PSSNV

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox