1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * ASIX AX8817X based USB 2.0 Ethernet Devices
4 * Copyright (C) 2003-2006 David Hollis <dhollis@davehollis.com>
5 * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net>
6 * Copyright (C) 2006 James Painter <jamie.painter@iname.com>
7 * Copyright (c) 2002-2003 TiVo Inc.
12 #define AX_HOST_EN_RETRIES 30
14 int __must_check
asix_read_cmd(struct usbnet
*dev
, u8 cmd
, u16 value
, u16 index
,
15 u16 size
, void *data
, int in_pm
)
18 int (*fn
)(struct usbnet
*, u8
, u8
, u16
, u16
, void *, u16
);
25 fn
= usbnet_read_cmd_nopm
;
27 ret
= fn(dev
, cmd
, USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
28 value
, index
, data
, size
);
30 if (unlikely(ret
< size
)) {
31 ret
= ret
< 0 ? ret
: -ENODATA
;
33 netdev_warn(dev
->net
, "Failed to read reg index 0x%04x: %d\n",
40 int asix_write_cmd(struct usbnet
*dev
, u8 cmd
, u16 value
, u16 index
,
41 u16 size
, void *data
, int in_pm
)
44 int (*fn
)(struct usbnet
*, u8
, u8
, u16
, u16
, const void *, u16
);
49 fn
= usbnet_write_cmd
;
51 fn
= usbnet_write_cmd_nopm
;
53 ret
= fn(dev
, cmd
, USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
54 value
, index
, data
, size
);
56 if (unlikely(ret
< 0))
57 netdev_warn(dev
->net
, "Failed to write reg index 0x%04x: %d\n",
63 void asix_write_cmd_async(struct usbnet
*dev
, u8 cmd
, u16 value
, u16 index
,
66 usbnet_write_cmd_async(dev
, cmd
,
67 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
68 value
, index
, data
, size
);
71 static int asix_set_sw_mii(struct usbnet
*dev
, int in_pm
)
75 ret
= asix_write_cmd(dev
, AX_CMD_SET_SW_MII
, 0x0000, 0, 0, NULL
, in_pm
);
78 netdev_err(dev
->net
, "Failed to enable software MII access\n");
82 static int asix_set_hw_mii(struct usbnet
*dev
, int in_pm
)
86 ret
= asix_write_cmd(dev
, AX_CMD_SET_HW_MII
, 0x0000, 0, 0, NULL
, in_pm
);
88 netdev_err(dev
->net
, "Failed to enable hardware MII access\n");
92 static int asix_check_host_enable(struct usbnet
*dev
, int in_pm
)
97 for (i
= 0; i
< AX_HOST_EN_RETRIES
; ++i
) {
98 ret
= asix_set_sw_mii(dev
, in_pm
);
99 if (ret
== -ENODEV
|| ret
== -ETIMEDOUT
)
101 usleep_range(1000, 1100);
102 ret
= asix_read_cmd(dev
, AX_CMD_STATMNGSTS_REG
,
103 0, 0, 1, &smsr
, in_pm
);
108 else if (smsr
& AX_HOST_EN
)
112 return i
>= AX_HOST_EN_RETRIES
? -ETIMEDOUT
: ret
;
115 static void reset_asix_rx_fixup_info(struct asix_rx_fixup_info
*rx
)
117 /* Reset the variables that have a lifetime outside of
118 * asix_rx_fixup_internal() so that future processing starts from a
119 * known set of initial conditions.
123 /* Discard any incomplete Ethernet frame in the netdev buffer */
124 kfree_skb(rx
->ax_skb
);
128 /* Assume the Data header 32-bit word is at the start of the current
129 * or next URB socket buffer so reset all the state variables.
132 rx
->split_head
= false;
136 int asix_rx_fixup_internal(struct usbnet
*dev
, struct sk_buff
*skb
,
137 struct asix_rx_fixup_info
*rx
)
142 /* When an Ethernet frame spans multiple URB socket buffers,
143 * do a sanity test for the Data header synchronisation.
144 * Attempt to detect the situation of the previous socket buffer having
145 * been truncated or a socket buffer was missing. These situations
146 * cause a discontinuity in the data stream and therefore need to avoid
147 * appending bad data to the end of the current netdev socket buffer.
148 * Also avoid unnecessarily discarding a good current netdev socket
151 if (rx
->remaining
&& (rx
->remaining
+ sizeof(u32
) <= skb
->len
)) {
152 offset
= ((rx
->remaining
+ 1) & 0xfffe);
153 rx
->header
= get_unaligned_le32(skb
->data
+ offset
);
156 size
= (u16
)(rx
->header
& 0x7ff);
157 if (size
!= ((~rx
->header
>> 16) & 0x7ff)) {
158 netdev_err(dev
->net
, "asix_rx_fixup() Data Header synchronisation was lost, remaining %d\n",
160 reset_asix_rx_fixup_info(rx
);
164 while (offset
+ sizeof(u16
) <= skb
->len
) {
167 if (!rx
->remaining
) {
168 if (skb
->len
- offset
== sizeof(u16
)) {
169 rx
->header
= get_unaligned_le16(
171 rx
->split_head
= true;
172 offset
+= sizeof(u16
);
176 if (rx
->split_head
== true) {
177 rx
->header
|= (get_unaligned_le16(
178 skb
->data
+ offset
) << 16);
179 rx
->split_head
= false;
180 offset
+= sizeof(u16
);
182 rx
->header
= get_unaligned_le32(skb
->data
+
184 offset
+= sizeof(u32
);
187 /* take frame length from Data header 32-bit word */
188 size
= (u16
)(rx
->header
& 0x7ff);
189 if (size
!= ((~rx
->header
>> 16) & 0x7ff)) {
190 netdev_err(dev
->net
, "asix_rx_fixup() Bad Header Length 0x%x, offset %d\n",
192 reset_asix_rx_fixup_info(rx
);
195 if (size
> dev
->net
->mtu
+ ETH_HLEN
+ VLAN_HLEN
) {
196 netdev_dbg(dev
->net
, "asix_rx_fixup() Bad RX Length %d\n",
198 reset_asix_rx_fixup_info(rx
);
202 /* Sometimes may fail to get a netdev socket buffer but
203 * continue to process the URB socket buffer so that
204 * synchronisation of the Ethernet frame Data header
205 * word is maintained.
207 rx
->ax_skb
= netdev_alloc_skb_ip_align(dev
->net
, size
);
209 rx
->remaining
= size
;
212 if (rx
->remaining
> skb
->len
- offset
) {
213 copy_length
= skb
->len
- offset
;
214 rx
->remaining
-= copy_length
;
216 copy_length
= rx
->remaining
;
221 skb_put_data(rx
->ax_skb
, skb
->data
+ offset
,
223 if (!rx
->remaining
) {
224 usbnet_skb_return(dev
, rx
->ax_skb
);
229 offset
+= (copy_length
+ 1) & 0xfffe;
232 if (skb
->len
!= offset
) {
233 netdev_err(dev
->net
, "asix_rx_fixup() Bad SKB Length %d, %d\n",
235 reset_asix_rx_fixup_info(rx
);
242 int asix_rx_fixup_common(struct usbnet
*dev
, struct sk_buff
*skb
)
244 struct asix_common_private
*dp
= dev
->driver_priv
;
245 struct asix_rx_fixup_info
*rx
= &dp
->rx_fixup_info
;
247 return asix_rx_fixup_internal(dev
, skb
, rx
);
250 void asix_rx_fixup_common_free(struct asix_common_private
*dp
)
252 struct asix_rx_fixup_info
*rx
;
257 rx
= &dp
->rx_fixup_info
;
260 kfree_skb(rx
->ax_skb
);
265 struct sk_buff
*asix_tx_fixup(struct usbnet
*dev
, struct sk_buff
*skb
,
269 int headroom
= skb_headroom(skb
);
270 int tailroom
= skb_tailroom(skb
);
272 u32 padbytes
= 0xffff0000;
275 padlen
= ((skb
->len
+ 4) & (dev
->maxpacket
- 1)) ? 0 : 4;
277 /* We need to push 4 bytes in front of frame (packet_len)
278 * and maybe add 4 bytes after the end (if padlen is 4)
280 * Avoid skb_copy_expand() expensive call, using following rules :
281 * - We are allowed to push 4 bytes in headroom if skb_header_cloned()
282 * is false (and if we have 4 bytes of headroom)
283 * - We are allowed to put 4 bytes at tail if skb_cloned()
284 * is false (and if we have 4 bytes of tailroom)
286 * TCP packets for example are cloned, but __skb_header_release()
287 * was called in tcp stack, allowing us to use headroom for our needs.
289 if (!skb_header_cloned(skb
) &&
290 !(padlen
&& skb_cloned(skb
)) &&
291 headroom
+ tailroom
>= 4 + padlen
) {
292 /* following should not happen, but better be safe */
295 skb
->data
= memmove(skb
->head
+ 4, skb
->data
, skb
->len
);
296 skb_set_tail_pointer(skb
, skb
->len
);
299 struct sk_buff
*skb2
;
301 skb2
= skb_copy_expand(skb
, 4, padlen
, flags
);
302 dev_kfree_skb_any(skb
);
308 packet_len
= ((skb
->len
^ 0x0000ffff) << 16) + skb
->len
;
309 ptr
= skb_push(skb
, 4);
310 put_unaligned_le32(packet_len
, ptr
);
313 put_unaligned_le32(padbytes
, skb_tail_pointer(skb
));
314 skb_put(skb
, sizeof(padbytes
));
317 usbnet_set_skb_tx_stats(skb
, 1, 0);
321 int asix_read_phy_addr(struct usbnet
*dev
, bool internal
)
326 ret
= asix_read_cmd(dev
, AX_CMD_READ_PHY_ID
, 0, 0, 2, buf
, 0);
335 offset
= (internal
? 1 : 0);
338 netdev_dbg(dev
->net
, "%s PHY address 0x%x\n",
339 internal
? "internal" : "external", ret
);
344 netdev_err(dev
->net
, "Error reading PHY_ID register: %02x\n", ret
);
349 int asix_sw_reset(struct usbnet
*dev
, u8 flags
, int in_pm
)
353 ret
= asix_write_cmd(dev
, AX_CMD_SW_RESET
, flags
, 0, 0, NULL
, in_pm
);
355 netdev_err(dev
->net
, "Failed to send software reset: %02x\n", ret
);
360 u16
asix_read_rx_ctl(struct usbnet
*dev
, int in_pm
)
363 int ret
= asix_read_cmd(dev
, AX_CMD_READ_RX_CTL
, 0, 0, 2, &v
, in_pm
);
366 netdev_err(dev
->net
, "Error reading RX_CTL register: %02x\n", ret
);
369 ret
= le16_to_cpu(v
);
374 int asix_write_rx_ctl(struct usbnet
*dev
, u16 mode
, int in_pm
)
378 netdev_dbg(dev
->net
, "asix_write_rx_ctl() - mode = 0x%04x\n", mode
);
379 ret
= asix_write_cmd(dev
, AX_CMD_WRITE_RX_CTL
, mode
, 0, 0, NULL
, in_pm
);
381 netdev_err(dev
->net
, "Failed to write RX_CTL mode to 0x%04x: %02x\n",
387 u16
asix_read_medium_status(struct usbnet
*dev
, int in_pm
)
390 int ret
= asix_read_cmd(dev
, AX_CMD_READ_MEDIUM_STATUS
,
394 netdev_err(dev
->net
, "Error reading Medium Status register: %02x\n",
396 return ret
; /* TODO: callers not checking for error ret */
399 return le16_to_cpu(v
);
403 int asix_write_medium_mode(struct usbnet
*dev
, u16 mode
, int in_pm
)
407 netdev_dbg(dev
->net
, "asix_write_medium_mode() - mode = 0x%04x\n", mode
);
408 ret
= asix_write_cmd(dev
, AX_CMD_WRITE_MEDIUM_MODE
,
409 mode
, 0, 0, NULL
, in_pm
);
411 netdev_err(dev
->net
, "Failed to write Medium Mode mode to 0x%04x: %02x\n",
417 /* set MAC link settings according to information from phylib */
418 void asix_adjust_link(struct net_device
*netdev
)
420 struct phy_device
*phydev
= netdev
->phydev
;
421 struct usbnet
*dev
= netdev_priv(netdev
);
425 mode
= AX88772_MEDIUM_DEFAULT
;
427 if (phydev
->duplex
== DUPLEX_HALF
)
428 mode
&= ~AX_MEDIUM_FD
;
430 if (phydev
->speed
!= SPEED_100
)
431 mode
&= ~AX_MEDIUM_PS
;
434 asix_write_medium_mode(dev
, mode
, 0);
435 phy_print_status(phydev
);
436 usbnet_link_change(dev
, phydev
->link
, 0);
439 int asix_write_gpio(struct usbnet
*dev
, u16 value
, int sleep
, int in_pm
)
443 netdev_dbg(dev
->net
, "asix_write_gpio() - value = 0x%04x\n", value
);
444 ret
= asix_write_cmd(dev
, AX_CMD_WRITE_GPIOS
, value
, 0, 0, NULL
, in_pm
);
446 netdev_err(dev
->net
, "Failed to write GPIO value 0x%04x: %02x\n",
456 * AX88772 & AX88178 have a 16-bit RX_CTL value
458 void asix_set_multicast(struct net_device
*net
)
460 struct usbnet
*dev
= netdev_priv(net
);
461 struct asix_data
*data
= (struct asix_data
*)&dev
->data
;
462 u16 rx_ctl
= AX_DEFAULT_RX_CTL
;
464 if (net
->flags
& IFF_PROMISC
) {
465 rx_ctl
|= AX_RX_CTL_PRO
;
466 } else if (net
->flags
& IFF_ALLMULTI
||
467 netdev_mc_count(net
) > AX_MAX_MCAST
) {
468 rx_ctl
|= AX_RX_CTL_AMALL
;
469 } else if (netdev_mc_empty(net
)) {
470 /* just broadcast and directed */
472 /* We use the 20 byte dev->data
473 * for our 8 byte filter buffer
474 * to avoid allocating memory that
475 * is tricky to free later */
476 struct netdev_hw_addr
*ha
;
479 memset(data
->multi_filter
, 0, AX_MCAST_FILTER_SIZE
);
481 /* Build the multicast hash filter. */
482 netdev_for_each_mc_addr(ha
, net
) {
483 crc_bits
= ether_crc(ETH_ALEN
, ha
->addr
) >> 26;
484 data
->multi_filter
[crc_bits
>> 3] |=
488 asix_write_cmd_async(dev
, AX_CMD_WRITE_MULTI_FILTER
, 0, 0,
489 AX_MCAST_FILTER_SIZE
, data
->multi_filter
);
491 rx_ctl
|= AX_RX_CTL_AM
;
494 asix_write_cmd_async(dev
, AX_CMD_WRITE_RX_CTL
, rx_ctl
, 0, 0, NULL
);
497 static int __asix_mdio_read(struct net_device
*netdev
, int phy_id
, int loc
,
500 struct usbnet
*dev
= netdev_priv(netdev
);
504 mutex_lock(&dev
->phy_mutex
);
506 ret
= asix_check_host_enable(dev
, in_pm
);
507 if (ret
== -ENODEV
|| ret
== -ETIMEDOUT
) {
508 mutex_unlock(&dev
->phy_mutex
);
512 ret
= asix_read_cmd(dev
, AX_CMD_READ_MII_REG
, phy_id
, (__u16
)loc
, 2,
517 ret
= asix_set_hw_mii(dev
, in_pm
);
519 mutex_unlock(&dev
->phy_mutex
);
521 netdev_dbg(dev
->net
, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n",
522 phy_id
, loc
, le16_to_cpu(res
));
524 return ret
< 0 ? ret
: le16_to_cpu(res
);
527 int asix_mdio_read(struct net_device
*netdev
, int phy_id
, int loc
)
529 return __asix_mdio_read(netdev
, phy_id
, loc
, false);
532 static int __asix_mdio_write(struct net_device
*netdev
, int phy_id
, int loc
,
535 struct usbnet
*dev
= netdev_priv(netdev
);
536 __le16 res
= cpu_to_le16(val
);
539 netdev_dbg(dev
->net
, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n",
542 mutex_lock(&dev
->phy_mutex
);
544 ret
= asix_check_host_enable(dev
, in_pm
);
548 ret
= asix_write_cmd(dev
, AX_CMD_WRITE_MII_REG
, phy_id
, (__u16
)loc
, 2,
553 ret
= asix_set_hw_mii(dev
, in_pm
);
555 mutex_unlock(&dev
->phy_mutex
);
557 return ret
< 0 ? ret
: 0;
560 void asix_mdio_write(struct net_device
*netdev
, int phy_id
, int loc
, int val
)
562 __asix_mdio_write(netdev
, phy_id
, loc
, val
, false);
565 /* MDIO read and write wrappers for phylib */
566 int asix_mdio_bus_read(struct mii_bus
*bus
, int phy_id
, int regnum
)
568 struct usbnet
*priv
= bus
->priv
;
570 return __asix_mdio_read(priv
->net
, phy_id
, regnum
, false);
573 int asix_mdio_bus_write(struct mii_bus
*bus
, int phy_id
, int regnum
, u16 val
)
575 struct usbnet
*priv
= bus
->priv
;
577 return __asix_mdio_write(priv
->net
, phy_id
, regnum
, val
, false);
580 int asix_mdio_read_nopm(struct net_device
*netdev
, int phy_id
, int loc
)
582 return __asix_mdio_read(netdev
, phy_id
, loc
, true);
586 asix_mdio_write_nopm(struct net_device
*netdev
, int phy_id
, int loc
, int val
)
588 __asix_mdio_write(netdev
, phy_id
, loc
, val
, true);
591 void asix_get_wol(struct net_device
*net
, struct ethtool_wolinfo
*wolinfo
)
593 struct usbnet
*dev
= netdev_priv(net
);
596 if (asix_read_cmd(dev
, AX_CMD_READ_MONITOR_MODE
,
597 0, 0, 1, &opt
, 0) < 0) {
598 wolinfo
->supported
= 0;
599 wolinfo
->wolopts
= 0;
602 wolinfo
->supported
= WAKE_PHY
| WAKE_MAGIC
;
603 wolinfo
->wolopts
= 0;
604 if (opt
& AX_MONITOR_LINK
)
605 wolinfo
->wolopts
|= WAKE_PHY
;
606 if (opt
& AX_MONITOR_MAGIC
)
607 wolinfo
->wolopts
|= WAKE_MAGIC
;
610 int asix_set_wol(struct net_device
*net
, struct ethtool_wolinfo
*wolinfo
)
612 struct usbnet
*dev
= netdev_priv(net
);
615 if (wolinfo
->wolopts
& ~(WAKE_PHY
| WAKE_MAGIC
))
618 if (wolinfo
->wolopts
& WAKE_PHY
)
619 opt
|= AX_MONITOR_LINK
;
620 if (wolinfo
->wolopts
& WAKE_MAGIC
)
621 opt
|= AX_MONITOR_MAGIC
;
623 if (asix_write_cmd(dev
, AX_CMD_WRITE_MONITOR_MODE
,
624 opt
, 0, 0, NULL
, 0) < 0)
630 int asix_get_eeprom_len(struct net_device
*net
)
632 return AX_EEPROM_LEN
;
635 int asix_get_eeprom(struct net_device
*net
, struct ethtool_eeprom
*eeprom
,
638 struct usbnet
*dev
= netdev_priv(net
);
640 int first_word
, last_word
;
643 if (eeprom
->len
== 0)
646 eeprom
->magic
= AX_EEPROM_MAGIC
;
648 first_word
= eeprom
->offset
>> 1;
649 last_word
= (eeprom
->offset
+ eeprom
->len
- 1) >> 1;
651 eeprom_buff
= kmalloc_array(last_word
- first_word
+ 1, sizeof(u16
),
656 /* ax8817x returns 2 bytes from eeprom on read */
657 for (i
= first_word
; i
<= last_word
; i
++) {
658 if (asix_read_cmd(dev
, AX_CMD_READ_EEPROM
, i
, 0, 2,
659 &eeprom_buff
[i
- first_word
], 0) < 0) {
665 memcpy(data
, (u8
*)eeprom_buff
+ (eeprom
->offset
& 1), eeprom
->len
);
670 int asix_set_eeprom(struct net_device
*net
, struct ethtool_eeprom
*eeprom
,
673 struct usbnet
*dev
= netdev_priv(net
);
675 int first_word
, last_word
;
679 netdev_dbg(net
, "write EEPROM len %d, offset %d, magic 0x%x\n",
680 eeprom
->len
, eeprom
->offset
, eeprom
->magic
);
682 if (eeprom
->len
== 0)
685 if (eeprom
->magic
!= AX_EEPROM_MAGIC
)
688 first_word
= eeprom
->offset
>> 1;
689 last_word
= (eeprom
->offset
+ eeprom
->len
- 1) >> 1;
691 eeprom_buff
= kmalloc_array(last_word
- first_word
+ 1, sizeof(u16
),
696 /* align data to 16 bit boundaries, read the missing data from
698 if (eeprom
->offset
& 1) {
699 ret
= asix_read_cmd(dev
, AX_CMD_READ_EEPROM
, first_word
, 0, 2,
702 netdev_err(net
, "Failed to read EEPROM at offset 0x%02x.\n", first_word
);
707 if ((eeprom
->offset
+ eeprom
->len
) & 1) {
708 ret
= asix_read_cmd(dev
, AX_CMD_READ_EEPROM
, last_word
, 0, 2,
709 &eeprom_buff
[last_word
- first_word
], 0);
711 netdev_err(net
, "Failed to read EEPROM at offset 0x%02x.\n", last_word
);
716 memcpy((u8
*)eeprom_buff
+ (eeprom
->offset
& 1), data
, eeprom
->len
);
718 /* write data to EEPROM */
719 ret
= asix_write_cmd(dev
, AX_CMD_WRITE_ENABLE
, 0x0000, 0, 0, NULL
, 0);
721 netdev_err(net
, "Failed to enable EEPROM write\n");
726 for (i
= first_word
; i
<= last_word
; i
++) {
727 netdev_dbg(net
, "write to EEPROM at offset 0x%02x, data 0x%04x\n",
728 i
, eeprom_buff
[i
- first_word
]);
729 ret
= asix_write_cmd(dev
, AX_CMD_WRITE_EEPROM
, i
,
730 eeprom_buff
[i
- first_word
], 0, NULL
, 0);
732 netdev_err(net
, "Failed to write EEPROM at offset 0x%02x.\n",
739 ret
= asix_write_cmd(dev
, AX_CMD_WRITE_DISABLE
, 0x0000, 0, 0, NULL
, 0);
741 netdev_err(net
, "Failed to disable EEPROM write\n");
751 void asix_get_drvinfo(struct net_device
*net
, struct ethtool_drvinfo
*info
)
753 /* Inherit standard device info */
754 usbnet_get_drvinfo(net
, info
);
755 strscpy(info
->driver
, DRIVER_NAME
, sizeof(info
->driver
));
756 strscpy(info
->version
, DRIVER_VERSION
, sizeof(info
->version
));
759 int asix_set_mac_address(struct net_device
*net
, void *p
)
761 struct usbnet
*dev
= netdev_priv(net
);
762 struct asix_data
*data
= (struct asix_data
*)&dev
->data
;
763 struct sockaddr
*addr
= p
;
765 if (netif_running(net
))
767 if (!is_valid_ether_addr(addr
->sa_data
))
768 return -EADDRNOTAVAIL
;
770 eth_hw_addr_set(net
, addr
->sa_data
);
772 /* We use the 20 byte dev->data
773 * for our 6 byte mac buffer
774 * to avoid allocating memory that
775 * is tricky to free later */
776 memcpy(data
->mac_addr
, addr
->sa_data
, ETH_ALEN
);
777 asix_write_cmd_async(dev
, AX_CMD_WRITE_NODE_ID
, 0, 0, ETH_ALEN
,