aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb
diff options
context:
space:
mode:
authorBjørn Mork <bjorn@mork.no>2014-05-16 15:48:18 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-16 22:39:01 -0400
commit5aa73d5d72bddfcac253d06f84e80e38c5bb430c (patch)
treee642b6328ba8a70f29941161d33cf628de13a0c5 /drivers/net/usb
parent97dc48e220282742e4c4a8fde81bdd4dbe011f1e (diff)
net: cdc_ncm: split out rx_max/tx_max update of setup
Split out the part of setup dealing with updating the rx_max and tx_max buffer sizes so that this code can be reused for dynamically updating the limits. Signed-off-by: Bjørn Mork <bjorn@mork.no> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/usb')
-rw-r--r--drivers/net/usb/cdc_ncm.c88
1 files changed, 57 insertions, 31 deletions
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index d23bca57a23f..e5f5153bf8c6 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -65,6 +65,61 @@ static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx);
65static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer); 65static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer);
66static struct usb_driver cdc_ncm_driver; 66static struct usb_driver cdc_ncm_driver;
67 67
68/* handle rx_max and tx_max changes */
69static void cdc_ncm_update_rxtx_max(struct usbnet *dev, u32 new_rx, u32 new_tx)
70{
71 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
72 u8 iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber;
73 u32 val, max, min;
74
75 /* clamp new_rx to sane values */
76 min = USB_CDC_NCM_NTB_MIN_IN_SIZE;
77 max = min_t(u32, CDC_NCM_NTB_MAX_SIZE_RX, le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize));
78
79 /* dwNtbInMaxSize spec violation? Use MIN size for both limits */
80 if (max < min) {
81 dev_warn(&dev->intf->dev, "dwNtbInMaxSize=%u is too small. Using %u\n",
82 le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize), min);
83 max = min;
84 }
85
86 val = clamp_t(u32, new_rx, min, max);
87 if (val != new_rx) {
88 dev_dbg(&dev->intf->dev, "rx_max must be in the [%u, %u] range. Using %u\n",
89 min, max, val);
90 }
91
92 /* inform device about NTB input size changes */
93 if (val != ctx->rx_max) {
94 __le32 dwNtbInMaxSize = cpu_to_le32(val);
95
96 dev_info(&dev->intf->dev, "setting rx_max = %u\n", val);
97 if (usbnet_write_cmd(dev, USB_CDC_SET_NTB_INPUT_SIZE,
98 USB_TYPE_CLASS | USB_DIR_OUT
99 | USB_RECIP_INTERFACE,
100 0, iface_no, &dwNtbInMaxSize, 4) < 0)
101 dev_dbg(&dev->intf->dev, "Setting NTB Input Size failed\n");
102 else
103 ctx->rx_max = val;
104 }
105
106 /* clamp new_tx to sane values */
107 min = CDC_NCM_MIN_HDR_SIZE + ctx->max_datagram_size;
108 max = min_t(u32, CDC_NCM_NTB_MAX_SIZE_TX, le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize));
109
110 /* some devices set dwNtbOutMaxSize too low for the above default */
111 min = min(min, max);
112
113 val = clamp_t(u32, new_tx, min, max);
114 if (val != new_tx) {
115 dev_dbg(&dev->intf->dev, "tx_max must be in the [%u, %u] range. Using %u\n",
116 min, max, val);
117 }
118 if (val != ctx->tx_max)
119 dev_info(&dev->intf->dev, "setting tx_max = %u\n", val);
120 ctx->tx_max = val;
121}
122
68static int cdc_ncm_setup(struct usbnet *dev) 123static int cdc_ncm_setup(struct usbnet *dev)
69{ 124{
70 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; 125 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
@@ -132,37 +187,8 @@ static int cdc_ncm_setup(struct usbnet *dev)
132 (ctx->tx_max_datagrams > CDC_NCM_DPT_DATAGRAMS_MAX)) 187 (ctx->tx_max_datagrams > CDC_NCM_DPT_DATAGRAMS_MAX))
133 ctx->tx_max_datagrams = CDC_NCM_DPT_DATAGRAMS_MAX; 188 ctx->tx_max_datagrams = CDC_NCM_DPT_DATAGRAMS_MAX;
134 189
135 /* verify maximum size of received NTB in bytes */ 190 /* clamp rx_max and tx_max and inform device */
136 if (ctx->rx_max < USB_CDC_NCM_NTB_MIN_IN_SIZE) { 191 cdc_ncm_update_rxtx_max(dev, le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize), le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize));
137 dev_dbg(&dev->intf->dev, "Using min receive length=%d\n",
138 USB_CDC_NCM_NTB_MIN_IN_SIZE);
139 ctx->rx_max = USB_CDC_NCM_NTB_MIN_IN_SIZE;
140 }
141
142 if (ctx->rx_max > CDC_NCM_NTB_MAX_SIZE_RX) {
143 dev_dbg(&dev->intf->dev, "Using default maximum receive length=%d\n",
144 CDC_NCM_NTB_MAX_SIZE_RX);
145 ctx->rx_max = CDC_NCM_NTB_MAX_SIZE_RX;
146 }
147
148 /* inform device about NTB input size changes */
149 if (ctx->rx_max != le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize)) {
150 __le32 dwNtbInMaxSize = cpu_to_le32(ctx->rx_max);
151
152 err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_INPUT_SIZE,
153 USB_TYPE_CLASS | USB_DIR_OUT
154 | USB_RECIP_INTERFACE,
155 0, iface_no, &dwNtbInMaxSize, 4);
156 if (err < 0)
157 dev_dbg(&dev->intf->dev, "Setting NTB Input Size failed\n");
158 }
159
160 /* verify maximum size of transmitted NTB in bytes */
161 if (ctx->tx_max > CDC_NCM_NTB_MAX_SIZE_TX) {
162 dev_dbg(&dev->intf->dev, "Using default maximum transmit length=%d\n",
163 CDC_NCM_NTB_MAX_SIZE_TX);
164 ctx->tx_max = CDC_NCM_NTB_MAX_SIZE_TX;
165 }
166 192
167 /* 193 /*
168 * verify that the structure alignment is: 194 * verify that the structure alignment is: