diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/usb/cdc_ncm.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 3b1ba8237768..b45e5cae2a6b 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -283,6 +283,48 @@ static DEVICE_ATTR(rx_max, S_IRUGO | S_IWUSR, cdc_ncm_show_rx_max, cdc_ncm_store static DEVICE_ATTR(tx_max, S_IRUGO | S_IWUSR, cdc_ncm_show_tx_max, cdc_ncm_store_tx_max); static DEVICE_ATTR(tx_timer_usecs, S_IRUGO | S_IWUSR, cdc_ncm_show_tx_timer_usecs, cdc_ncm_store_tx_timer_usecs); +static ssize_t ndp_to_end_show(struct device *d, struct device_attribute *attr, char *buf) +{ + struct usbnet *dev = netdev_priv(to_net_dev(d)); + struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; + + return sprintf(buf, "%c\n", ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END ? 'Y' : 'N'); +} + +static ssize_t ndp_to_end_store(struct device *d, struct device_attribute *attr, const char *buf, size_t len) +{ + struct usbnet *dev = netdev_priv(to_net_dev(d)); + struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; + bool enable; + + if (strtobool(buf, &enable)) + return -EINVAL; + + /* no change? */ + if (enable == (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END)) + return len; + + if (enable && !ctx->delayed_ndp16) { + ctx->delayed_ndp16 = kzalloc(ctx->max_ndp_size, GFP_KERNEL); + if (!ctx->delayed_ndp16) + return -ENOMEM; + } + + /* flush pending data before changing flag */ + netif_tx_lock_bh(dev->net); + usbnet_start_xmit(NULL, dev->net); + spin_lock_bh(&ctx->mtx); + if (enable) + ctx->drvflags |= CDC_NCM_FLAG_NDP_TO_END; + else + ctx->drvflags &= ~CDC_NCM_FLAG_NDP_TO_END; + spin_unlock_bh(&ctx->mtx); + netif_tx_unlock_bh(dev->net); + + return len; +} +static DEVICE_ATTR_RW(ndp_to_end); + #define NCM_PARM_ATTR(name, format, tocpu) \ static ssize_t cdc_ncm_show_##name(struct device *d, struct device_attribute *attr, char *buf) \ { \ @@ -305,6 +347,7 @@ NCM_PARM_ATTR(wNtbOutMaxDatagrams, "%u", le16_to_cpu); static struct attribute *cdc_ncm_sysfs_attrs[] = { &dev_attr_min_tx_pkt.attr, + &dev_attr_ndp_to_end.attr, &dev_attr_rx_max.attr, &dev_attr_tx_max.attr, &dev_attr_tx_timer_usecs.attr, |