diff options
author | Bjørn Mork <bjorn@mork.no> | 2014-05-16 15:48:18 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-05-16 22:39:01 -0400 |
commit | 5aa73d5d72bddfcac253d06f84e80e38c5bb430c (patch) | |
tree | e642b6328ba8a70f29941161d33cf628de13a0c5 /drivers/net/usb | |
parent | 97dc48e220282742e4c4a8fde81bdd4dbe011f1e (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.c | 88 |
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); | |||
65 | static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer); | 65 | static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer); |
66 | static struct usb_driver cdc_ncm_driver; | 66 | static struct usb_driver cdc_ncm_driver; |
67 | 67 | ||
68 | /* handle rx_max and tx_max changes */ | ||
69 | static 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 | |||
68 | static int cdc_ncm_setup(struct usbnet *dev) | 123 | static 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: |