diff options
author | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2010-08-26 18:33:28 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2010-08-27 14:36:03 +0200 |
commit | 12f396a8b02e57f579d2863299948b5172ffdf6f (patch) | |
tree | dd354d4cf966925422d20f5796a134d148d39693 /include | |
parent | f2283c2057b28d81b9060ba3fde68f24f2eb2922 (diff) | |
download | barebox-12f396a8b02e57f579d2863299948b5172ffdf6f.tar.gz barebox-12f396a8b02e57f579d2863299948b5172ffdf6f.tar.xz |
net: rework the mii support
this rework is done in order to add a phylib and allow to have phy driver support
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/mii.h (renamed from include/miiphy.h) | 132 | ||||
-rw-r--r-- | include/miidev.h | 62 | ||||
-rw-r--r-- | include/usb/usbnet.h | 4 |
3 files changed, 167 insertions, 31 deletions
diff --git a/include/miiphy.h b/include/linux/mii.h index 67f1b1ce98..734517268f 100644 --- a/include/miiphy.h +++ b/include/linux/mii.h @@ -5,13 +5,10 @@ * Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com) */ -#ifndef _MII_PHY_H_ -#define _MII_PHY_H_ +#ifndef __LINUX_MII_H__ +#define __LINUX_MII_H__ -#include <driver.h> - -#define MIIPHY_FORCE_10 (1 << 0) -#define MIIPHY_FORCE_LINK (1 << 1) +/* Generic MII registers. */ #define MII_BMCR 0x00 /* Basic mode control register */ #define MII_BMSR 0x01 /* Basic mode status register */ @@ -22,7 +19,7 @@ #define MII_EXPANSION 0x06 /* Expansion register */ #define MII_CTRL1000 0x09 /* 1000BASE-T control */ #define MII_STAT1000 0x0a /* 1000BASE-T status */ -#define MII_ESTATUS 0x0f /* Extended Status */ +#define MII_ESTATUS 0x0f /* Extended Status */ #define MII_DCOUNTER 0x12 /* Disconnect counter */ #define MII_FCSCOUNTER 0x13 /* False carrier counter */ #define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */ @@ -36,6 +33,8 @@ #define MII_NCONFIG 0x1c /* Network interface config */ /* Basic mode control register. */ +#define BMCR_SPEED_MASK 0x2040 /* 10/100/1000 */ +#define BMCR_SPEED10 0x0000 /* Select 10Mbps */ #define BMCR_RESV 0x003f /* Unused... */ #define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */ #define BMCR_CTST 0x0080 /* Collision test */ @@ -56,9 +55,9 @@ #define BMSR_RFAULT 0x0010 /* Remote fault detected */ #define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */ #define BMSR_RESV 0x00c0 /* Unused... */ -#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */ -#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */ -#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */ +#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */ +#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */ +#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */ #define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ #define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ #define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ @@ -136,23 +135,98 @@ #define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */ #define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */ -struct miiphy_device { - struct device_d dev; - - int address; /* The address the phy has on the bus */ - int (*read)(struct miiphy_device *mdev, uint8_t phy_addr, uint8_t reg_addr, uint16_t *value); - int (*write)(struct miiphy_device *mdev, uint8_t phy_addr, uint8_t reg_addr, uint16_t data); - - int flags; - - struct eth_device *edev; - struct cdev cdev; -}; +/* Flow control flags */ +#define FLOW_CTRL_TX 0x01 +#define FLOW_CTRL_RX 0x02 -int miiphy_register(struct miiphy_device *mdev); -void miiphy_unregister(struct miiphy_device *mdev); -int miiphy_restart_aneg(struct miiphy_device *mdev); -int miiphy_wait_aneg(struct miiphy_device *mdev); -int miiphy_print_status(struct miiphy_device *mdev); - -#endif +/** + * mii_nway_result + * @negotiated: value of MII ANAR and'd with ANLPAR + * + * Given a set of MII abilities, check each bit and returns the + * currently supported media, in the priority order defined by + * IEEE 802.3u. We use LPA_xxx constants but note this is not the + * value of LPA solely, as described above. + * + * The one exception to IEEE 802.3u is that 100baseT4 is placed + * between 100T-full and 100T-half. If your phy does not support + * 100T4 this is fine. If your phy places 100T4 elsewhere in the + * priority order, you will need to roll your own function. + */ +static inline unsigned int mii_nway_result (unsigned int negotiated) +{ + unsigned int ret; + + if (negotiated & LPA_100FULL) + ret = LPA_100FULL; + else if (negotiated & LPA_100BASE4) + ret = LPA_100BASE4; + else if (negotiated & LPA_100HALF) + ret = LPA_100HALF; + else if (negotiated & LPA_10FULL) + ret = LPA_10FULL; + else + ret = LPA_10HALF; + + return ret; +} + +/** + * mii_duplex + * @duplex_lock: Non-zero if duplex is locked at full + * @negotiated: value of MII ANAR and'd with ANLPAR + * + * A small helper function for a common case. Returns one + * if the media is operating or locked at full duplex, and + * returns zero otherwise. + */ +static inline unsigned int mii_duplex (unsigned int duplex_lock, + unsigned int negotiated) +{ + if (duplex_lock) + return 1; + if (mii_nway_result(negotiated) & LPA_DUPLEX) + return 1; + return 0; +} + +/** + * mii_advertise_flowctrl - get flow control advertisement flags + * @cap: Flow control capabilities (FLOW_CTRL_RX, FLOW_CTRL_TX or both) + */ +static inline u16 mii_advertise_flowctrl(int cap) +{ + u16 adv = 0; + + if (cap & FLOW_CTRL_RX) + adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; + if (cap & FLOW_CTRL_TX) + adv ^= ADVERTISE_PAUSE_ASYM; + + return adv; +} + +/** + * mii_resolve_flowctrl_fdx + * @lcladv: value of MII ADVERTISE register + * @rmtadv: value of MII LPA register + * + * Resolve full duplex flow control as per IEEE 802.3-2005 table 28B-3 + */ +static inline u8 mii_resolve_flowctrl_fdx(u16 lcladv, u16 rmtadv) +{ + u8 cap = 0; + + if (lcladv & rmtadv & ADVERTISE_PAUSE_CAP) { + cap = FLOW_CTRL_TX | FLOW_CTRL_RX; + } else if (lcladv & rmtadv & ADVERTISE_PAUSE_ASYM) { + if (lcladv & ADVERTISE_PAUSE_CAP) + cap = FLOW_CTRL_RX; + else if (rmtadv & ADVERTISE_PAUSE_CAP) + cap = FLOW_CTRL_TX; + } + + return cap; +} + +#endif /* __LINUX_MII_H__ */ diff --git a/include/miidev.h b/include/miidev.h new file mode 100644 index 0000000000..6f653d9f01 --- /dev/null +++ b/include/miidev.h @@ -0,0 +1,62 @@ +/* + * (C) Copyright 2001 + * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com. + * + * (C) Copyright 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef __MIIDEV_H__ +#define __MIIDEV_H__ + +#include <driver.h> +#include <linux/mii.h> + +#define MIIDEV_FORCE_10 (1 << 0) +#define MIIDEV_FORCE_LINK (1 << 1) + +struct mii_device { + struct device_d dev; + + int address; /* The address the phy has on the bus */ + int (*read) (struct mii_device *dev, int addr, int reg); + int (*write) (struct mii_device *dev, int addr, int reg, int value); + + int flags; + + struct eth_device *edev; + struct cdev cdev; +}; + +int mii_register(struct mii_device *dev); +void mii_unregister(struct mii_device *mdev); +int miidev_restart_aneg(struct mii_device *mdev); +int miidev_wait_aneg(struct mii_device *mdev); +int miidev_print_status(struct mii_device *mdev); + +static int inline mii_write(struct mii_device *dev, int addr, int reg, int value) +{ + return dev->write(dev, addr, reg, value); +} + +static int inline mii_read(struct mii_device *dev, int addr, int reg) +{ + return dev->read(dev, addr, reg); +} +#endif /* __MIIDEV_H__ */ diff --git a/include/usb/usbnet.h b/include/usb/usbnet.h index e3ea373d95..1609b2eb26 100644 --- a/include/usb/usbnet.h +++ b/include/usb/usbnet.h @@ -23,7 +23,7 @@ #define __LINUX_USB_USBNET_H #include <net.h> -#include <miiphy.h> +#include <miidev.h> /* interface from usbnet core to each USB networking link we handle */ struct usbnet { @@ -40,7 +40,7 @@ struct usbnet { /* protocol/interface state */ struct eth_device edev; - struct miiphy_device miiphy; + struct mii_device miidev; int msg_enable; unsigned long data [5]; |