hc
2024-05-16 8d2a02b24d66aa359e83eebc1ed3c0f85367a1cb
kernel/drivers/net/usb/cx82310_eth.c
....@@ -1,20 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Driver for USB ethernet port of Conexant CX82310-based ADSL routers
34 * Copyright (C) 2010 by Ondrej Zary
45 * some parts inspired by the cxacru driver
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
186 */
197
208 #include <linux/module.h>
....@@ -52,6 +40,11 @@
5240 #define CX82310_MTU 1514
5341 #define CMD_EP 0x01
5442
43
+struct cx82310_priv {
44
+ struct work_struct reenable_work;
45
+ struct usbnet *dev;
46
+};
47
+
5548 /*
5649 * execute control command
5750 * - optionally send some data (command parameters)
....@@ -78,8 +71,8 @@
7871 CMD_PACKET_SIZE, &actual_len, CMD_TIMEOUT);
7972 if (ret < 0) {
8073 if (cmd != CMD_GET_LINK_STATUS)
81
- dev_err(&dev->udev->dev, "send command %#x: error %d\n",
82
- cmd, ret);
74
+ netdev_err(dev->net, "send command %#x: error %d\n",
75
+ cmd, ret);
8376 goto end;
8477 }
8578
....@@ -91,30 +84,27 @@
9184 CMD_TIMEOUT);
9285 if (ret < 0) {
9386 if (cmd != CMD_GET_LINK_STATUS)
94
- dev_err(&dev->udev->dev,
95
- "reply receive error %d\n",
96
- ret);
87
+ netdev_err(dev->net, "reply receive error %d\n",
88
+ ret);
9789 goto end;
9890 }
9991 if (actual_len > 0)
10092 break;
10193 }
10294 if (actual_len == 0) {
103
- dev_err(&dev->udev->dev, "no reply to command %#x\n",
104
- cmd);
95
+ netdev_err(dev->net, "no reply to command %#x\n", cmd);
10596 ret = -EIO;
10697 goto end;
10798 }
10899 if (buf[0] != cmd) {
109
- dev_err(&dev->udev->dev,
110
- "got reply to command %#x, expected: %#x\n",
111
- buf[0], cmd);
100
+ netdev_err(dev->net, "got reply to command %#x, expected: %#x\n",
101
+ buf[0], cmd);
112102 ret = -EIO;
113103 goto end;
114104 }
115105 if (buf[1] != STATUS_SUCCESS) {
116
- dev_err(&dev->udev->dev, "command %#x failed: %#x\n",
117
- cmd, buf[1]);
106
+ netdev_err(dev->net, "command %#x failed: %#x\n", cmd,
107
+ buf[1]);
118108 ret = -EIO;
119109 goto end;
120110 }
....@@ -125,6 +115,23 @@
125115 end:
126116 kfree(buf);
127117 return ret;
118
+}
119
+
120
+static int cx82310_enable_ethernet(struct usbnet *dev)
121
+{
122
+ int ret = cx82310_cmd(dev, CMD_ETHERNET_MODE, true, "\x01", 1, NULL, 0);
123
+
124
+ if (ret)
125
+ netdev_err(dev->net, "unable to enable ethernet mode: %d\n",
126
+ ret);
127
+ return ret;
128
+}
129
+
130
+static void cx82310_reenable_work(struct work_struct *work)
131
+{
132
+ struct cx82310_priv *priv = container_of(work, struct cx82310_priv,
133
+ reenable_work);
134
+ cx82310_enable_ethernet(priv->dev);
128135 }
129136
130137 #define partial_len data[0] /* length of partial packet data */
....@@ -138,6 +145,7 @@
138145 struct usb_device *udev = dev->udev;
139146 u8 link[3];
140147 int timeout = 50;
148
+ struct cx82310_priv *priv;
141149
142150 /* avoid ADSL modems - continue only if iProduct is "USB NET CARD" */
143151 if (usb_string(udev, udev->descriptor.iProduct, buf, sizeof(buf)) > 0
....@@ -164,6 +172,15 @@
164172 if (!dev->partial_data)
165173 return -ENOMEM;
166174
175
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
176
+ if (!priv) {
177
+ ret = -ENOMEM;
178
+ goto err_partial;
179
+ }
180
+ dev->driver_priv = priv;
181
+ INIT_WORK(&priv->reenable_work, cx82310_reenable_work);
182
+ priv->dev = dev;
183
+
167184 /* wait for firmware to become ready (indicated by the link being up) */
168185 while (--timeout) {
169186 ret = cx82310_cmd(dev, CMD_GET_LINK_STATUS, true, NULL, 0,
....@@ -174,24 +191,21 @@
174191 msleep(500);
175192 }
176193 if (!timeout) {
177
- dev_err(&udev->dev, "firmware not ready in time\n");
194
+ netdev_err(dev->net, "firmware not ready in time\n");
178195 ret = -ETIMEDOUT;
179196 goto err;
180197 }
181198
182199 /* enable ethernet mode (?) */
183
- ret = cx82310_cmd(dev, CMD_ETHERNET_MODE, true, "\x01", 1, NULL, 0);
184
- if (ret) {
185
- dev_err(&udev->dev, "unable to enable ethernet mode: %d\n",
186
- ret);
200
+ ret = cx82310_enable_ethernet(dev);
201
+ if (ret)
187202 goto err;
188
- }
189203
190204 /* get the MAC address */
191205 ret = cx82310_cmd(dev, CMD_GET_MAC_ADDR, true, NULL, 0,
192206 dev->net->dev_addr, ETH_ALEN);
193207 if (ret) {
194
- dev_err(&udev->dev, "unable to read MAC address: %d\n", ret);
208
+ netdev_err(dev->net, "unable to read MAC address: %d\n", ret);
195209 goto err;
196210 }
197211
....@@ -202,13 +216,19 @@
202216
203217 return 0;
204218 err:
219
+ kfree(dev->driver_priv);
220
+err_partial:
205221 kfree((void *)dev->partial_data);
206222 return ret;
207223 }
208224
209225 static void cx82310_unbind(struct usbnet *dev, struct usb_interface *intf)
210226 {
227
+ struct cx82310_priv *priv = dev->driver_priv;
228
+
211229 kfree((void *)dev->partial_data);
230
+ cancel_work_sync(&priv->reenable_work);
231
+ kfree(dev->driver_priv);
212232 }
213233
214234 /*
....@@ -223,6 +243,7 @@
223243 {
224244 int len;
225245 struct sk_buff *skb2;
246
+ struct cx82310_priv *priv = dev->driver_priv;
226247
227248 /*
228249 * If the last skb ended with an incomplete packet, this skb contains
....@@ -257,9 +278,11 @@
257278 break;
258279 }
259280
260
- if (len > CX82310_MTU) {
261
- dev_err(&dev->udev->dev, "RX packet too long: %d B\n",
262
- len);
281
+ if (len == 0xffff) {
282
+ netdev_info(dev->net, "router was rebooted, re-enabling ethernet mode");
283
+ schedule_work(&priv->reenable_work);
284
+ } else if (len > CX82310_MTU) {
285
+ netdev_err(dev->net, "RX packet too long: %d B\n", len);
263286 return 0;
264287 }
265288