11// SPDX-License-Identifier: GPL-2.0-only
22/*
3- * Copyright (c) 1999-2013 Petko Manolov ([email protected] ) 3+ * Copyright (c) 1999-2021 Petko Manolov ([email protected] ) 44 *
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.
9- * v0.3.x URBifying bulk requests and bugfixing. First relatively
10- * stable release. Still can touch device's registers only
11- * from top-halves.
12- * v0.4.0 Control messages remained unurbified are now URBs.
13- * Now we can touch the HW at any time.
14- * v0.4.9 Control urbs again use process context to wait. Argh...
15- * Some long standing bugs (enable_net_traffic) fixed.
16- * Also nasty trick about resubmiting control urb from
17- * interrupt context used. Please let me know how it
18- * behaves. Pegasus II support added since this version.
19- * TODO: suppressing HCD warnings spewage on disconnect.
20- * v0.4.13 Ethernet address is now set at probe(), not at open()
21- * time as this seems to break dhcpd.
22- * v0.5.0 branch to 2.5.x kernels
23- * v0.5.1 ethtool support added
24- * v0.5.5 rx socket buffers are in a pool and the their allocation
25- * is out of the interrupt routine.
26- * ...
27- * v0.9.3 simplified [get|set]_register(s), async update registers
28- * logic revisited, receive skb_pool removed.
295 */
306
317#include <linux/sched.h>
4521/*
4622 * Version Information
4723 */
48- #define DRIVER_VERSION "v0.9.3 (2013/04/25)"
4924#define DRIVER_AUTHOR "Petko Manolov <
[email protected] >"
5025#define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
5126
@@ -132,9 +107,15 @@ static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
132107static int set_registers (pegasus_t * pegasus , __u16 indx , __u16 size ,
133108 const void * data )
134109{
135- return usb_control_msg_send (pegasus -> usb , 0 , PEGASUS_REQ_SET_REGS ,
110+ int ret ;
111+
112+ ret = usb_control_msg_send (pegasus -> usb , 0 , PEGASUS_REQ_SET_REGS ,
136113 PEGASUS_REQT_WRITE , 0 , indx , data , size ,
137114 1000 , GFP_NOIO );
115+ if (ret < 0 )
116+ netif_dbg (pegasus , drv , pegasus -> net , "%s failed with %d\n" , __func__ , ret );
117+
118+ return ret ;
138119}
139120
140121/*
@@ -145,10 +126,15 @@ static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size,
145126static int set_register (pegasus_t * pegasus , __u16 indx , __u8 data )
146127{
147128 void * buf = & data ;
129+ int ret ;
148130
149- return usb_control_msg_send (pegasus -> usb , 0 , PEGASUS_REQ_SET_REG ,
131+ ret = usb_control_msg_send (pegasus -> usb , 0 , PEGASUS_REQ_SET_REG ,
150132 PEGASUS_REQT_WRITE , data , indx , buf , 1 ,
151133 1000 , GFP_NOIO );
134+ if (ret < 0 )
135+ netif_dbg (pegasus , drv , pegasus -> net , "%s failed with %d\n" , __func__ , ret );
136+
137+ return ret ;
152138}
153139
154140static int update_eth_regs_async (pegasus_t * pegasus )
@@ -188,10 +174,9 @@ static int update_eth_regs_async(pegasus_t *pegasus)
188174
189175static int __mii_op (pegasus_t * p , __u8 phy , __u8 indx , __u16 * regd , __u8 cmd )
190176{
191- int i ;
192- __u8 data [4 ] = { phy , 0 , 0 , indx };
177+ int i , ret ;
193178 __le16 regdi ;
194- int ret = - ETIMEDOUT ;
179+ __u8 data [ 4 ] = { phy , 0 , 0 , indx } ;
195180
196181 if (cmd & PHY_WRITE ) {
197182 __le16 * t = (__le16 * ) & data [1 ];
@@ -207,12 +192,15 @@ static int __mii_op(pegasus_t *p, __u8 phy, __u8 indx, __u16 *regd, __u8 cmd)
207192 if (data [0 ] & PHY_DONE )
208193 break ;
209194 }
210- if (i >= REG_TIMEOUT )
195+ if (i >= REG_TIMEOUT ) {
196+ ret = - ETIMEDOUT ;
211197 goto fail ;
198+ }
212199 if (cmd & PHY_READ ) {
213200 ret = get_registers (p , PhyData , 2 , & regdi );
201+ if (ret < 0 )
202+ goto fail ;
214203 * regd = le16_to_cpu (regdi );
215- return ret ;
216204 }
217205 return 0 ;
218206fail :
@@ -235,9 +223,13 @@ static int write_mii_word(pegasus_t *pegasus, __u8 phy, __u8 indx, __u16 *regd)
235223static int mdio_read (struct net_device * dev , int phy_id , int loc )
236224{
237225 pegasus_t * pegasus = netdev_priv (dev );
226+ int ret ;
238227 u16 res ;
239228
240- read_mii_word (pegasus , phy_id , loc , & res );
229+ ret = read_mii_word (pegasus , phy_id , loc , & res );
230+ if (ret < 0 )
231+ return ret ;
232+
241233 return (int )res ;
242234}
243235
@@ -251,32 +243,35 @@ static void mdio_write(struct net_device *dev, int phy_id, int loc, int val)
251243
252244static int read_eprom_word (pegasus_t * pegasus , __u8 index , __u16 * retdata )
253245{
254- int i ;
255- __u8 tmp = 0 ;
246+ int ret , i ;
256247 __le16 retdatai ;
257- int ret ;
248+ __u8 tmp = 0 ;
258249
259250 set_register (pegasus , EpromCtrl , 0 );
260251 set_register (pegasus , EpromOffset , index );
261252 set_register (pegasus , EpromCtrl , EPROM_READ );
262253
263254 for (i = 0 ; i < REG_TIMEOUT ; i ++ ) {
264255 ret = get_registers (pegasus , EpromCtrl , 1 , & tmp );
256+ if (ret < 0 )
257+ goto fail ;
265258 if (tmp & EPROM_DONE )
266259 break ;
267- if (ret == - ESHUTDOWN )
268- goto fail ;
269260 }
270- if (i >= REG_TIMEOUT )
261+ if (i >= REG_TIMEOUT ) {
262+ ret = - ETIMEDOUT ;
271263 goto fail ;
264+ }
272265
273266 ret = get_registers (pegasus , EpromData , 2 , & retdatai );
267+ if (ret < 0 )
268+ goto fail ;
274269 * retdata = le16_to_cpu (retdatai );
275270 return ret ;
276271
277272fail :
278- netif_warn (pegasus , drv , pegasus -> net , "%s failed\n" , __func__ );
279- return - ETIMEDOUT ;
273+ netif_dbg (pegasus , drv , pegasus -> net , "%s failed\n" , __func__ );
274+ return ret ;
280275}
281276
282277#ifdef PEGASUS_WRITE_EEPROM
@@ -324,10 +319,10 @@ static int write_eprom_word(pegasus_t *pegasus, __u8 index, __u16 data)
324319 return ret ;
325320
326321fail :
327- netif_warn (pegasus , drv , pegasus -> net , "%s failed\n" , __func__ );
322+ netif_dbg (pegasus , drv , pegasus -> net , "%s failed\n" , __func__ );
328323 return - ETIMEDOUT ;
329324}
330- #endif /* PEGASUS_WRITE_EEPROM */
325+ #endif /* PEGASUS_WRITE_EEPROM */
331326
332327static inline int get_node_id (pegasus_t * pegasus , u8 * id )
333328{
@@ -367,19 +362,21 @@ static void set_ethernet_addr(pegasus_t *pegasus)
367362 return ;
368363err :
369364 eth_hw_addr_random (pegasus -> net );
370- dev_info ( & pegasus -> intf -> dev , "software assigned MAC address.\n" );
365+ netif_dbg ( pegasus , drv , pegasus -> net , "software assigned MAC address.\n" );
371366
372367 return ;
373368}
374369
375370static inline int reset_mac (pegasus_t * pegasus )
376371{
372+ int ret , i ;
377373 __u8 data = 0x8 ;
378- int i ;
379374
380375 set_register (pegasus , EthCtrl1 , data );
381376 for (i = 0 ; i < REG_TIMEOUT ; i ++ ) {
382- get_registers (pegasus , EthCtrl1 , 1 , & data );
377+ ret = get_registers (pegasus , EthCtrl1 , 1 , & data );
378+ if (ret < 0 )
379+ goto fail ;
383380 if (~data & 0x08 ) {
384381 if (loopback )
385382 break ;
@@ -402,22 +399,29 @@ static inline int reset_mac(pegasus_t *pegasus)
402399 }
403400 if (usb_dev_id [pegasus -> dev_index ].vendor == VENDOR_ELCON ) {
404401 __u16 auxmode ;
405- read_mii_word (pegasus , 3 , 0x1b , & auxmode );
402+ ret = read_mii_word (pegasus , 3 , 0x1b , & auxmode );
403+ if (ret < 0 )
404+ goto fail ;
406405 auxmode |= 4 ;
407406 write_mii_word (pegasus , 3 , 0x1b , & auxmode );
408407 }
409408
410409 return 0 ;
410+ fail :
411+ netif_dbg (pegasus , drv , pegasus -> net , "%s failed\n" , __func__ );
412+ return ret ;
411413}
412414
413415static int enable_net_traffic (struct net_device * dev , struct usb_device * usb )
414416{
415- __u16 linkpart ;
416- __u8 data [4 ];
417417 pegasus_t * pegasus = netdev_priv (dev );
418418 int ret ;
419+ __u16 linkpart ;
420+ __u8 data [4 ];
419421
420- read_mii_word (pegasus , pegasus -> phy , MII_LPA , & linkpart );
422+ ret = read_mii_word (pegasus , pegasus -> phy , MII_LPA , & linkpart );
423+ if (ret < 0 )
424+ goto fail ;
421425 data [0 ] = 0xc8 ; /* TX & RX enable, append status, no CRC */
422426 data [1 ] = 0 ;
423427 if (linkpart & (ADVERTISE_100FULL | ADVERTISE_10FULL ))
@@ -435,21 +439,26 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb)
435439 usb_dev_id [pegasus -> dev_index ].vendor == VENDOR_LINKSYS2 ||
436440 usb_dev_id [pegasus -> dev_index ].vendor == VENDOR_DLINK ) {
437441 u16 auxmode ;
438- read_mii_word (pegasus , 0 , 0x1b , & auxmode );
442+ ret = read_mii_word (pegasus , 0 , 0x1b , & auxmode );
443+ if (ret < 0 )
444+ goto fail ;
439445 auxmode |= 4 ;
440446 write_mii_word (pegasus , 0 , 0x1b , & auxmode );
441447 }
442448
449+ return 0 ;
450+ fail :
451+ netif_dbg (pegasus , drv , pegasus -> net , "%s failed\n" , __func__ );
443452 return ret ;
444453}
445454
446455static void read_bulk_callback (struct urb * urb )
447456{
448457 pegasus_t * pegasus = urb -> context ;
449458 struct net_device * net ;
459+ u8 * buf = urb -> transfer_buffer ;
450460 int rx_status , count = urb -> actual_length ;
451461 int status = urb -> status ;
452- u8 * buf = urb -> transfer_buffer ;
453462 __u16 pkt_len ;
454463
455464 if (!pegasus )
@@ -880,7 +889,6 @@ static void pegasus_get_drvinfo(struct net_device *dev,
880889 pegasus_t * pegasus = netdev_priv (dev );
881890
882891 strlcpy (info -> driver , driver_name , sizeof (info -> driver ));
883- strlcpy (info -> version , DRIVER_VERSION , sizeof (info -> version ));
884892 usb_make_path (pegasus -> usb , info -> bus_info , sizeof (info -> bus_info ));
885893}
886894
@@ -998,8 +1006,7 @@ static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
9981006 data [0 ] = pegasus -> phy ;
9991007 fallthrough ;
10001008 case SIOCDEVPRIVATE + 1 :
1001- read_mii_word (pegasus , data [0 ], data [1 ] & 0x1f , & data [3 ]);
1002- res = 0 ;
1009+ res = read_mii_word (pegasus , data [0 ], data [1 ] & 0x1f , & data [3 ]);
10031010 break ;
10041011 case SIOCDEVPRIVATE + 2 :
10051012 if (!capable (CAP_NET_ADMIN ))
@@ -1033,22 +1040,25 @@ static void pegasus_set_multicast(struct net_device *net)
10331040
10341041static __u8 mii_phy_probe (pegasus_t * pegasus )
10351042{
1036- int i ;
1043+ int i , ret ;
10371044 __u16 tmp ;
10381045
10391046 for (i = 0 ; i < 32 ; i ++ ) {
1040- read_mii_word (pegasus , i , MII_BMSR , & tmp );
1047+ ret = read_mii_word (pegasus , i , MII_BMSR , & tmp );
1048+ if (ret < 0 )
1049+ goto fail ;
10411050 if (tmp == 0 || tmp == 0xffff || (tmp & BMSR_MEDIA ) == 0 )
10421051 continue ;
10431052 else
10441053 return i ;
10451054 }
1046-
1055+ fail :
10471056 return 0xff ;
10481057}
10491058
10501059static inline void setup_pegasus_II (pegasus_t * pegasus )
10511060{
1061+ int ret ;
10521062 __u8 data = 0xa5 ;
10531063
10541064 set_register (pegasus , Reg1d , 0 );
@@ -1060,7 +1070,9 @@ static inline void setup_pegasus_II(pegasus_t *pegasus)
10601070 set_register (pegasus , Reg7b , 2 );
10611071
10621072 set_register (pegasus , 0x83 , data );
1063- get_registers (pegasus , 0x83 , 1 , & data );
1073+ ret = get_registers (pegasus , 0x83 , 1 , & data );
1074+ if (ret < 0 )
1075+ goto fail ;
10641076
10651077 if (data == 0xa5 )
10661078 pegasus -> chip = 0x8513 ;
@@ -1075,6 +1087,10 @@ static inline void setup_pegasus_II(pegasus_t *pegasus)
10751087 set_register (pegasus , Reg81 , 6 );
10761088 else
10771089 set_register (pegasus , Reg81 , 2 );
1090+
1091+ return ;
1092+ fail :
1093+ netif_dbg (pegasus , drv , pegasus -> net , "%s failed\n" , __func__ );
10781094}
10791095
10801096static void check_carrier (struct work_struct * work )
@@ -1296,7 +1312,7 @@ static void __init parse_id(char *id)
12961312
12971313static int __init pegasus_init (void )
12981314{
1299- pr_info ("%s: %s, " DRIVER_DESC "\n" , driver_name , DRIVER_VERSION );
1315+ pr_info ("%s: " DRIVER_DESC "\n" , driver_name );
13001316 if (devid )
13011317 parse_id (devid );
13021318 return usb_register (& pegasus_driver );
0 commit comments