pegasus.c (fb58cf4f2881eeb21b2a5997871a1678772b746d) pegasus.c (f30e25a9d1b25ac8d40071c4dc2679ad0fcdc55a)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (c) 1999-2013 Petko Manolov (petkan@nucleusys.com)
4 *
5 * ChangeLog:
6 * .... Most of the time spent on reading sources & docs.
7 * v0.2.x First official release for the Linux kernel.
8 * v0.3.0 Beutified and structured, some bugs fixed.

--- 110 unchanged lines hidden (view full) ---

119 if (status < 0)
120 dev_dbg(&urb->dev->dev, "%s failed with %d", __func__, status);
121 kfree(req);
122 usb_free_urb(urb);
123}
124
125static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
126{
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (c) 1999-2013 Petko Manolov (petkan@nucleusys.com)
4 *
5 * ChangeLog:
6 * .... Most of the time spent on reading sources & docs.
7 * v0.2.x First official release for the Linux kernel.
8 * v0.3.0 Beutified and structured, some bugs fixed.

--- 110 unchanged lines hidden (view full) ---

119 if (status < 0)
120 dev_dbg(&urb->dev->dev, "%s failed with %d", __func__, status);
121 kfree(req);
122 usb_free_urb(urb);
123}
124
125static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
126{
127 return usb_control_msg_recv(pegasus->usb, 0, PEGASUS_REQ_GET_REGS,
128 PEGASUS_REQT_READ, 0, indx, data, size,
129 1000, GFP_NOIO);
127 u8 *buf;
128 int ret;
129
130 buf = kmalloc(size, GFP_NOIO);
131 if (!buf)
132 return -ENOMEM;
133
134 ret = usb_control_msg(pegasus->usb, usb_rcvctrlpipe(pegasus->usb, 0),
135 PEGASUS_REQ_GET_REGS, PEGASUS_REQT_READ, 0,
136 indx, buf, size, 1000);
137 if (ret < 0)
138 netif_dbg(pegasus, drv, pegasus->net,
139 "%s returned %d\n", __func__, ret);
140 else if (ret <= size)
141 memcpy(data, buf, ret);
142 kfree(buf);
143 return ret;
130}
131
132static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size,
133 const void *data)
134{
144}
145
146static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size,
147 const void *data)
148{
135 return usb_control_msg_send(pegasus->usb, 0, PEGASUS_REQ_SET_REGS,
136 PEGASUS_REQT_WRITE, 0, indx, data, size,
137 1000, GFP_NOIO);
149 u8 *buf;
150 int ret;
151
152 buf = kmemdup(data, size, GFP_NOIO);
153 if (!buf)
154 return -ENOMEM;
155
156 ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0),
157 PEGASUS_REQ_SET_REGS, PEGASUS_REQT_WRITE, 0,
158 indx, buf, size, 100);
159 if (ret < 0)
160 netif_dbg(pegasus, drv, pegasus->net,
161 "%s returned %d\n", __func__, ret);
162 kfree(buf);
163 return ret;
138}
139
164}
165
140/*
141 * There is only one way to write to a single ADM8511 register and this is via
142 * specific control request. 'data' is ignored by the device, but it is here to
143 * not break the API.
144 */
145static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data)
146{
166static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data)
167{
147 void *buf = &data;
168 u8 *buf;
169 int ret;
148
170
149 return usb_control_msg_send(pegasus->usb, 0, PEGASUS_REQ_SET_REG,
150 PEGASUS_REQT_WRITE, data, indx, buf, 1,
151 1000, GFP_NOIO);
171 buf = kmemdup(&data, 1, GFP_NOIO);
172 if (!buf)
173 return -ENOMEM;
174
175 ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0),
176 PEGASUS_REQ_SET_REG, PEGASUS_REQT_WRITE, data,
177 indx, buf, 1, 1000);
178 if (ret < 0)
179 netif_dbg(pegasus, drv, pegasus->net,
180 "%s returned %d\n", __func__, ret);
181 kfree(buf);
182 return ret;
152}
153
154static int update_eth_regs_async(pegasus_t *pegasus)
155{
156 int ret = -ENOMEM;
157 struct urb *async_urb;
158 struct usb_ctrlrequest *req;
159

--- 164 unchanged lines hidden (view full) ---

324 return ret;
325
326fail:
327 netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__);
328 return -ETIMEDOUT;
329}
330#endif /* PEGASUS_WRITE_EEPROM */
331
183}
184
185static int update_eth_regs_async(pegasus_t *pegasus)
186{
187 int ret = -ENOMEM;
188 struct urb *async_urb;
189 struct usb_ctrlrequest *req;
190

--- 164 unchanged lines hidden (view full) ---

355 return ret;
356
357fail:
358 netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__);
359 return -ETIMEDOUT;
360}
361#endif /* PEGASUS_WRITE_EEPROM */
362
332static inline void get_node_id(pegasus_t *pegasus, __u8 *id)
363static inline int get_node_id(pegasus_t *pegasus, u8 *id)
333{
364{
334 int i;
335 __u16 w16;
365 int i, ret;
366 u16 w16;
336
337 for (i = 0; i < 3; i++) {
367
368 for (i = 0; i < 3; i++) {
338 read_eprom_word(pegasus, i, &w16);
369 ret = read_eprom_word(pegasus, i, &w16);
370 if (ret < 0)
371 return ret;
339 ((__le16 *) id)[i] = cpu_to_le16(w16);
340 }
372 ((__le16 *) id)[i] = cpu_to_le16(w16);
373 }
374
375 return 0;
341}
342
343static void set_ethernet_addr(pegasus_t *pegasus)
344{
376}
377
378static void set_ethernet_addr(pegasus_t *pegasus)
379{
345 __u8 node_id[6];
380 int ret;
381 u8 node_id[6];
346
347 if (pegasus->features & PEGASUS_II) {
382
383 if (pegasus->features & PEGASUS_II) {
348 get_registers(pegasus, 0x10, sizeof(node_id), node_id);
384 ret = get_registers(pegasus, 0x10, sizeof(node_id), node_id);
385 if (ret < 0)
386 goto err;
349 } else {
387 } else {
350 get_node_id(pegasus, node_id);
351 set_registers(pegasus, EthID, sizeof(node_id), node_id);
388 ret = get_node_id(pegasus, node_id);
389 if (ret < 0)
390 goto err;
391 ret = set_registers(pegasus, EthID, sizeof(node_id), node_id);
392 if (ret < 0)
393 goto err;
352 }
394 }
395
353 memcpy(pegasus->net->dev_addr, node_id, sizeof(node_id));
396 memcpy(pegasus->net->dev_addr, node_id, sizeof(node_id));
397
398 return;
399err:
400 eth_hw_addr_random(pegasus->net);
401 dev_info(&pegasus->intf->dev, "software assigned MAC address.\n");
402
403 return;
354}
355
356static inline int reset_mac(pegasus_t *pegasus)
357{
358 __u8 data = 0x8;
359 int i;
360
361 set_register(pegasus, EthCtrl1, data);

--- 932 unchanged lines hidden ---
404}
405
406static inline int reset_mac(pegasus_t *pegasus)
407{
408 __u8 data = 0x8;
409 int i;
410
411 set_register(pegasus, EthCtrl1, data);

--- 932 unchanged lines hidden ---