| 1 | Index: sys/dev/usb/usbdevs
|
---|
| 2 | ===================================================================
|
---|
| 3 | --- sys/dev/usb/usbdevs (revision 224736)
|
---|
| 4 | +++ sys/dev/usb/usbdevs (working copy)
|
---|
| 5 | @@ -1044,6 +1044,7 @@
|
---|
| 6 | product ASIX AX88178 0x1780 AX88178
|
---|
| 7 | product ASIX AX88772 0x7720 AX88772
|
---|
| 8 | product ASIX AX88772A 0x772a AX88772A USB 2.0 10/100 Ethernet
|
---|
| 9 | +product ASIX AX88772B 0x772b AX88772B USB 2.0 10/100 Ethernet
|
---|
| 10 |
|
---|
| 11 | /* ASUS products */
|
---|
| 12 | product ASUS2 USBN11 0x0b05 USB-N11
|
---|
| 13 | Index: sys/dev/usb/net/if_axereg.h
|
---|
| 14 | ===================================================================
|
---|
| 15 | --- sys/dev/usb/net/if_axereg.h (revision 224736)
|
---|
| 16 | +++ sys/dev/usb/net/if_axereg.h (working copy)
|
---|
| 17 | @@ -92,6 +92,12 @@
|
---|
| 18 | #define AXE_CMD_SW_PHY_STATUS 0x0021
|
---|
| 19 | #define AXE_CMD_SW_PHY_SELECT 0x0122
|
---|
| 20 |
|
---|
| 21 | +/* AX88772A and AX88772B only. */
|
---|
| 22 | +#define AXE_CMD_READ_VLAN_CTRL 0x4027
|
---|
| 23 | +#define AXE_CMD_WRITE_VLAN_CTRL 0x4028
|
---|
| 24 | +
|
---|
| 25 | +#define AXE_772B_CMD_RXCTL_WRITE_CFG 0x012A
|
---|
| 26 | +
|
---|
| 27 | #define AXE_SW_RESET_CLEAR 0x00
|
---|
| 28 | #define AXE_SW_RESET_RR 0x01
|
---|
| 29 | #define AXE_SW_RESET_RT 0x02
|
---|
| 30 | @@ -128,12 +134,18 @@
|
---|
| 31 | #define AXE_178_RXCMD_KEEP_INVALID_CRC 0x0004
|
---|
| 32 | #define AXE_RXCMD_BROADCAST 0x0008
|
---|
| 33 | #define AXE_RXCMD_MULTICAST 0x0010
|
---|
| 34 | +#define AXE_RXCMD_ACCEPT_RUNT 0x0040 /* AX88772B */
|
---|
| 35 | #define AXE_RXCMD_ENABLE 0x0080
|
---|
| 36 | #define AXE_178_RXCMD_MFB_MASK 0x0300
|
---|
| 37 | #define AXE_178_RXCMD_MFB_2048 0x0000
|
---|
| 38 | #define AXE_178_RXCMD_MFB_4096 0x0100
|
---|
| 39 | #define AXE_178_RXCMD_MFB_8192 0x0200
|
---|
| 40 | #define AXE_178_RXCMD_MFB_16384 0x0300
|
---|
| 41 | +#define AXE_772B_RXCMD_HDR_TYPE_0 0x0000
|
---|
| 42 | +#define AXE_772B_RXCMD_HDR_TYPE_1 0x0100
|
---|
| 43 | +#define AXE_772B_RXCMD_IPHDR_ALIGN 0x0200
|
---|
| 44 | +#define AXE_772B_RXCMD_ADD_CHKSUM 0x0400
|
---|
| 45 | +#define AXE_RXCMD_LOOPBACK 0x1000 /* AX88772A/AX88772B */
|
---|
| 46 |
|
---|
| 47 | #define AXE_PHY_SEL_PRI 1
|
---|
| 48 | #define AXE_PHY_SEL_SEC 0
|
---|
| 49 | @@ -172,6 +184,21 @@
|
---|
| 50 | #define AXE_PHY_MODE_REALTEK_8251CL 0x0E
|
---|
| 51 | #define AXE_PHY_MODE_ATTANSIC 0x40
|
---|
| 52 |
|
---|
| 53 | +/* AX88772A/AX88772B only. */
|
---|
| 54 | +#define AXE_SW_PHY_SELECT_EXT 0x0000
|
---|
| 55 | +#define AXE_SW_PHY_SELECT_EMBEDDED 0x0001
|
---|
| 56 | +#define AXE_SW_PHY_SELECT_AUTO 0x0002
|
---|
| 57 | +#define AXE_SW_PHY_SELECT_SS_MII 0x0004
|
---|
| 58 | +#define AXE_SW_PHY_SELECT_SS_RVRS_MII 0x0008
|
---|
| 59 | +#define AXE_SW_PHY_SELECT_SS_RVRS_RMII 0x000C
|
---|
| 60 | +#define AXE_SW_PHY_SELECT_SS_ENB 0x0010
|
---|
| 61 | +
|
---|
| 62 | +/* AX88772A/AX88772B VLAN control. */
|
---|
| 63 | +#define AXE_VLAN_CTRL_ENB 0x00001000
|
---|
| 64 | +#define AXE_VLAN_CTRL_STRIP 0x00002000
|
---|
| 65 | +#define AXE_VLAN_CTRL_VID1_MASK 0x00000FFF
|
---|
| 66 | +#define AXE_VLAN_CTRL_VID2_MASK 0x0FFF0000
|
---|
| 67 | +
|
---|
| 68 | #define AXE_BULK_BUF_SIZE 16384 /* bytes */
|
---|
| 69 |
|
---|
| 70 | #define AXE_CTL_READ 0x01
|
---|
| 71 | @@ -180,6 +207,24 @@
|
---|
| 72 | #define AXE_CONFIG_IDX 0 /* config number 1 */
|
---|
| 73 | #define AXE_IFACE_IDX 0
|
---|
| 74 |
|
---|
| 75 | +/* EEPROM Map. */
|
---|
| 76 | +#define AXE_EEPROM_772B_NODE_ID 0x04
|
---|
| 77 | +#define AXE_EEPROM_772B_PHY_PWRCFG 0x18
|
---|
| 78 | +
|
---|
| 79 | +struct ax88772b_mfb {
|
---|
| 80 | + int byte_cnt;
|
---|
| 81 | + int threshold;
|
---|
| 82 | + int size;
|
---|
| 83 | +};
|
---|
| 84 | +#define AX88772B_MFB_2K 0
|
---|
| 85 | +#define AX88772B_MFB_4K 1
|
---|
| 86 | +#define AX88772B_MFB_6K 2
|
---|
| 87 | +#define AX88772B_MFB_8K 3
|
---|
| 88 | +#define AX88772B_MFB_16K 4
|
---|
| 89 | +#define AX88772B_MFB_20K 5
|
---|
| 90 | +#define AX88772B_MFB_24K 6
|
---|
| 91 | +#define AX88772B_MFB_32K 7
|
---|
| 92 | +
|
---|
| 93 | struct axe_sframe_hdr {
|
---|
| 94 | uint16_t len;
|
---|
| 95 | uint16_t ilen;
|
---|
| 96 | @@ -203,12 +248,23 @@
|
---|
| 97 | int sc_flags;
|
---|
| 98 | #define AXE_FLAG_LINK 0x0001
|
---|
| 99 | #define AXE_FLAG_772 0x1000 /* AX88772 */
|
---|
| 100 | -#define AXE_FLAG_178 0x2000 /* AX88178 */
|
---|
| 101 | +#define AXE_FLAG_772A 0x2000 /* AX88772A */
|
---|
| 102 | +#define AXE_FLAG_772B 0x4000 /* AX88772B */
|
---|
| 103 | +#define AXE_FLAG_178 0x8000 /* AX88178 */
|
---|
| 104 |
|
---|
| 105 | uint8_t sc_ipgs[3];
|
---|
| 106 | uint8_t sc_phyaddrs[2];
|
---|
| 107 | + uint16_t sc_pwrcfg;
|
---|
| 108 | + int sc_tx_bufsz;
|
---|
| 109 | };
|
---|
| 110 |
|
---|
| 111 | +#define AXE_IS_178_FAMILY(sc) \
|
---|
| 112 | + ((sc)->sc_flags & (AXE_FLAG_772 | AXE_FLAG_772A | AXE_FLAG_772B | \
|
---|
| 113 | + AXE_FLAG_178))
|
---|
| 114 | +
|
---|
| 115 | +#define AXE_IS_772(sc) \
|
---|
| 116 | + ((sc)->sc_flags & (AXE_FLAG_772 | AXE_FLAG_772A | AXE_FLAG_772B))
|
---|
| 117 | +
|
---|
| 118 | #define AXE_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
|
---|
| 119 | #define AXE_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
|
---|
| 120 | #define AXE_LOCK_ASSERT(_sc, t) mtx_assert(&(_sc)->sc_mtx, t)
|
---|
| 121 | Index: sys/dev/usb/net/if_axe.c
|
---|
| 122 | ===================================================================
|
---|
| 123 | --- sys/dev/usb/net/if_axe.c (revision 224736)
|
---|
| 124 | +++ sys/dev/usb/net/if_axe.c (working copy)
|
---|
| 125 | @@ -84,7 +84,6 @@
|
---|
| 126 | #include <sys/systm.h>
|
---|
| 127 | #include <sys/kernel.h>
|
---|
| 128 | #include <sys/bus.h>
|
---|
| 129 | -#include <sys/linker_set.h>
|
---|
| 130 | #include <sys/module.h>
|
---|
| 131 | #include <sys/lock.h>
|
---|
| 132 | #include <sys/mutex.h>
|
---|
| 133 | @@ -142,11 +141,12 @@
|
---|
| 134 | AXE_DEV(ASIX, AX88172, 0),
|
---|
| 135 | AXE_DEV(ASIX, AX88178, AXE_FLAG_178),
|
---|
| 136 | AXE_DEV(ASIX, AX88772, AXE_FLAG_772),
|
---|
| 137 | - AXE_DEV(ASIX, AX88772A, AXE_FLAG_772),
|
---|
| 138 | + AXE_DEV(ASIX, AX88772A, AXE_FLAG_772A),
|
---|
| 139 | + AXE_DEV(ASIX, AX88772B, AXE_FLAG_772B),
|
---|
| 140 | AXE_DEV(ATEN, UC210T, 0),
|
---|
| 141 | AXE_DEV(BELKIN, F5D5055, AXE_FLAG_178),
|
---|
| 142 | AXE_DEV(BILLIONTON, USB2AR, 0),
|
---|
| 143 | - AXE_DEV(CISCOLINKSYS, USB200MV2, AXE_FLAG_772),
|
---|
| 144 | + AXE_DEV(CISCOLINKSYS, USB200MV2, AXE_FLAG_772A),
|
---|
| 145 | AXE_DEV(COREGA, FETHER_USB2_TX, 0),
|
---|
| 146 | AXE_DEV(DLINK, DUBE100, 0),
|
---|
| 147 | AXE_DEV(DLINK, DUBE100B1, AXE_FLAG_772),
|
---|
| 148 | @@ -191,6 +191,9 @@
|
---|
| 149 | static int axe_cmd(struct axe_softc *, int, int, int, void *);
|
---|
| 150 | static void axe_ax88178_init(struct axe_softc *);
|
---|
| 151 | static void axe_ax88772_init(struct axe_softc *);
|
---|
| 152 | +static void axe_ax88772_phywake(struct axe_softc *);
|
---|
| 153 | +static void axe_ax88772a_init(struct axe_softc *);
|
---|
| 154 | +static void axe_ax88772b_init(struct axe_softc *);
|
---|
| 155 | static int axe_get_phyno(struct axe_softc *, int);
|
---|
| 156 |
|
---|
| 157 | static const struct usb_config axe_config[AXE_N_TRANSFER] = {
|
---|
| 158 | @@ -199,7 +202,8 @@
|
---|
| 159 | .type = UE_BULK,
|
---|
| 160 | .endpoint = UE_ADDR_ANY,
|
---|
| 161 | .direction = UE_DIR_OUT,
|
---|
| 162 | - .bufsize = AXE_BULK_BUF_SIZE,
|
---|
| 163 | + .frames = 16,
|
---|
| 164 | + .bufsize = 16 * MCLBYTES,
|
---|
| 165 | .flags = {.pipe_bof = 1,.force_short_xfer = 1,},
|
---|
| 166 | .callback = axe_bulk_write_callback,
|
---|
| 167 | .timeout = 10000, /* 10 seconds */
|
---|
| 168 | @@ -216,6 +220,17 @@
|
---|
| 169 | },
|
---|
| 170 | };
|
---|
| 171 |
|
---|
| 172 | +static const struct ax88772b_mfb ax88772b_mfb_table[] = {
|
---|
| 173 | + { 0x8000, 0x8001, 2048 },
|
---|
| 174 | + { 0x8100, 0x8147, 4096},
|
---|
| 175 | + { 0x8200, 0x81EB, 6144},
|
---|
| 176 | + { 0x8300, 0x83D7, 8192},
|
---|
| 177 | + { 0x8400, 0x851E, 16384},
|
---|
| 178 | + { 0x8500, 0x8666, 20480},
|
---|
| 179 | + { 0x8600, 0x87AE, 24576},
|
---|
| 180 | + { 0x8700, 0x8A3D, 32768}
|
---|
| 181 | +};
|
---|
| 182 | +
|
---|
| 183 | static device_method_t axe_methods[] = {
|
---|
| 184 | /* Device interface */
|
---|
| 185 | DEVMETHOD(device_probe, axe_probe),
|
---|
| 186 | @@ -302,7 +317,7 @@
|
---|
| 187 | axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL);
|
---|
| 188 |
|
---|
| 189 | val = le16toh(val);
|
---|
| 190 | - if ((sc->sc_flags & AXE_FLAG_772) != 0 && reg == MII_BMSR) {
|
---|
| 191 | + if (AXE_IS_772(sc) && reg == MII_BMSR) {
|
---|
| 192 | /*
|
---|
| 193 | * BMSR of AX88772 indicates that it supports extended
|
---|
| 194 | * capability but the extended status register is
|
---|
| 195 | @@ -384,7 +399,7 @@
|
---|
| 196 | val = 0;
|
---|
| 197 | if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0)
|
---|
| 198 | val |= AXE_MEDIA_FULL_DUPLEX;
|
---|
| 199 | - if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772)) {
|
---|
| 200 | + if (AXE_IS_178_FAMILY(sc)) {
|
---|
| 201 | val |= AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC;
|
---|
| 202 | if ((sc->sc_flags & AXE_FLAG_178) != 0)
|
---|
| 203 | val |= AXE_178_MEDIA_ENCK;
|
---|
| 204 | @@ -420,12 +435,12 @@
|
---|
| 205 |
|
---|
| 206 | AXE_LOCK_ASSERT(sc, MA_OWNED);
|
---|
| 207 |
|
---|
| 208 | - if (mii->mii_instance) {
|
---|
| 209 | - struct mii_softc *miisc;
|
---|
| 210 | + if (mii->mii_instance) {
|
---|
| 211 | + struct mii_softc *miisc;
|
---|
| 212 |
|
---|
| 213 | - LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
|
---|
| 214 | - mii_phy_reset(miisc);
|
---|
| 215 | - }
|
---|
| 216 | + LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
|
---|
| 217 | + mii_phy_reset(miisc);
|
---|
| 218 | + }
|
---|
| 219 | error = mii_mediachg(mii);
|
---|
| 220 | return (error);
|
---|
| 221 | }
|
---|
| 222 | @@ -516,7 +531,7 @@
|
---|
| 223 | axe_ax88178_init(struct axe_softc *sc)
|
---|
| 224 | {
|
---|
| 225 | struct usb_ether *ue;
|
---|
| 226 | - int gpio0, phymode;
|
---|
| 227 | + int gpio0, ledmode, phymode;
|
---|
| 228 | uint16_t eeprom, val;
|
---|
| 229 |
|
---|
| 230 | ue = &sc->sc_ue;
|
---|
| 231 | @@ -530,14 +545,17 @@
|
---|
| 232 | if (eeprom == 0xffff) {
|
---|
| 233 | phymode = AXE_PHY_MODE_MARVELL;
|
---|
| 234 | gpio0 = 1;
|
---|
| 235 | + ledmode = 0;
|
---|
| 236 | } else {
|
---|
| 237 | phymode = eeprom & 0x7f;
|
---|
| 238 | gpio0 = (eeprom & 0x80) ? 0 : 1;
|
---|
| 239 | + ledmode = eeprom >> 8;
|
---|
| 240 | }
|
---|
| 241 |
|
---|
| 242 | if (bootverbose)
|
---|
| 243 | - device_printf(sc->sc_ue.ue_dev, "EEPROM data : 0x%04x\n",
|
---|
| 244 | - eeprom);
|
---|
| 245 | + device_printf(sc->sc_ue.ue_dev,
|
---|
| 246 | + "EEPROM data : 0x%04x, phymode : 0x%02x\n", eeprom,
|
---|
| 247 | + phymode);
|
---|
| 248 | /* Program GPIOs depending on PHY hardware. */
|
---|
| 249 | switch (phymode) {
|
---|
| 250 | case AXE_PHY_MODE_MARVELL:
|
---|
| 251 | @@ -549,11 +567,26 @@
|
---|
| 252 | AXE_GPIO_WRITE(AXE_GPIO0_EN | AXE_GPIO2_EN, hz / 4);
|
---|
| 253 | AXE_GPIO_WRITE(AXE_GPIO0_EN | AXE_GPIO2 | AXE_GPIO2_EN,
|
---|
| 254 | hz / 32);
|
---|
| 255 | - } else
|
---|
| 256 | + } else {
|
---|
| 257 | AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO1 |
|
---|
| 258 | - AXE_GPIO1_EN, hz / 32);
|
---|
| 259 | + AXE_GPIO1_EN, hz / 3);
|
---|
| 260 | + if (ledmode == 1) {
|
---|
| 261 | + AXE_GPIO_WRITE(AXE_GPIO1_EN, hz / 3);
|
---|
| 262 | + AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN,
|
---|
| 263 | + hz / 3);
|
---|
| 264 | + } else {
|
---|
| 265 | + AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN |
|
---|
| 266 | + AXE_GPIO2 | AXE_GPIO2_EN, hz / 32);
|
---|
| 267 | + AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN |
|
---|
| 268 | + AXE_GPIO2_EN, hz / 4);
|
---|
| 269 | + AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN |
|
---|
| 270 | + AXE_GPIO2 | AXE_GPIO2_EN, hz / 32);
|
---|
| 271 | + }
|
---|
| 272 | + }
|
---|
| 273 | break;
|
---|
| 274 | case AXE_PHY_MODE_CICADA:
|
---|
| 275 | + case AXE_PHY_MODE_CICADA_V2:
|
---|
| 276 | + case AXE_PHY_MODE_CICADA_V2_ASIX:
|
---|
| 277 | if (gpio0 == 1)
|
---|
| 278 | AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO0 |
|
---|
| 279 | AXE_GPIO0_EN, hz / 32);
|
---|
| 280 | @@ -610,7 +643,6 @@
|
---|
| 281 |
|
---|
| 282 | axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
|
---|
| 283 | }
|
---|
| 284 | -#undef AXE_GPIO_WRITE
|
---|
| 285 |
|
---|
| 286 | static void
|
---|
| 287 | axe_ax88772_init(struct axe_softc *sc)
|
---|
| 288 | @@ -654,6 +686,91 @@
|
---|
| 289 | }
|
---|
| 290 |
|
---|
| 291 | static void
|
---|
| 292 | +axe_ax88772_phywake(struct axe_softc *sc)
|
---|
| 293 | +{
|
---|
| 294 | + struct usb_ether *ue;
|
---|
| 295 | +
|
---|
| 296 | + ue = &sc->sc_ue;
|
---|
| 297 | + if (sc->sc_phyno == AXE_772_PHY_NO_EPHY) {
|
---|
| 298 | + /* Manually select internal(embedded) PHY - MAC mode. */
|
---|
| 299 | + axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, AXE_SW_PHY_SELECT_SS_ENB |
|
---|
| 300 | + AXE_SW_PHY_SELECT_EMBEDDED | AXE_SW_PHY_SELECT_SS_MII,
|
---|
| 301 | + NULL);
|
---|
| 302 | + uether_pause(&sc->sc_ue, hz / 32);
|
---|
| 303 | + } else {
|
---|
| 304 | + /*
|
---|
| 305 | + * Manually select external PHY - MAC mode.
|
---|
| 306 | + * Reverse MII/RMII is for AX88772A PHY mode.
|
---|
| 307 | + */
|
---|
| 308 | + axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, AXE_SW_PHY_SELECT_SS_ENB |
|
---|
| 309 | + AXE_SW_PHY_SELECT_EXT | AXE_SW_PHY_SELECT_SS_MII, NULL);
|
---|
| 310 | + uether_pause(&sc->sc_ue, hz / 32);
|
---|
| 311 | + }
|
---|
| 312 | + /* Take PHY out of power down. */
|
---|
| 313 | + axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPPD |
|
---|
| 314 | + AXE_SW_RESET_IPRL, NULL);
|
---|
| 315 | + uether_pause(&sc->sc_ue, hz / 4);
|
---|
| 316 | + axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPRL, NULL);
|
---|
| 317 | + uether_pause(&sc->sc_ue, hz);
|
---|
| 318 | + axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL);
|
---|
| 319 | + uether_pause(&sc->sc_ue, hz / 32);
|
---|
| 320 | + axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPRL, NULL);
|
---|
| 321 | + uether_pause(&sc->sc_ue, hz / 32);
|
---|
| 322 | +}
|
---|
| 323 | +
|
---|
| 324 | +static void
|
---|
| 325 | +axe_ax88772a_init(struct axe_softc *sc)
|
---|
| 326 | +{
|
---|
| 327 | + struct usb_ether *ue;
|
---|
| 328 | +
|
---|
| 329 | + ue = &sc->sc_ue;
|
---|
| 330 | + /* Reload EEPROM. */
|
---|
| 331 | + AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM, hz / 32);
|
---|
| 332 | + axe_ax88772_phywake(sc);
|
---|
| 333 | + /* Stop MAC. */
|
---|
| 334 | + axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
|
---|
| 335 | +}
|
---|
| 336 | +
|
---|
| 337 | +static void
|
---|
| 338 | +axe_ax88772b_init(struct axe_softc *sc)
|
---|
| 339 | +{
|
---|
| 340 | + struct usb_ether *ue;
|
---|
| 341 | + uint16_t eeprom;
|
---|
| 342 | + uint8_t *eaddr;
|
---|
| 343 | + int i;
|
---|
| 344 | +
|
---|
| 345 | + ue = &sc->sc_ue;
|
---|
| 346 | + /* Reload EEPROM. */
|
---|
| 347 | + AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM, hz / 32);
|
---|
| 348 | + /*
|
---|
| 349 | + * Save PHY power saving configuration(high byte) and
|
---|
| 350 | + * clear EEPROM checksum value(low byte).
|
---|
| 351 | + */
|
---|
| 352 | + axe_cmd(sc, AXE_CMD_SROM_READ, 0, AXE_EEPROM_772B_PHY_PWRCFG, &eeprom);
|
---|
| 353 | + sc->sc_pwrcfg = le16toh(eeprom) & 0xFF00;
|
---|
| 354 | +
|
---|
| 355 | + /*
|
---|
| 356 | + * Auto-loaded default station address from internal ROM is
|
---|
| 357 | + * 00:00:00:00:00:00 such that an explicit access to EEPROM
|
---|
| 358 | + * is required to get real station address.
|
---|
| 359 | + */
|
---|
| 360 | + eaddr = ue->ue_eaddr;
|
---|
| 361 | + for (i = 0; i < ETHER_ADDR_LEN / 2; i++) {
|
---|
| 362 | + axe_cmd(sc, AXE_CMD_SROM_READ, 0, AXE_EEPROM_772B_NODE_ID + i,
|
---|
| 363 | + &eeprom);
|
---|
| 364 | + eeprom = le16toh(eeprom);
|
---|
| 365 | + *eaddr++ = (uint8_t)(eeprom & 0xFF);
|
---|
| 366 | + *eaddr++ = (uint8_t)((eeprom >> 8) & 0xFF);
|
---|
| 367 | + }
|
---|
| 368 | + /* Wakeup PHY. */
|
---|
| 369 | + axe_ax88772_phywake(sc);
|
---|
| 370 | + /* Stop MAC. */
|
---|
| 371 | + axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
|
---|
| 372 | +}
|
---|
| 373 | +
|
---|
| 374 | +#undef AXE_GPIO_WRITE
|
---|
| 375 | +
|
---|
| 376 | +static void
|
---|
| 377 | axe_reset(struct axe_softc *sc)
|
---|
| 378 | {
|
---|
| 379 | struct usb_config_descriptor *cd;
|
---|
| 380 | @@ -668,6 +785,16 @@
|
---|
| 381 |
|
---|
| 382 | /* Wait a little while for the chip to get its brains in order. */
|
---|
| 383 | uether_pause(&sc->sc_ue, hz / 100);
|
---|
| 384 | +
|
---|
| 385 | + /* Reinitialize controller to achieve full reset. */
|
---|
| 386 | + if (sc->sc_flags & AXE_FLAG_178)
|
---|
| 387 | + axe_ax88178_init(sc);
|
---|
| 388 | + else if (sc->sc_flags & AXE_FLAG_772)
|
---|
| 389 | + axe_ax88772_init(sc);
|
---|
| 390 | + else if (sc->sc_flags & AXE_FLAG_772A)
|
---|
| 391 | + axe_ax88772a_init(sc);
|
---|
| 392 | + else if (sc->sc_flags & AXE_FLAG_772B)
|
---|
| 393 | + axe_ax88772b_init(sc);
|
---|
| 394 | }
|
---|
| 395 |
|
---|
| 396 | static void
|
---|
| 397 | @@ -691,23 +818,35 @@
|
---|
| 398 | sc->sc_phyno = 0;
|
---|
| 399 | }
|
---|
| 400 |
|
---|
| 401 | - if (sc->sc_flags & AXE_FLAG_178)
|
---|
| 402 | + /* Initialize controller and get station address. */
|
---|
| 403 | + if (sc->sc_flags & AXE_FLAG_178) {
|
---|
| 404 | axe_ax88178_init(sc);
|
---|
| 405 | - else if (sc->sc_flags & AXE_FLAG_772)
|
---|
| 406 | + sc->sc_tx_bufsz = 16 * 1024;
|
---|
| 407 | + axe_cmd(sc, AXE_178_CMD_READ_NODEID, 0, 0, ue->ue_eaddr);
|
---|
| 408 | + } else if (sc->sc_flags & AXE_FLAG_772) {
|
---|
| 409 | axe_ax88772_init(sc);
|
---|
| 410 | -
|
---|
| 411 | - /*
|
---|
| 412 | - * Get station address.
|
---|
| 413 | - */
|
---|
| 414 | - if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772))
|
---|
| 415 | + sc->sc_tx_bufsz = 8 * 1024;
|
---|
| 416 | axe_cmd(sc, AXE_178_CMD_READ_NODEID, 0, 0, ue->ue_eaddr);
|
---|
| 417 | - else
|
---|
| 418 | + } else if (sc->sc_flags & AXE_FLAG_772A) {
|
---|
| 419 | + axe_ax88772a_init(sc);
|
---|
| 420 | + sc->sc_tx_bufsz = 8 * 1024;
|
---|
| 421 | + axe_cmd(sc, AXE_178_CMD_READ_NODEID, 0, 0, ue->ue_eaddr);
|
---|
| 422 | + } else if (sc->sc_flags & AXE_FLAG_772B) {
|
---|
| 423 | + axe_ax88772b_init(sc);
|
---|
| 424 | + sc->sc_tx_bufsz = 8 * 1024;
|
---|
| 425 | + } else
|
---|
| 426 | axe_cmd(sc, AXE_172_CMD_READ_NODEID, 0, 0, ue->ue_eaddr);
|
---|
| 427 |
|
---|
| 428 | /*
|
---|
| 429 | * Fetch IPG values.
|
---|
| 430 | */
|
---|
| 431 | - axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, sc->sc_ipgs);
|
---|
| 432 | + if (sc->sc_flags & (AXE_FLAG_772A | AXE_FLAG_772B)) {
|
---|
| 433 | + /* Set IPG values. */
|
---|
| 434 | + sc->sc_ipgs[0] = 0x15;
|
---|
| 435 | + sc->sc_ipgs[1] = 0x16;
|
---|
| 436 | + sc->sc_ipgs[2] = 0x1A;
|
---|
| 437 | + } else
|
---|
| 438 | + axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, sc->sc_ipgs);
|
---|
| 439 | }
|
---|
| 440 |
|
---|
| 441 | /*
|
---|
| 442 | @@ -810,7 +949,7 @@
|
---|
| 443 | err = 0;
|
---|
| 444 |
|
---|
| 445 | pc = usbd_xfer_get_frame(xfer, 0);
|
---|
| 446 | - if (sc->sc_flags & (AXE_FLAG_772 | AXE_FLAG_178)) {
|
---|
| 447 | + if (AXE_IS_178_FAMILY(sc)) {
|
---|
| 448 | while (pos < actlen) {
|
---|
| 449 | if ((pos + sizeof(hdr)) > actlen) {
|
---|
| 450 | /* too little data */
|
---|
| 451 | @@ -875,7 +1014,7 @@
|
---|
| 452 | struct ifnet *ifp = uether_getifp(&sc->sc_ue);
|
---|
| 453 | struct usb_page_cache *pc;
|
---|
| 454 | struct mbuf *m;
|
---|
| 455 | - int pos;
|
---|
| 456 | + int nframes, pos;
|
---|
| 457 |
|
---|
| 458 | switch (USB_GET_STATE(xfer)) {
|
---|
| 459 | case USB_ST_TRANSFERRED:
|
---|
| 460 | @@ -892,40 +1031,34 @@
|
---|
| 461 | */
|
---|
| 462 | return;
|
---|
| 463 | }
|
---|
| 464 | - pos = 0;
|
---|
| 465 | - pc = usbd_xfer_get_frame(xfer, 0);
|
---|
| 466 |
|
---|
| 467 | - while (1) {
|
---|
| 468 | -
|
---|
| 469 | + for (nframes = 0; nframes < 16 &&
|
---|
| 470 | + !IFQ_DRV_IS_EMPTY(&ifp->if_snd); nframes++) {
|
---|
| 471 | IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
|
---|
| 472 | -
|
---|
| 473 | - if (m == NULL) {
|
---|
| 474 | - if (pos > 0)
|
---|
| 475 | - break; /* send out data */
|
---|
| 476 | - return;
|
---|
| 477 | - }
|
---|
| 478 | - if (m->m_pkthdr.len > MCLBYTES) {
|
---|
| 479 | - m->m_pkthdr.len = MCLBYTES;
|
---|
| 480 | - }
|
---|
| 481 | - if (sc->sc_flags & (AXE_FLAG_772 | AXE_FLAG_178)) {
|
---|
| 482 | -
|
---|
| 483 | + if (m == NULL)
|
---|
| 484 | + break;
|
---|
| 485 | + usbd_xfer_set_frame_offset(xfer, nframes * MCLBYTES,
|
---|
| 486 | + nframes);
|
---|
| 487 | + pos = 0;
|
---|
| 488 | + pc = usbd_xfer_get_frame(xfer, nframes);
|
---|
| 489 | + if (AXE_IS_178_FAMILY(sc)) {
|
---|
| 490 | hdr.len = htole16(m->m_pkthdr.len);
|
---|
| 491 | hdr.ilen = ~hdr.len;
|
---|
| 492 | -
|
---|
| 493 | usbd_copy_in(pc, pos, &hdr, sizeof(hdr));
|
---|
| 494 | -
|
---|
| 495 | pos += sizeof(hdr);
|
---|
| 496 | -
|
---|
| 497 | - /*
|
---|
| 498 | - * NOTE: Some drivers force a short packet
|
---|
| 499 | - * by appending a dummy header with zero
|
---|
| 500 | - * length at then end of the USB transfer.
|
---|
| 501 | - * This driver uses the
|
---|
| 502 | - * USB_FORCE_SHORT_XFER flag instead.
|
---|
| 503 | - */
|
---|
| 504 | + usbd_m_copy_in(pc, pos, m, 0, m->m_pkthdr.len);
|
---|
| 505 | + pos += m->m_pkthdr.len;
|
---|
| 506 | + if ((pos % 512) == 0) {
|
---|
| 507 | + hdr.len = 0;
|
---|
| 508 | + hdr.ilen = 0xffff;
|
---|
| 509 | + usbd_copy_in(pc, pos, &hdr,
|
---|
| 510 | + sizeof(hdr));
|
---|
| 511 | + pos += sizeof(hdr);
|
---|
| 512 | + }
|
---|
| 513 | + } else {
|
---|
| 514 | + usbd_m_copy_in(pc, pos, m, 0, m->m_pkthdr.len);
|
---|
| 515 | + pos += m->m_pkthdr.len;
|
---|
| 516 | }
|
---|
| 517 | - usbd_m_copy_in(pc, pos, m, 0, m->m_pkthdr.len);
|
---|
| 518 | - pos += m->m_pkthdr.len;
|
---|
| 519 |
|
---|
| 520 | /*
|
---|
| 521 | * XXX
|
---|
| 522 | @@ -946,22 +1079,16 @@
|
---|
| 523 |
|
---|
| 524 | m_freem(m);
|
---|
| 525 |
|
---|
| 526 | - if (sc->sc_flags & (AXE_FLAG_772 | AXE_FLAG_178)) {
|
---|
| 527 | - if (pos > (AXE_BULK_BUF_SIZE - MCLBYTES - sizeof(hdr))) {
|
---|
| 528 | - /* send out frame(s) */
|
---|
| 529 | - break;
|
---|
| 530 | - }
|
---|
| 531 | - } else {
|
---|
| 532 | - /* send out frame */
|
---|
| 533 | - break;
|
---|
| 534 | - }
|
---|
| 535 | + /* Set frame length. */
|
---|
| 536 | + usbd_xfer_set_frame_len(xfer, nframes, pos);
|
---|
| 537 | }
|
---|
| 538 | -
|
---|
| 539 | - usbd_xfer_set_frame_len(xfer, 0, pos);
|
---|
| 540 | - usbd_transfer_submit(xfer);
|
---|
| 541 | - ifp->if_drv_flags |= IFF_DRV_OACTIVE;
|
---|
| 542 | + if (nframes != 0) {
|
---|
| 543 | + usbd_xfer_set_frames(xfer, nframes);
|
---|
| 544 | + usbd_transfer_submit(xfer);
|
---|
| 545 | + ifp->if_drv_flags |= IFF_DRV_OACTIVE;
|
---|
| 546 | + }
|
---|
| 547 | return;
|
---|
| 548 | -
|
---|
| 549 | + /* NOTREACHED */
|
---|
| 550 | default: /* Error */
|
---|
| 551 | DPRINTFN(11, "transfer error, %s\n",
|
---|
| 552 | usbd_errstr(error));
|
---|
| 553 | @@ -1016,37 +1143,54 @@
|
---|
| 554 |
|
---|
| 555 | AXE_LOCK_ASSERT(sc, MA_OWNED);
|
---|
| 556 |
|
---|
| 557 | + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
|
---|
| 558 | + return;
|
---|
| 559 | +
|
---|
| 560 | /* Cancel pending I/O */
|
---|
| 561 | axe_stop(ue);
|
---|
| 562 |
|
---|
| 563 | + axe_reset(sc);
|
---|
| 564 | +
|
---|
| 565 | /* Set MAC address. */
|
---|
| 566 | - if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772))
|
---|
| 567 | + if (AXE_IS_178_FAMILY(sc))
|
---|
| 568 | axe_cmd(sc, AXE_178_CMD_WRITE_NODEID, 0, 0, IF_LLADDR(ifp));
|
---|
| 569 | else
|
---|
| 570 | axe_cmd(sc, AXE_172_CMD_WRITE_NODEID, 0, 0, IF_LLADDR(ifp));
|
---|
| 571 |
|
---|
| 572 | /* Set transmitter IPG values */
|
---|
| 573 | - if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772)) {
|
---|
| 574 | + if (AXE_IS_178_FAMILY(sc))
|
---|
| 575 | axe_cmd(sc, AXE_178_CMD_WRITE_IPG012, sc->sc_ipgs[2],
|
---|
| 576 | (sc->sc_ipgs[1] << 8) | (sc->sc_ipgs[0]), NULL);
|
---|
| 577 | - } else {
|
---|
| 578 | + else {
|
---|
| 579 | axe_cmd(sc, AXE_172_CMD_WRITE_IPG0, 0, sc->sc_ipgs[0], NULL);
|
---|
| 580 | axe_cmd(sc, AXE_172_CMD_WRITE_IPG1, 0, sc->sc_ipgs[1], NULL);
|
---|
| 581 | axe_cmd(sc, AXE_172_CMD_WRITE_IPG2, 0, sc->sc_ipgs[2], NULL);
|
---|
| 582 | }
|
---|
| 583 |
|
---|
| 584 | - /* Enable receiver, set RX mode */
|
---|
| 585 | + /* AX88772B uses different maximum frame burst configuration. */
|
---|
| 586 | + if (sc->sc_flags & AXE_FLAG_772B)
|
---|
| 587 | + axe_cmd(sc, AXE_772B_CMD_RXCTL_WRITE_CFG,
|
---|
| 588 | + ax88772b_mfb_table[AX88772B_MFB_16K].threshold,
|
---|
| 589 | + ax88772b_mfb_table[AX88772B_MFB_16K].byte_cnt, NULL);
|
---|
| 590 | +
|
---|
| 591 | + /* Enable receiver, set RX mode. */
|
---|
| 592 | rxmode = (AXE_RXCMD_MULTICAST | AXE_RXCMD_ENABLE);
|
---|
| 593 | - if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772)) {
|
---|
| 594 | -#if 0
|
---|
| 595 | - rxmode |= AXE_178_RXCMD_MFB_2048; /* chip default */
|
---|
| 596 | -#else
|
---|
| 597 | - /*
|
---|
| 598 | - * Default Rx buffer size is too small to get
|
---|
| 599 | - * maximum performance.
|
---|
| 600 | - */
|
---|
| 601 | - rxmode |= AXE_178_RXCMD_MFB_16384;
|
---|
| 602 | -#endif
|
---|
| 603 | + if (AXE_IS_178_FAMILY(sc)) {
|
---|
| 604 | + if (sc->sc_flags & AXE_FLAG_772B) {
|
---|
| 605 | + /*
|
---|
| 606 | + * Select RX header format type 1. Aligning IP
|
---|
| 607 | + * header on 4 byte boundary is not needed
|
---|
| 608 | + * because we always copy the received frame in
|
---|
| 609 | + * RX handler.
|
---|
| 610 | + */
|
---|
| 611 | + rxmode |= AXE_772B_RXCMD_HDR_TYPE_1;
|
---|
| 612 | + } else {
|
---|
| 613 | + /*
|
---|
| 614 | + * Default Rx buffer size is too small to get
|
---|
| 615 | + * maximum performance.
|
---|
| 616 | + */
|
---|
| 617 | + rxmode |= AXE_178_RXCMD_MFB_16384;
|
---|
| 618 | + }
|
---|
| 619 | } else {
|
---|
| 620 | rxmode |= AXE_172_RXCMD_UNICAST;
|
---|
| 621 | }
|
---|
| 622 | @@ -1066,6 +1210,8 @@
|
---|
| 623 | usbd_xfer_set_stall(sc->sc_xfer[AXE_BULK_DT_WR]);
|
---|
| 624 |
|
---|
| 625 | ifp->if_drv_flags |= IFF_DRV_RUNNING;
|
---|
| 626 | + /* Switch to selected media. */
|
---|
| 627 | + axe_ifmedia_upd(ifp);
|
---|
| 628 | axe_start(ue);
|
---|
| 629 | }
|
---|
| 630 |
|
---|
| 631 | @@ -1107,6 +1253,4 @@
|
---|
| 632 | */
|
---|
| 633 | usbd_transfer_stop(sc->sc_xfer[AXE_BULK_DT_WR]);
|
---|
| 634 | usbd_transfer_stop(sc->sc_xfer[AXE_BULK_DT_RD]);
|
---|
| 635 | -
|
---|
| 636 | - axe_reset(sc);
|
---|
| 637 | }
|
---|