| 1 | /* $NetBSD: if_axenreg.h,v 1.3 2016/04/23 10:15:31 skrll Exp $ */ |
| 2 | /* $OpenBSD: if_axenreg.h,v 1.1 2013/10/07 05:37:41 yuo Exp $ */ |
| 3 | |
| 4 | /* |
| 5 | * Copyright (c) 2013 Yojiro UO <yuo@openbsd.org>. All right reserved. |
| 6 | * |
| 7 | */ |
| 8 | |
| 9 | #include <sys/rndsource.h> |
| 10 | |
| 11 | /* |
| 12 | * Definitions for the ASIX Electronics AX88179 to ethernet controller. |
| 13 | */ |
| 14 | |
| 15 | #define AXEN_PHY_ID 0x0003 |
| 16 | #define AXEN_MCAST_FILTER_SIZE 8 |
| 17 | /* unit: KB */ |
| 18 | #define AXEN_BUFSZ_LS 8 |
| 19 | #define AXEN_BUFSZ_HS 16 |
| 20 | #define AXEN_BUFSZ_SS 24 |
| 21 | |
| 22 | #define AXEN_REV_UA1 0 |
| 23 | #define AXEN_REV_UA2 1 |
| 24 | |
| 25 | |
| 26 | /* recieve header */ |
| 27 | /* |
| 28 | * +-multicast/broadcast |
| 29 | * | +-rx_ok |
| 30 | * | | ++-----L3_type (1:ipv4, 0/2:ipv6) |
| 31 | * pkt_len(13) | | ||+ ++-L4_type(0: icmp, 1: UDP, 4: TCP) |
| 32 | * |765|43210 76543210|7654 3210 7654 3210| |
| 33 | * |+-Drop_err |+-L4_err |+-L4_CSUM_ERR |
| 34 | * +--crc_err +--L3_err +--L3_CSUM_ERR |
| 35 | * |
| 36 | * ex) pkt_hdr 0x00680820 |
| 37 | * drop_err, crc_err: none |
| 38 | * pkt_length = 104 byte |
| 39 | * 0x0820 = 0000 1000 0010 0000 => ipv4 icmp |
| 40 | * |
| 41 | * ex) pkt_hdr 0x004c8800 |
| 42 | * drop_err, crc_err: none |
| 43 | * pkt_length = 76 byte |
| 44 | * 0x8800 = 1000 1000 0000 0000 => ipv6 mcast icmp |
| 45 | * |
| 46 | * [memo] |
| 47 | * 0x0820: ipv4 icmp 0000 1000 0010 0000 |
| 48 | * 0x8820: ipv4 icmp (broadcast) 1000 1000 0010 0000 |
| 49 | * 0x0824: ipv4 udp (nping) 0000 1000 0010 0100 |
| 50 | * 0x0830: ipv4 tcp (ssh) 0000 1000 0011 0000 |
| 51 | * |
| 52 | * 0x0800: ipv6 icmp 0000 1000 0000 0000 |
| 53 | * 0x8800: ipv6 icmp (multicast) 1000 1000 0000 0000 |
| 54 | * 0x8844: ipv6 UDP/MDNS mcast 1000 1000 0100 0100 |
| 55 | * 0x0850: ipv6 tcp (ssh) 0000 1000 0101 0000 |
| 56 | */ |
| 57 | |
| 58 | #define AXEN_RXHDR_CRC_ERR (1 << 31) |
| 59 | #define AXEN_RXHDR_DROP_ERR (1 << 30) |
| 60 | #define AXEN_RXHDR_MCAST (1 << 15) |
| 61 | #define AXEN_RXHDR_RX_OK (1 << 11) |
| 62 | #define AXEN_RXHDR_L3_ERR (1 << 9) |
| 63 | #define AXEN_RXHDR_L4_ERR (1 << 8) |
| 64 | #define AXEN_RXHDR_L3CSUM_ERR (1 << 1) |
| 65 | #define AXEN_RXHDR_L4CSUM_ERR (1 << 0) |
| 66 | |
| 67 | /* L4 packet type (3bit) */ |
| 68 | #define AXEN_RXHDR_L4_TYPE_MASK 0x0000001c |
| 69 | #define AXEN_RXHDR_L4_TYPE_OFFSET 2 |
| 70 | #define AXEN_RXHDR_L4_TYPE_ICMP 0x0 |
| 71 | #define AXEN_RXHDR_L4_TYPE_UDP 0x1 |
| 72 | #define AXEN_RXHDR_L4_TYPE_TCP 0x4 |
| 73 | |
| 74 | /* L3 packet type (2bit) */ |
| 75 | #define AXEN_RXHDR_L3_TYPE_MASK 0x00000600 |
| 76 | #define AXEN_RXHDR_L3_TYPE_OFFSET 5 |
| 77 | #define AXEN_RXHDR_L3_TYPE_UNDEF 0x0 |
| 78 | #define AXEN_RXHDR_L3_TYPE_IPV4 0x1 |
| 79 | #define AXEN_RXHDR_L3_TYPE_IPV6 0x2 |
| 80 | |
| 81 | /* |
| 82 | * commands |
| 83 | */ |
| 84 | #define AXEN_CMD_LEN(x) (((x) & 0xF000) >> 12) |
| 85 | #define AXEN_CMD_DIR(x) (((x) & 0x0F00) >> 8) |
| 86 | #define AXEN_CMD_CMD(x) ((x) & 0x00FF) |
| 87 | |
| 88 | /* ---MAC--- */ |
| 89 | /* 1byte cmd */ |
| 90 | #define AXEN_CMD_MAC_READ 0x1001 |
| 91 | #define AXEN_CMD_MAC_WRITE 0x1101 |
| 92 | |
| 93 | #define AXEN_USB_UPLINK 0x02 |
| 94 | #define AXEN_USB_FS 0x01 |
| 95 | #define AXEN_USB_HS 0x02 |
| 96 | #define AXEN_USB_SS 0x04 |
| 97 | #define AXEN_GENERAL_STATUS 0x03 |
| 98 | #define AXEN_GENERAL_STATUS_MASK 0x4 |
| 99 | #define AXEN_REV0 0x0 |
| 100 | #define AXEN_REV1 0x4 |
| 101 | #define AXEN_UNK_05 0x05 |
| 102 | #define AXEN_MAC_EEPROM_ADDR 0x07 |
| 103 | #define AXEN_MAC_EEPROM_READ 0x08 |
| 104 | #define AXEN_MAC_EEPROM_CMD 0x0a |
| 105 | #define AXEN_EEPROM_READ 0x04 |
| 106 | #define AXEN_EEPROM_WRITE 0x08 |
| 107 | #define AXEN_EEPROM_BUSY 0x10 |
| 108 | #define AXEN_MONITOR_MODE 0x24 |
| 109 | #define AXEN_MONITOR_NONE 0x00 |
| 110 | #define AXEN_MONITOR_RWLC 0x02 |
| 111 | #define AXEN_MONITOR_RWMP 0x04 |
| 112 | #define AXEN_MONITOR_RWWF 0x08 |
| 113 | #define AXEN_MONITOR_RW_FLAG 0x10 |
| 114 | #define AXEN_MONITOR_PMEPOL 0x20 |
| 115 | #define AXEN_MONITOR_PMETYPE 0x40 |
| 116 | #define AXEN_UNK_28 0x28 |
| 117 | #define AXEN_PHYCLK 0x33 |
| 118 | #define AXEN_PHYCLK_BCS 0x01 |
| 119 | #define AXEN_PHYCLK_ACS 0x02 |
| 120 | #define AXEN_PHYCLK_ULR 0x08 |
| 121 | #define AXEN_PHYCLK_ACSREQ 0x10 |
| 122 | #define AXEN_RX_COE 0x34 |
| 123 | #define AXEN_RXCOE_OFF 0x00 |
| 124 | #define AXEN_RXCOE_IPv4 0x01 |
| 125 | #define AXEN_RXCOE_TCPv4 0x02 |
| 126 | #define AXEN_RXCOE_UDPv4 0x04 |
| 127 | #define AXEN_RXCOE_ICMP 0x08 |
| 128 | #define AXEN_RXCOE_IGMP 0x10 |
| 129 | #define AXEN_RXCOE_TCPv6 0x20 |
| 130 | #define AXEN_RXCOE_UDPv6 0x40 |
| 131 | #define AXEN_RXCOE_ICMPv6 0x80 |
| 132 | #define AXEN_TX_COE 0x35 |
| 133 | #define AXEN_TXCOE_OFF 0x00 |
| 134 | #define AXEN_TXCOE_IPv4 0x01 |
| 135 | #define AXEN_TXCOE_TCPv4 0x02 |
| 136 | #define AXEN_TXCOE_UDPv4 0x04 |
| 137 | #define AXEN_TXCOE_ICMP 0x08 |
| 138 | #define AXEN_TXCOE_IGMP 0x10 |
| 139 | #define AXEN_TXCOE_TCPv6 0x20 |
| 140 | #define AXEN_TXCOE_UDPv6 0x40 |
| 141 | #define AXEN_TXCOE_ICMPv6 0x80 |
| 142 | #define AXEN_PAUSE_HIGH_WATERMARK 0x54 |
| 143 | #define AXEN_PAUSE_LOW_WATERMARK 0x55 |
| 144 | |
| 145 | |
| 146 | /* 2byte cmd */ |
| 147 | #define AXEN_CMD_MAC_READ2 0x2001 |
| 148 | #define AXEN_CMD_MAC_WRITE2 0x2101 |
| 149 | |
| 150 | #define AXEN_MAC_RXCTL 0x0b |
| 151 | #define AXEN_RXCTL_STOP 0x0000 |
| 152 | #define AXEN_RXCTL_PROMISC 0x0001 |
| 153 | #define AXEN_RXCTL_ACPT_ALL_MCAST 0x0002 |
| 154 | #define AXEN_RXCTL_HA8B 0x0004 |
| 155 | #define AXEN_RXCTL_AUTOB 0x0008 |
| 156 | #define AXEN_RXCTL_ACPT_BCAST 0x0010 |
| 157 | #define AXEN_RXCTL_ACPT_PHY_MCAST 0x0020 |
| 158 | #define AXEN_RXCTL_START 0x0080 |
| 159 | #define AXEN_RXCTL_DROPCRCERR 0x0100 |
| 160 | #define AXEN_RXCTL_IPE 0x0200 |
| 161 | #define AXEN_RXCTL_TXPADCRC 0x0400 |
| 162 | #define AXEN_MEDIUM_STATUS 0x22 |
| 163 | #define AXEN_MEDIUM_NONE 0x0000 |
| 164 | #define AXEN_MEDIUM_GIGA 0x0001 |
| 165 | #define AXEN_MEDIUM_FDX 0x0002 |
| 166 | #define AXEN_MEDIUM_ALWAYS_ONE 0x0004 |
| 167 | #define AXEN_MEDIUM_EN_125MHZ 0x0008 |
| 168 | #define AXEN_MEDIUM_RXFLOW_CTRL_EN 0x0010 |
| 169 | #define AXEN_MEDIUM_TXFLOW_CTRL_EN 0x0020 |
| 170 | #define AXEN_MEDIUM_RECV_EN 0x0100 |
| 171 | #define AXEN_MEDIUM_PS 0x0200 |
| 172 | #define AXEN_MEDIUM_JUMBO_EN 0x8040 |
| 173 | #define AXEN_PHYPWR_RSTCTL 0x26 |
| 174 | #define AXEN_PHYPWR_RSTCTL_BZ 0x0010 |
| 175 | #define AXEN_PHYPWR_RSTCTL_IPRL 0x0020 |
| 176 | #define AXEN_PHYPWR_RSTCTL_AUTODETACH 0x1000 |
| 177 | |
| 178 | #define AXEN_CMD_EEPROM_READ 0x2004 |
| 179 | #define AXEN_EEPROM_STAT 0x43 |
| 180 | |
| 181 | /* 5byte cmd */ |
| 182 | #define AXEN_CMD_MAC_SET_RXSR 0x5101 |
| 183 | #define AXEN_RX_BULKIN_QCTRL 0x2e |
| 184 | |
| 185 | /* 6byte cmd */ |
| 186 | #define AXEN_CMD_MAC_READ_ETHER 0x6001 |
| 187 | #define AXEN_CMD_MAC_NODE_ID 0x10 |
| 188 | |
| 189 | /* 8byte cmd */ |
| 190 | #define AXEN_CMD_MAC_READ_FILTER 0x8001 |
| 191 | #define AXEN_CMD_MAC_WRITE_FILTER 0x8101 |
| 192 | #define AXEN_FILTER_MULTI 0x16 |
| 193 | |
| 194 | /* ---PHY--- */ |
| 195 | /* 2byte cmd */ |
| 196 | #define AXEN_CMD_MII_READ_REG 0x2002 |
| 197 | #define AXEN_CMD_MII_WRITE_REG 0x2102 |
| 198 | |
| 199 | |
| 200 | |
| 201 | /* ========= */ |
| 202 | #define AXEN_GPIO0_EN 0x01 |
| 203 | #define AXEN_GPIO0 0x02 |
| 204 | #define AXEN_GPIO1_EN 0x04 |
| 205 | #define AXEN_GPIO1 0x08 |
| 206 | #define AXEN_GPIO2_EN 0x10 |
| 207 | #define AXEN_GPIO2 0x20 |
| 208 | #define AXEN_GPIO_RELOAD_EEPROM 0x80 |
| 209 | |
| 210 | |
| 211 | #define AXEN_TIMEOUT 1000 |
| 212 | |
| 213 | #define AXEN_RX_LIST_CNT 1 |
| 214 | #define AXEN_TX_LIST_CNT 1 |
| 215 | |
| 216 | |
| 217 | #define AXEN_CONFIG_NO 1 |
| 218 | #define AXEN_IFACE_IDX 0 |
| 219 | |
| 220 | /* |
| 221 | * The interrupt endpoint is currently unused |
| 222 | * by the ASIX part. |
| 223 | */ |
| 224 | #define AXEN_ENDPT_RX 0x0 |
| 225 | #define AXEN_ENDPT_TX 0x1 |
| 226 | #define AXEN_ENDPT_INTR 0x2 |
| 227 | #define AXEN_ENDPT_MAX 0x3 |
| 228 | |
| 229 | struct axen_type { |
| 230 | struct usb_devno axen_dev; |
| 231 | uint16_t axen_flags; |
| 232 | #define AX178A 0x0001 /* AX88178a */ |
| 233 | #define AX179 0x0002 /* AX88179 */ |
| 234 | }; |
| 235 | |
| 236 | struct axen_softc; |
| 237 | |
| 238 | struct axen_chain { |
| 239 | struct axen_softc *axen_sc; |
| 240 | struct usbd_xfer *axen_xfer; |
| 241 | uint8_t *axen_buf; |
| 242 | int axen_accum; |
| 243 | int axen_idx; |
| 244 | }; |
| 245 | |
| 246 | struct axen_cdata { |
| 247 | struct axen_chain axen_tx_chain[AXEN_TX_LIST_CNT]; |
| 248 | struct axen_chain axen_rx_chain[AXEN_RX_LIST_CNT]; |
| 249 | int axen_tx_prod; |
| 250 | int axen_tx_cons; |
| 251 | int axen_tx_cnt; |
| 252 | int axen_rx_prod; |
| 253 | }; |
| 254 | |
| 255 | struct axen_qctrl { |
| 256 | uint8_t ctrl; |
| 257 | uint8_t timer_low; |
| 258 | uint8_t timer_high; |
| 259 | uint8_t bufsize; |
| 260 | uint8_t ifg; |
| 261 | } __packed; |
| 262 | |
| 263 | struct axen_sframe_hdr { |
| 264 | uint32_t plen; /* packet length */ |
| 265 | uint32_t gso; |
| 266 | } __packed; |
| 267 | |
| 268 | struct axen_softc { |
| 269 | device_t axen_dev; |
| 270 | struct ethercom axen_ec; |
| 271 | struct mii_data axen_mii; |
| 272 | krndsource_t rnd_source; |
| 273 | struct usbd_device * axen_udev; |
| 274 | struct usbd_interface * axen_iface; |
| 275 | |
| 276 | uint16_t axen_vendor; |
| 277 | uint16_t axen_product; |
| 278 | uint16_t axen_flags; |
| 279 | |
| 280 | int axen_ed[AXEN_ENDPT_MAX]; |
| 281 | struct usbd_pipe *axen_ep[AXEN_ENDPT_MAX]; |
| 282 | int axen_if_flags; |
| 283 | struct axen_cdata axen_cdata; |
| 284 | struct callout axen_stat_ch; |
| 285 | |
| 286 | int axen_refcnt; |
| 287 | bool axen_dying; |
| 288 | bool axen_attached; |
| 289 | |
| 290 | struct usb_task axen_tick_task; |
| 291 | |
| 292 | krwlock_t axen_mii_lock; |
| 293 | |
| 294 | int axen_link; |
| 295 | |
| 296 | uint8_t axen_ipgs[3]; |
| 297 | int axen_phyno; |
| 298 | struct timeval axen_rx_notice; |
| 299 | u_int axen_bufsz; |
| 300 | int axen_rev; |
| 301 | |
| 302 | #define sc_if axen_ec.ec_if |
| 303 | }; |
| 304 | |
| 305 | #define GET_MII(sc) (&(sc)->axen_mii) |
| 306 | #define GET_IFP(sc) (&(sc)->sc_if) |
| 307 | |
| 308 | #define ETHER_ALIGN 2 |
| 309 | |