aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-11-02 02:02:19 -0400
committerDavid S. Miller <davem@davemloft.net>2013-11-02 02:02:19 -0400
commitf99f4f8b094065601f87953b6d372d1e082bdf8b (patch)
treeb5bd37a8edb1e3ff5f0c261daddd8b3362824d9f
parentc1a2e95435976cb040db1f6c0afbe4287c3d2e28 (diff)
parenta6fe67087d7cb916e41b4ad1b3a57c91150edb88 (diff)
Merge branch 'cdc_ncm'
Bjørn Mork says: ==================== cdc_ncm: many small and mostly trivial fixes This series ended up longer than expected, and it is still not complete. There is more to come when time allows... Most changes are trivial. Notable non-trivial changes are - removed filtering of identical speed notifications - tx_max calulation is changed to count the pad byte if necessary, and respect the device limit as an absolute upper limit even if it is too low according to the spec - remove the bug preventing SET_MAX_DATAGRAM_SIZE from having any effect - drop the pad-to-max if ZLPs are enabled - the driver specific VERSION is dropped - dev->hard_mtu is set to tx_max instead of max_datagram_size causing usbnet to calculate the qlen based on the real max size of tx skbs This series has been tested, along with the previously posted cdc_mbim series, on the NCM and MBIM devices I have: - Ericsson F5521gw (NCM) - Huawei E367 (MBIM) - D-Link DWM-156 A7 (MBIM w/ too low dwNtb{In,Out}MaxSize bug) - Sierra Wireless MC7710 (MBIM w/ ZLP and CDC Union bugs) Apart from the D-Link modem dropping a lot less oversized frames with the fix dedicated to it, there are no end user noticable functional changes as a result of this series. But all the non-trivial changes I listed above are of course detectable by users looking at that specific area (except maybe the removed speed notification, which requires a device sending duplicates to be noticable - I don't have any such device). ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/usb/cdc_mbim.c2
-rw-r--r--drivers/net/usb/cdc_ncm.c490
-rw-r--r--include/linux/usb/cdc_ncm.h30
3 files changed, 233 insertions, 289 deletions
diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c
index 253472a8a983..af76aaf08b6b 100644
--- a/drivers/net/usb/cdc_mbim.c
+++ b/drivers/net/usb/cdc_mbim.c
@@ -175,7 +175,7 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb
175 } 175 }
176 176
177 spin_lock_bh(&ctx->mtx); 177 spin_lock_bh(&ctx->mtx);
178 skb_out = cdc_ncm_fill_tx_frame(ctx, skb, sign); 178 skb_out = cdc_ncm_fill_tx_frame(dev, skb, sign);
179 spin_unlock_bh(&ctx->mtx); 179 spin_unlock_bh(&ctx->mtx);
180 return skb_out; 180 return skb_out;
181 181
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 43afde8f48d2..11c703337577 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -53,8 +53,6 @@
53#include <linux/usb/cdc.h> 53#include <linux/usb/cdc.h>
54#include <linux/usb/cdc_ncm.h> 54#include <linux/usb/cdc_ncm.h>
55 55
56#define DRIVER_VERSION "14-Mar-2012"
57
58#if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM) 56#if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM)
59static bool prefer_mbim = true; 57static bool prefer_mbim = true;
60#else 58#else
@@ -68,71 +66,67 @@ static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx);
68static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer); 66static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer);
69static struct usb_driver cdc_ncm_driver; 67static struct usb_driver cdc_ncm_driver;
70 68
71static void 69static u8 cdc_ncm_setup(struct usbnet *dev)
72cdc_ncm_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
73{
74 struct usbnet *dev = netdev_priv(net);
75
76 strlcpy(info->driver, dev->driver_name, sizeof(info->driver));
77 strlcpy(info->version, DRIVER_VERSION, sizeof(info->version));
78 strlcpy(info->fw_version, dev->driver_info->description,
79 sizeof(info->fw_version));
80 usb_make_path(dev->udev, info->bus_info, sizeof(info->bus_info));
81}
82
83static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
84{ 70{
71 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
72 struct usb_cdc_ncm_ntb_parameters ncm_parm;
85 u32 val; 73 u32 val;
86 u8 flags; 74 u8 flags;
87 u8 iface_no; 75 u8 iface_no;
88 int err; 76 int err;
89 int eth_hlen; 77 int eth_hlen;
90 u16 ntb_fmt_supported; 78 u16 ntb_fmt_supported;
91 u32 min_dgram_size; 79 __le16 max_datagram_size;
92 u32 min_hdr_size;
93 struct usbnet *dev = netdev_priv(ctx->netdev);
94 80
95 iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber; 81 iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber;
96 82
97 err = usbnet_read_cmd(dev, USB_CDC_GET_NTB_PARAMETERS, 83 err = usbnet_read_cmd(dev, USB_CDC_GET_NTB_PARAMETERS,
98 USB_TYPE_CLASS | USB_DIR_IN 84 USB_TYPE_CLASS | USB_DIR_IN
99 |USB_RECIP_INTERFACE, 85 |USB_RECIP_INTERFACE,
100 0, iface_no, &ctx->ncm_parm, 86 0, iface_no, &ncm_parm,
101 sizeof(ctx->ncm_parm)); 87 sizeof(ncm_parm));
102 if (err < 0) { 88 if (err < 0) {
103 pr_debug("failed GET_NTB_PARAMETERS\n"); 89 dev_err(&dev->intf->dev, "failed GET_NTB_PARAMETERS\n");
104 return 1; 90 return err; /* GET_NTB_PARAMETERS is required */
105 } 91 }
106 92
107 /* read correct set of parameters according to device mode */ 93 /* read correct set of parameters according to device mode */
108 ctx->rx_max = le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize); 94 ctx->rx_max = le32_to_cpu(ncm_parm.dwNtbInMaxSize);
109 ctx->tx_max = le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize); 95 ctx->tx_max = le32_to_cpu(ncm_parm.dwNtbOutMaxSize);
110 ctx->tx_remainder = le16_to_cpu(ctx->ncm_parm.wNdpOutPayloadRemainder); 96 ctx->tx_remainder = le16_to_cpu(ncm_parm.wNdpOutPayloadRemainder);
111 ctx->tx_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutDivisor); 97 ctx->tx_modulus = le16_to_cpu(ncm_parm.wNdpOutDivisor);
112 ctx->tx_ndp_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutAlignment); 98 ctx->tx_ndp_modulus = le16_to_cpu(ncm_parm.wNdpOutAlignment);
113 /* devices prior to NCM Errata shall set this field to zero */ 99 /* devices prior to NCM Errata shall set this field to zero */
114 ctx->tx_max_datagrams = le16_to_cpu(ctx->ncm_parm.wNtbOutMaxDatagrams); 100 ctx->tx_max_datagrams = le16_to_cpu(ncm_parm.wNtbOutMaxDatagrams);
115 ntb_fmt_supported = le16_to_cpu(ctx->ncm_parm.bmNtbFormatsSupported); 101 ntb_fmt_supported = le16_to_cpu(ncm_parm.bmNtbFormatsSupported);
116 102
117 eth_hlen = ETH_HLEN; 103 /* there are some minor differences in NCM and MBIM defaults */
118 min_dgram_size = CDC_NCM_MIN_DATAGRAM_SIZE; 104 if (cdc_ncm_comm_intf_is_mbim(ctx->control->cur_altsetting)) {
119 min_hdr_size = CDC_NCM_MIN_HDR_SIZE; 105 if (!ctx->mbim_desc)
120 if (ctx->mbim_desc != NULL) { 106 return -EINVAL;
121 flags = ctx->mbim_desc->bmNetworkCapabilities;
122 eth_hlen = 0; 107 eth_hlen = 0;
123 min_dgram_size = CDC_MBIM_MIN_DATAGRAM_SIZE; 108 flags = ctx->mbim_desc->bmNetworkCapabilities;
124 min_hdr_size = 0; 109 ctx->max_datagram_size = le16_to_cpu(ctx->mbim_desc->wMaxSegmentSize);
125 } else if (ctx->func_desc != NULL) { 110 if (ctx->max_datagram_size < CDC_MBIM_MIN_DATAGRAM_SIZE)
126 flags = ctx->func_desc->bmNetworkCapabilities; 111 ctx->max_datagram_size = CDC_MBIM_MIN_DATAGRAM_SIZE;
127 } else { 112 } else {
128 flags = 0; 113 if (!ctx->func_desc)
114 return -EINVAL;
115 eth_hlen = ETH_HLEN;
116 flags = ctx->func_desc->bmNetworkCapabilities;
117 ctx->max_datagram_size = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize);
118 if (ctx->max_datagram_size < CDC_NCM_MIN_DATAGRAM_SIZE)
119 ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE;
129 } 120 }
130 121
131 pr_debug("dwNtbInMaxSize=%u dwNtbOutMaxSize=%u " 122 /* common absolute max for NCM and MBIM */
132 "wNdpOutPayloadRemainder=%u wNdpOutDivisor=%u " 123 if (ctx->max_datagram_size > CDC_NCM_MAX_DATAGRAM_SIZE)
133 "wNdpOutAlignment=%u wNtbOutMaxDatagrams=%u flags=0x%x\n", 124 ctx->max_datagram_size = CDC_NCM_MAX_DATAGRAM_SIZE;
134 ctx->rx_max, ctx->tx_max, ctx->tx_remainder, ctx->tx_modulus, 125
135 ctx->tx_ndp_modulus, ctx->tx_max_datagrams, flags); 126 dev_dbg(&dev->intf->dev,
127 "dwNtbInMaxSize=%u dwNtbOutMaxSize=%u wNdpOutPayloadRemainder=%u wNdpOutDivisor=%u wNdpOutAlignment=%u wNtbOutMaxDatagrams=%u flags=0x%x\n",
128 ctx->rx_max, ctx->tx_max, ctx->tx_remainder, ctx->tx_modulus,
129 ctx->tx_ndp_modulus, ctx->tx_max_datagrams, flags);
136 130
137 /* max count of tx datagrams */ 131 /* max count of tx datagrams */
138 if ((ctx->tx_max_datagrams == 0) || 132 if ((ctx->tx_max_datagrams == 0) ||
@@ -141,19 +135,19 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
141 135
142 /* verify maximum size of received NTB in bytes */ 136 /* verify maximum size of received NTB in bytes */
143 if (ctx->rx_max < USB_CDC_NCM_NTB_MIN_IN_SIZE) { 137 if (ctx->rx_max < USB_CDC_NCM_NTB_MIN_IN_SIZE) {
144 pr_debug("Using min receive length=%d\n", 138 dev_dbg(&dev->intf->dev, "Using min receive length=%d\n",
145 USB_CDC_NCM_NTB_MIN_IN_SIZE); 139 USB_CDC_NCM_NTB_MIN_IN_SIZE);
146 ctx->rx_max = USB_CDC_NCM_NTB_MIN_IN_SIZE; 140 ctx->rx_max = USB_CDC_NCM_NTB_MIN_IN_SIZE;
147 } 141 }
148 142
149 if (ctx->rx_max > CDC_NCM_NTB_MAX_SIZE_RX) { 143 if (ctx->rx_max > CDC_NCM_NTB_MAX_SIZE_RX) {
150 pr_debug("Using default maximum receive length=%d\n", 144 dev_dbg(&dev->intf->dev, "Using default maximum receive length=%d\n",
151 CDC_NCM_NTB_MAX_SIZE_RX); 145 CDC_NCM_NTB_MAX_SIZE_RX);
152 ctx->rx_max = CDC_NCM_NTB_MAX_SIZE_RX; 146 ctx->rx_max = CDC_NCM_NTB_MAX_SIZE_RX;
153 } 147 }
154 148
155 /* inform device about NTB input size changes */ 149 /* inform device about NTB input size changes */
156 if (ctx->rx_max != le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize)) { 150 if (ctx->rx_max != le32_to_cpu(ncm_parm.dwNtbInMaxSize)) {
157 __le32 dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); 151 __le32 dwNtbInMaxSize = cpu_to_le32(ctx->rx_max);
158 152
159 err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_INPUT_SIZE, 153 err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_INPUT_SIZE,
@@ -161,16 +155,22 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)