Skip to content

Commit

Permalink
net: cdc_ncm: use true max dgram count for header estimates
Browse files Browse the repository at this point in the history
Many newer NCM and MBIM devices will request a maximum tx
datagram count which is much smaller than our hard-coded
absolute max. We can reduce the overhead without sacrificing
any of the simplicity for these devices, by simply using the
true negotiated count in when calculated the maximum NTH and
NDP header sizes.

Signed-off-by: Bjørn Mork <bjorn@mork.no>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Bjørn Mork authored and David S. Miller committed May 17, 2014
1 parent 6c4e548 commit 70559b8
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 12 deletions.
9 changes: 6 additions & 3 deletions drivers/net/usb/cdc_ncm.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ static void cdc_ncm_update_rxtx_max(struct usbnet *dev, u32 new_rx, u32 new_tx)
}

/* clamp new_tx to sane values */
min = CDC_NCM_MIN_HDR_SIZE + ctx->max_datagram_size;
min = ctx->max_datagram_size + ctx->max_ndp_size + sizeof(struct usb_cdc_ncm_nth16);
max = min_t(u32, CDC_NCM_NTB_MAX_SIZE_TX, le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize));

/* some devices set dwNtbOutMaxSize too low for the above default */
Expand Down Expand Up @@ -318,6 +318,9 @@ static int cdc_ncm_init(struct usbnet *dev)
(ctx->tx_max_datagrams > CDC_NCM_DPT_DATAGRAMS_MAX))
ctx->tx_max_datagrams = CDC_NCM_DPT_DATAGRAMS_MAX;

/* set up maximum NDP size */
ctx->max_ndp_size = sizeof(struct usb_cdc_ncm_ndp16) + (ctx->tx_max_datagrams + 1) * sizeof(struct usb_cdc_ncm_dpe16);

/* initial coalescing timer interval */
ctx->timer_interval = CDC_NCM_TIMER_INTERVAL_USEC * NSEC_PER_USEC;

Expand Down Expand Up @@ -800,7 +803,7 @@ static struct usb_cdc_ncm_ndp16 *cdc_ncm_ndp(struct cdc_ncm_ctx *ctx, struct sk_
cdc_ncm_align_tail(skb, ctx->tx_ndp_modulus, 0, ctx->tx_max);

/* verify that there is room for the NDP and the datagram (reserve) */
if ((ctx->tx_max - skb->len - reserve) < CDC_NCM_NDP_SIZE)
if ((ctx->tx_max - skb->len - reserve) < ctx->max_ndp_size)
return NULL;

/* link to it */
Expand All @@ -810,7 +813,7 @@ static struct usb_cdc_ncm_ndp16 *cdc_ncm_ndp(struct cdc_ncm_ctx *ctx, struct sk_
nth16->wNdpIndex = cpu_to_le16(skb->len);

/* push a new empty NDP */
ndp16 = (struct usb_cdc_ncm_ndp16 *)memset(skb_put(skb, CDC_NCM_NDP_SIZE), 0, CDC_NCM_NDP_SIZE);
ndp16 = (struct usb_cdc_ncm_ndp16 *)memset(skb_put(skb, ctx->max_ndp_size), 0, ctx->max_ndp_size);
ndp16->dwSignature = sign;
ndp16->wLength = cpu_to_le16(sizeof(struct usb_cdc_ncm_ndp16) + sizeof(struct usb_cdc_ncm_dpe16));
return ndp16;
Expand Down
10 changes: 1 addition & 9 deletions include/linux/usb/cdc_ncm.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,6 @@
#define CDC_NCM_TIMER_INTERVAL_MIN 5UL
#define CDC_NCM_TIMER_INTERVAL_MAX (15UL * USEC_PER_SEC)

/* The following macro defines the minimum header space */
#define CDC_NCM_MIN_HDR_SIZE \
(sizeof(struct usb_cdc_ncm_nth16) + sizeof(struct usb_cdc_ncm_ndp16) + \
(CDC_NCM_DPT_DATAGRAMS_MAX + 1) * sizeof(struct usb_cdc_ncm_dpe16))

#define CDC_NCM_NDP_SIZE \
(sizeof(struct usb_cdc_ncm_ndp16) + \
(CDC_NCM_DPT_DATAGRAMS_MAX + 1) * sizeof(struct usb_cdc_ncm_dpe16))

#define cdc_ncm_comm_intf_is_mbim(x) ((x)->desc.bInterfaceSubClass == USB_CDC_SUBCLASS_MBIM && \
(x)->desc.bInterfaceProtocol == USB_CDC_PROTO_NONE)
#define cdc_ncm_data_intf_is_mbim(x) ((x)->desc.bInterfaceProtocol == USB_CDC_MBIM_PROTO_NTB)
Expand All @@ -110,6 +101,7 @@ struct cdc_ncm_ctx {
atomic_t stop;

u64 timer_interval;
u32 max_ndp_size;

u32 tx_timer_pending;
u32 tx_curr_frame_num;
Expand Down

0 comments on commit 70559b8

Please sign in to comment.