Merge branch 'for-next/ethernet'
This commit is contained in:
commit
149d4764a3
|
@ -123,7 +123,7 @@ int miidev_wait_aneg(struct mii_device *mdev)
|
|||
|
||||
int miidev_get_status(struct mii_device *mdev)
|
||||
{
|
||||
int ret, status;
|
||||
int ret, status, adv, lpa;
|
||||
|
||||
ret = mii_read(mdev, mdev->address, MII_BMSR);
|
||||
if (ret < 0)
|
||||
|
@ -136,13 +136,31 @@ int miidev_get_status(struct mii_device *mdev)
|
|||
goto err_out;
|
||||
|
||||
if (ret & BMCR_ANENABLE) {
|
||||
ret = mii_read(mdev, mdev->address, MII_LPA);
|
||||
if (ret < 0)
|
||||
if (mdev->capabilities & MIIDEV_CAPABLE_1000M) {
|
||||
lpa = mii_read(mdev, mdev->address, MII_STAT1000);
|
||||
if (lpa < 0)
|
||||
goto err_out;
|
||||
adv = mii_read(mdev, mdev->address, MII_CTRL1000);
|
||||
if (adv < 0)
|
||||
goto err_out;
|
||||
lpa &= adv << 2;
|
||||
if (lpa & (LPA_1000FULL | LPA_1000HALF)) {
|
||||
if (lpa & LPA_1000FULL)
|
||||
status |= MIIDEV_STATUS_IS_FULL_DUPLEX;
|
||||
status |= MIIDEV_STATUS_IS_1000MBIT;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
lpa = mii_read(mdev, mdev->address, MII_LPA);
|
||||
if (lpa < 0)
|
||||
goto err_out;
|
||||
|
||||
status |= ret & LPA_DUPLEX ? MIIDEV_STATUS_IS_FULL_DUPLEX : 0;
|
||||
status |= ret & LPA_100 ? MIIDEV_STATUS_IS_100MBIT :
|
||||
MIIDEV_STATUS_IS_10MBIT;
|
||||
adv = mii_read(mdev, mdev->address, MII_ADVERTISE);
|
||||
if (adv < 0)
|
||||
goto err_out;
|
||||
lpa &= adv;
|
||||
status |= lpa & LPA_DUPLEX ? MIIDEV_STATUS_IS_FULL_DUPLEX : 0;
|
||||
status |= lpa & LPA_100 ? MIIDEV_STATUS_IS_100MBIT :
|
||||
MIIDEV_STATUS_IS_10MBIT;
|
||||
} else {
|
||||
status |= ret & BMCR_FULLDPLX ? MIIDEV_STATUS_IS_FULL_DUPLEX : 0;
|
||||
status |= ret & BMCR_SPEED100 ? MIIDEV_STATUS_IS_100MBIT :
|
||||
|
@ -170,8 +188,8 @@ int miidev_print_status(struct mii_device *mdev)
|
|||
return status;
|
||||
|
||||
duplex = status & MIIDEV_STATUS_IS_FULL_DUPLEX ? "Full" : "Half";
|
||||
speed = status & MIIDEV_STATUS_IS_100MBIT ? 100 : 10;
|
||||
|
||||
speed = status & MIIDEV_STATUS_IS_1000MBIT ? 1000 :
|
||||
(status & MIIDEV_STATUS_IS_100MBIT ? 100 : 10);
|
||||
|
||||
printf("%s: Link is %s", mdev->cdev.name,
|
||||
status & MIIDEV_STATUS_IS_UP ? "up" : "down");
|
||||
|
@ -186,11 +204,11 @@ static ssize_t miidev_read(struct cdev *cdev, void *_buf, size_t count, loff_t o
|
|||
uint16_t *buf = _buf;
|
||||
struct mii_device *mdev = cdev->priv;
|
||||
|
||||
while (i > 1) {
|
||||
*buf = mii_read(mdev, mdev->address, offset);
|
||||
while (i > 0) {
|
||||
*buf = mii_read(mdev, mdev->address, offset / 2);
|
||||
buf++;
|
||||
i -= 2;
|
||||
offset++;
|
||||
offset += 2;
|
||||
}
|
||||
|
||||
return count;
|
||||
|
@ -202,11 +220,11 @@ static ssize_t miidev_write(struct cdev *cdev, const void *_buf, size_t count, l
|
|||
const uint16_t *buf = _buf;
|
||||
struct mii_device *mdev = cdev->priv;
|
||||
|
||||
while (i > 1) {
|
||||
mii_write(mdev, mdev->address, offset, *buf);
|
||||
while (i > 0) {
|
||||
mii_write(mdev, mdev->address, offset / 2, *buf);
|
||||
buf++;
|
||||
i -= 2;
|
||||
offset++;
|
||||
offset += 2;
|
||||
}
|
||||
|
||||
return count;
|
||||
|
@ -221,7 +239,27 @@ static struct file_operations miidev_ops = {
|
|||
static int miidev_probe(struct device_d *dev)
|
||||
{
|
||||
struct mii_device *mdev = dev->priv;
|
||||
int val;
|
||||
int caps = 0;
|
||||
|
||||
val = mii_read(mdev, mdev->address, MII_PHYSID1);
|
||||
if (val < 0 || val == 0xffff)
|
||||
goto err_out;
|
||||
val = mii_read(mdev, mdev->address, MII_PHYSID2);
|
||||
if (val < 0 || val == 0xffff)
|
||||
goto err_out;
|
||||
val = mii_read(mdev, mdev->address, MII_BMSR);
|
||||
if (val < 0)
|
||||
goto err_out;
|
||||
if (val & BMSR_ESTATEN) {
|
||||
val = mii_read(mdev, mdev->address, MII_ESTATUS);
|
||||
if (val < 0)
|
||||
goto err_out;
|
||||
if (val & (ESTATUS_1000_TFULL | ESTATUS_1000_THALF))
|
||||
caps = MIIDEV_CAPABLE_1000M;
|
||||
}
|
||||
|
||||
mdev->capabilities = caps;
|
||||
mdev->cdev.name = asprintf("phy%d", dev->id);
|
||||
mdev->cdev.size = 64;
|
||||
mdev->cdev.ops = &miidev_ops;
|
||||
|
@ -230,6 +268,10 @@ static int miidev_probe(struct device_d *dev)
|
|||
devfs_create(&mdev->cdev);
|
||||
list_add_tail(&mdev->list, &miidev_list);
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
dev_err(dev, "cannot read PHY registers (addr %d)\n", mdev->address);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void miidev_remove(struct device_d *dev)
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#define MIIDEV_FORCE_10 (1 << 0)
|
||||
#define MIIDEV_FORCE_LINK (1 << 1)
|
||||
|
||||
#define MIIDEV_CAPABLE_1000M (1 << 0)
|
||||
|
||||
struct mii_device {
|
||||
struct device_d dev;
|
||||
struct device_d *parent;
|
||||
|
@ -40,6 +42,7 @@ struct mii_device {
|
|||
int (*write) (struct mii_device *dev, int addr, int reg, int value);
|
||||
|
||||
int flags;
|
||||
int capabilities;
|
||||
|
||||
struct eth_device *edev;
|
||||
struct cdev cdev;
|
||||
|
@ -55,6 +58,7 @@ int miidev_get_status(struct mii_device *mdev);
|
|||
#define MIIDEV_STATUS_IS_FULL_DUPLEX (1 << 1)
|
||||
#define MIIDEV_STATUS_IS_10MBIT (1 << 2)
|
||||
#define MIIDEV_STATUS_IS_100MBIT (1 << 3)
|
||||
#define MIIDEV_STATUS_IS_1000MBIT (1 << 4)
|
||||
int miidev_print_status(struct mii_device *mdev);
|
||||
|
||||
static int inline mii_write(struct mii_device *dev, int addr, int reg, int value)
|
||||
|
|
|
@ -38,8 +38,8 @@ struct eth_device {
|
|||
int (*send) (struct eth_device*, void *packet, int length);
|
||||
int (*recv) (struct eth_device*);
|
||||
void (*halt) (struct eth_device*);
|
||||
int (*get_ethaddr) (struct eth_device*, unsigned char *adr);
|
||||
int (*set_ethaddr) (struct eth_device*, unsigned char *adr);
|
||||
int (*get_ethaddr) (struct eth_device*, u8 adr[6]);
|
||||
int (*set_ethaddr) (struct eth_device*, u8 adr[6]);
|
||||
|
||||
struct eth_device *next;
|
||||
void *priv;
|
||||
|
@ -287,8 +287,8 @@ int string_to_ip(const char *s, IPaddr_t *ip);
|
|||
IPaddr_t getenv_ip(const char *name);
|
||||
int setenv_ip(const char *name, IPaddr_t ip);
|
||||
|
||||
int string_to_ethaddr(const char *str, char *enetaddr);
|
||||
void ethaddr_to_string(const unsigned char *enetaddr, char *str);
|
||||
int string_to_ethaddr(const char *str, u8 enetaddr[6]);
|
||||
void ethaddr_to_string(const u8 enetaddr[6], char *str);
|
||||
|
||||
#ifdef CONFIG_NET_RESOLV
|
||||
IPaddr_t resolv(char *host);
|
||||
|
|
|
@ -167,7 +167,7 @@ int eth_rx(void)
|
|||
static int eth_set_ethaddr(struct device_d *dev, struct param_d *param, const char *val)
|
||||
{
|
||||
struct eth_device *edev = dev_to_edev(dev);
|
||||
char ethaddr[sizeof("xx:xx:xx:xx:xx:xx")];
|
||||
u8 ethaddr[6];
|
||||
|
||||
if (!val)
|
||||
return dev_param_set_generic(dev, param, NULL);
|
||||
|
|
|
@ -159,7 +159,7 @@ void print_IPaddr (IPaddr_t x)
|
|||
puts(ip_to_string(x));
|
||||
}
|
||||
|
||||
int string_to_ethaddr(const char *str, char *enetaddr)
|
||||
int string_to_ethaddr(const char *str, u8 enetaddr[6])
|
||||
{
|
||||
int reg;
|
||||
char *e;
|
||||
|
@ -181,7 +181,7 @@ int string_to_ethaddr(const char *str, char *enetaddr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void ethaddr_to_string(const unsigned char *enetaddr, char *str)
|
||||
void ethaddr_to_string(const u8 enetaddr[6], char *str)
|
||||
{
|
||||
sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X",
|
||||
enetaddr[0], enetaddr[1], enetaddr[2], enetaddr[3],
|
||||
|
|
Loading…
Reference in New Issue