4 * Copyright 2006, Haiku, Inc. All Rights Reserved.
5 * Distributed under the terms of the MIT License.
12 * Copyright (c) 1997, 1998, 1999, 2000
13 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. All advertising materials mentioning features or use of this software
24 * must display the following acknowledgement:
25 * This product includes software developed by Bill Paul.
26 * 4. Neither the name of the author nor the names of any co-contributors
27 * may be used to endorse or promote products derived from this software
28 * without specific prior written permission.
30 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
31 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
34 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
35 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
36 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
37 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
38 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
40 * THE POSSIBILITY OF SUCH DAMAGE.
47 extern usb_module_info
*usb
;
49 #define AUE_SETBIT(sc, reg, x) \
50 aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) | (x))
52 #define AUE_CLRBIT(sc, reg, x) \
53 aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) & ~(x))
56 aue_csr_read_1(pegasus_dev
*sc
, int reg
)
67 err
= usb
->send_request(sc
->dev
, USB_REQTYPE_VENDOR
| USB_REQTYPE_DEVICE_IN
,
68 AUE_UR_READREG
, 0, reg
, 1, &val
, &length
);
79 aue_csr_read_2(pegasus_dev
*sc
, int reg
)
90 err
= usb
->send_request(sc
->dev
, USB_REQTYPE_VENDOR
| USB_REQTYPE_DEVICE_IN
,
91 AUE_UR_READREG
, 0, reg
, 2, &val
, &length
);
103 aue_csr_write_1(pegasus_dev
*sc
, int reg
, int val
)
113 err
= usb
->send_request(sc
->dev
, USB_REQTYPE_VENDOR
| USB_REQTYPE_DEVICE_OUT
,
114 AUE_UR_WRITEREG
, val
, reg
, 1, &val
, &length
);
126 aue_csr_write_2(pegasus_dev
*sc
, int reg
, int val
)
136 err
= usb
->send_request(sc
->dev
, USB_REQTYPE_VENDOR
| USB_REQTYPE_DEVICE_OUT
,
137 AUE_UR_WRITEREG
, val
, reg
, 2, &val
, &length
);
149 * Read a word of data stored in the EEPROM at address 'addr.'
152 aue_eeprom_getword(pegasus_dev
*sc
, int addr
, u_int16_t
*dest
)
157 aue_csr_write_1(sc
, AUE_EE_REG
, addr
);
158 aue_csr_write_1(sc
, AUE_EE_CTL
, AUE_EECTL_READ
);
160 for (i
= 0; i
< AUE_TIMEOUT
; i
++) {
161 if (aue_csr_read_1(sc
, AUE_EE_CTL
) & AUE_EECTL_DONE
)
165 if (i
== AUE_TIMEOUT
) {
166 dprintf("aue%d: EEPROM read timed out\n",
170 word
= aue_csr_read_2(sc
, AUE_EE_DATA
);
180 * Read a sequence of words from the EEPROM.
183 aue_read_eeprom(pegasus_dev
*sc
, caddr_t dest
, int off
, int cnt
, int swap
)
186 u_int16_t word
= 0, *ptr
;
188 for (i
= 0; i
< cnt
; i
++) {
189 aue_eeprom_getword(sc
, off
+ i
, &word
);
190 ptr
= (u_int16_t
*)(dest
+ (i
* 2));
202 aue_miibus_readreg(pegasus_dev
*sc
, int phy
, int reg
)
208 * The Am79C901 HomePNA PHY actually contains
209 * two transceivers: a 1Mbps HomePNA PHY and a
210 * 10Mbps full/half duplex ethernet PHY with
211 * NWAY autoneg. However in the ADMtek adapter,
212 * only the 1Mbps PHY is actually connected to
213 * anything, so we ignore the 10Mbps one. It
214 * happens to be configured for MII address 3,
215 * so we filter that out.
217 if (sc
->aue_vendor
== USB_VENDOR_ADMTEK
&&
218 sc
->aue_product
== USB_PRODUCT_ADMTEK_PEGASUS
) {
227 aue_csr_write_1(sc
, AUE_PHY_ADDR
, phy
);
228 aue_csr_write_1(sc
, AUE_PHY_CTL
, reg
| AUE_PHYCTL_READ
);
230 for (i
= 0; i
< AUE_TIMEOUT
; i
++) {
231 if (aue_csr_read_1(sc
, AUE_PHY_CTL
) & AUE_PHYCTL_DONE
)
235 if (i
== AUE_TIMEOUT
) {
236 dprintf("aue%d: MII read timed out\n", sc
->aue_unit
);
239 val
= aue_csr_read_2(sc
, AUE_PHY_DATA
);
246 aue_miibus_writereg(pegasus_dev
*sc
, int phy
, int reg
, int data
)
253 aue_csr_write_2(sc
, AUE_PHY_DATA
, data
);
254 aue_csr_write_1(sc
, AUE_PHY_ADDR
, phy
);
255 aue_csr_write_1(sc
, AUE_PHY_CTL
, reg
| AUE_PHYCTL_WRITE
);
257 for (i
= 0; i
< AUE_TIMEOUT
; i
++) {
258 if (aue_csr_read_1(sc
, AUE_PHY_CTL
) & AUE_PHYCTL_DONE
)
262 if (i
== AUE_TIMEOUT
) {
263 dprintf("aue%d: MII read timed out\n",
272 aue_miibus_read(pegasus_dev
*dev
, uint16 reg
)
274 return aue_miibus_readreg(dev
, dev
->phy
, reg
);
279 aue_miibus_write(pegasus_dev
*dev
, uint16 reg
, uint16 value
)
281 aue_miibus_writereg(dev
, dev
->phy
, reg
, value
);
286 aue_miibus_status_from_phy(pegasus_dev
*dev
, uint16 phy
)
291 // the status must be retrieved two times, because the first
292 // one may not work on some PHYs (notably ICS 1893)
294 status
= aue_miibus_readreg(dev
, phy
, MII_STATUS
);
301 aue_miibus_status(pegasus_dev
*dev
)
303 return aue_miibus_status_from_phy(dev
, dev
->phy
);
308 aue_init_phy(pegasus_dev
*dev
)
315 // search for total of 32 possible MII PHY addresses
316 for (phy
= 0; phy
< 32; phy
++) {
319 status
= aue_miibus_status_from_phy(dev
, phy
);
320 if (status
== 0xffff || status
== 0x0000)
321 // this MII is not accessable
327 if (dev
->phy
== 255) {
328 DPRINTF_ERR("No MII PHY transceiver found!\n");
329 return B_ENTRY_NOT_FOUND
;
331 DPRINTF_INFO("aue_init_phy MII PHY found at %d\n", dev
->phy
);
333 status
= aue_miibus_read(dev
, MII_CONTROL
);
334 status
&= ~MII_CONTROL_ISOLATE
;
336 aue_miibus_write(dev
, MII_CONTROL
, status
);
338 aue_miibus_write(dev
, MII_CONTROL
, MII_CONTROL_RESET
);
339 for (i
= 0; i
< 100; i
++) {
340 if ((aue_miibus_read(dev
, MII_STATUS
) & MII_CONTROL_RESET
) == 0)
345 dev
->link
= aue_miibus_status(dev
) & MII_STATUS_LINK
;
352 aue_reset_pegasus_II(pegasus_dev
*sc
)
354 /* Magic constants taken from Linux driver. */
355 aue_csr_write_1(sc
, AUE_REG_1D
, 0);
356 aue_csr_write_1(sc
, AUE_REG_7B
, 2);
358 if ((sc
->aue_flags
& HAS_HOME_PNA
) && mii_mode
)
359 aue_csr_write_1(sc
, AUE_REG_81
, 6);
362 aue_csr_write_1(sc
, AUE_REG_81
, 2);
366 aue_reset(pegasus_dev
*sc
)
370 AUE_SETBIT(sc
, AUE_CTL1
, AUE_CTL1_RESETMAC
);
372 for (i
= 0; i
< AUE_TIMEOUT
; i
++) {
373 if (!(aue_csr_read_1(sc
, AUE_CTL1
) & AUE_CTL1_RESETMAC
))
377 if (i
== AUE_TIMEOUT
)
378 dprintf("aue%d: reset failed\n", sc
->aue_unit
);
381 * The PHY(s) attached to the Pegasus chip may be held
382 * in reset until we flip on the GPIO outputs. Make sure
383 * to set the GPIO pins high so that the PHY(s) will
386 * Note: We force all of the GPIO pins low first, *then*
387 * enable the ones we want.
389 aue_csr_write_1(sc
, AUE_GPIO0
, AUE_GPIO_OUT0
|AUE_GPIO_SEL0
);
390 aue_csr_write_1(sc
, AUE_GPIO0
, AUE_GPIO_OUT0
|AUE_GPIO_SEL0
|AUE_GPIO_SEL1
);
392 if (sc
->aue_flags
& LSYS
) {
393 /* Grrr. LinkSys has to be different from everyone else. */
394 aue_csr_write_1(sc
, AUE_GPIO0
,
395 AUE_GPIO_SEL0
| AUE_GPIO_SEL1
);
396 aue_csr_write_1(sc
, AUE_GPIO0
,
397 AUE_GPIO_SEL0
| AUE_GPIO_SEL1
| AUE_GPIO_OUT0
);
400 if (sc
->aue_flags
& PII
)
401 aue_reset_pegasus_II(sc
);
403 /* Wait a little while for the chip to get its brains in order. */
414 aue_attach(pegasus_dev
*sc
)
416 u_char eaddr
[ETHER_ADDRESS_LENGTH
];
420 /* Reset the adapter. */
424 * Get station address from the EEPROM.
426 aue_read_eeprom(sc
, (caddr_t
)&eaddr
, 0, 3, 0);
428 memcpy(sc
->macaddr
, eaddr
, ETHER_ADDRESS_LENGTH
);
430 if (aue_init_phy(sc
) != B_OK
)
441 aue_init(pegasus_dev
*sc
)
444 /* Enable RX and TX */
445 aue_csr_write_1(sc
, AUE_CTL0
, AUE_CTL0_RXSTAT_APPEND
| AUE_CTL0_RX_ENB
);
446 AUE_SETBIT(sc
, AUE_CTL0
, AUE_CTL0_TX_ENB
);
447 AUE_SETBIT(sc
, AUE_CTL2
, AUE_CTL2_EP3_CLR
);
453 aue_uninit(pegasus_dev
*sc
)
455 aue_csr_write_1(sc
, AUE_CTL0
, 0);
456 aue_csr_write_1(sc
, AUE_CTL1
, 0);