close Warning: Can't use blame annotator:
No changeset 9538 in the repository

source: hybrid/trunk/nanobsd/misc/patches/backport-axe-to-8.2-release-v2.patch@ 10123

Last change on this file since 10123 was 10123, checked in by richardvm, 13 years ago

creating trunk based on 9.0

File size: 17.8 KB
RevLine 
1Index: 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
13Index: 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)
121Index: 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 }
Note: See TracBrowser for help on using the repository browser.