lkml.org 
[lkml]   [2006]   [May]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: [PATCH 2/2] ipg: redundancy with mii.h
Pekka Enberg <penberg@cs.helsinki.fi> :
[...]
> My initial patches are here:
>
> http://www.cs.helsinki.fi/u/penberg/linux/ip1000/

Nice. Thanks.

> I consider your tree the master now. Please let me know when you have
> recreated the history, so I can clone your tree. Thanks.

The new serie is available in branch 'netdev-ipg' at
git://electric-eye.fr.zoreil.com/home/romieu/linux-2.6.git

Former branch 'netdev-ipg' was moved to 'netdev-ipg.log'.

I have added a new patch (see (way) below).

$ git log master..

commit 17adeb85054a693224a2ab7787a224c722bdd4eb
Author: Francois Romieu <romieu@fr.zoreil.com>
Date: Fri May 5 01:42:12 2006 +0200

ip1000: ethtool {get/set}_settings support
The patch shoehorns the driver into the usual mii/ethtool framework.
mii_mutex will prove useful when the link management tasks issued in
irq context are moved to user/workqueue context. Next step.

At least the current code should not be _too_ broken.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

commit 997a02f4c4b3cf2ec0177ba33ffda6d550396eb7
Author: Francois Romieu <romieu@fr.zoreil.com>
Date: Thu May 4 00:29:59 2006 +0200

ip1000: remove forward declarations

It makes no sense in a new driver.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

commit b141c4ec3572f3151b2eb037ef5e7aba8d190445
Author: Francois Romieu <romieu@fr.zoreil.com>
Date: Thu May 4 00:04:57 2006 +0200

ip1000: replace #define with enum

Added some underscores to improve readability.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

commit 9d27e1ab51b2295d72ea254bbc8de5b5797a4139
Author: Francois Romieu <romieu@fr.zoreil.com>
Date: Wed May 3 22:51:16 2006 +0200

ip1000: removal of useless #defines

IPG_TX_NOTBUSY apart (one occurence in ipg.c), the #defines appear
nowhere in the sources.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

commit 42ad0c39990c1897ee56dfc34bb4a7b2de76ace0
Author: Francois Romieu <romieu@fr.zoreil.com>
Date: Wed May 3 22:44:47 2006 +0200

ip1000: redundancy with mii.h - take II

Replace a bunch of #define with their counterpart from mii.h

It is applied to the usual MII registers this time.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

commit be97a643f5d955208c0be7aa9e16a05c7737a2be
Author: Romieu Francois <romieu@fr.zoreil.com>
Date: Tue May 2 23:25:44 2006 +0200

ip1000: redundancy with mii.h

Replace a bunch of #define with their counterpart from mii.h

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

commit 273a5a5f0815a35cf06faeafea6fc47503d364cb
Author: Romieu Francois <romieu@fr.zoreil.com>
Date: Tue May 2 22:15:34 2006 +0200

ip1000: sanitize the pci device table

- vendor id belong to include/linux/pci_id.h ;
- the pci table does not include all the devices in nics_supported ;
- qualify the pci table as __devinitdata ;
- kill 50 LOC.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

commit e1e773d79369783d68fd7f66fffbe154929df837
Author: Romieu Francois <romieu@fr.zoreil.com>
Date: Tue May 2 01:07:48 2006 +0200

ip1000: plug leaks in the error path of ipg_nic_open

Added ipg_{rx/tx}_clear() to factor out some code.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

commit 9cb655fddfd2d169bc7574e849fa5eb179fef12c
Author: Romieu Francois <romieu@fr.zoreil.com>
Date: Tue May 2 00:15:54 2006 +0200

ip1000: leaks in ipg_probe

The error paths are badly broken.

Bonus:
- remove duplicate initialization of sp;
- remove useless NULL initialization of dev;
- USE_IO_OPS is not used (and the driver does not seem to care about
posted writes, rejoice).

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

commit 2b5d40c1c4cf795c31d2683bcdff646a8984115d
Author: Romieu Francois <romieu@fr.zoreil.com>
Date: Mon May 1 23:52:37 2006 +0200

ip1000: removal of unreachable code

map/unmap is done in ipg_{probe/remove}
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

commit 5b8bde4d4c02e3d54672d0c431941d9357c35417
Author: Romieu Francois <romieu@fr.zoreil.com>
Date: Mon May 1 22:40:29 2006 +0200

ip1000: speed-up access to the PHY registers

Reduce delays when reading/writing the PHY registers so we clock the
MII management interface at 2.5 MHz (the maximum according to the
datasheet) instead of 500 Hz.

Signed-off-by: David Vrabel <dvrabel@cantab.net>

commit d4a621ceadb0e4ee83a644be4ffef8bdef687249
Author: David Vrabel <dvrabel@cantab.net>
Date: Mon May 1 21:34:19 2006 +0200

ip1000: root_dev removal and PHY initialization

- Remove ether_crc_le() -- use crc32_le() instead.
- No more nonsense with root_dev -- ipg_remove() now works.
- Move PHY and MAC address initialization into the ipg_probe().
It was previously filling in the MAC address on open which breaks
some user space.
- Folded ipg_nic_init into ipg_probe since it was broke otherwise.

Signed-off-by: David Vrabel <dvrabel@cantab.net>

commit ae6f7b51bfb69a60062d390f10c83396c37f0301
Author: David Vrabel <dvrabel@cantab.net>
Date: Mon May 1 13:20:49 2006 +0200

ip1000: remove changelogs

Signed-off-by: David Vrabel <dvrabel@cantab.net>

commit 7aeb86e2db5deac7d8357d6d794550999fd5e7c6
Author: Pekka Enberg <penberg@cs.helsinki.fi>
Date: Sun Apr 30 12:45:16 2006 +0300

ip1000: alloc_etherdev already allocates memory for private data

Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>

commit 49b94ecdf8124c988160585d460b1cc643ee07e0
Author: Pekka Enberg <penberg@cs.helsinki.fi>
Date: Sun Apr 30 12:42:02 2006 +0300

ip1000: remove unused forward declarations

Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>

commit e85531a2d8c23b6ff17b3a8cd6d14e6c09954240
Author: Pekka Enberg <penberg@cs.helsinki.fi>
Date: Sun Apr 30 12:16:58 2006 +0300

ip1000: interrupt handler code cleanups

Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>

commit 822b9f528c47df857514e33d1ad98a9a551a3b00
Author: Pekka Enberg <penberg@cs.helsinki.fi>
Date: Sun Apr 30 12:05:09 2006 +0300

ip1000: rename baseaddr to ioaddr

Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>

commit e8e5f8dece06429793074df6f956a8c4cb60c362
Author: Pekka Enberg <penberg@cs.helsinki.fi>
Date: Sun Apr 30 12:02:51 2006 +0300

ip1000: remove device register write macros

Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>

commit 8e1a207d9e0d355aa2949ef4e5710e8c8987b01b
Author: Pekka Enberg <penberg@cs.helsinki.fi>
Date: Sun Apr 30 11:41:01 2006 +0300

ip1000: kill obfuscating register read macros

Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>

commit fd3e0c5b3599375024e1e7fc3ddb00f7f5bc0c53
Author: Pekka Enberg <penberg@cs.helsinki.fi>
Date: Sun Apr 30 00:03:23 2006 +0300

ip1000: use iomap for pio/mmio

Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>

commit 7ed56b01680978afc5db87f684de81398366bf84
Author: Pekka Enberg <penberg@cs.helsinki.fi>
Date: Sat Apr 29 14:02:34 2006 +0300

ip1000: use static for private symbols

Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>

commit b83bac329befd061bb66377d33b1efd4dd39a931
Author: Pekka Enberg <penberg@cs.helsinki.fi>
Date: Sat Apr 29 13:19:36 2006 +0300

ip1000: sparse fixes

Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>

commit 65229dd8a40d887364f3aa60277ac3f0e8c64041
Author: Pekka Enberg <penberg@cs.helsinki.fi>
Date: Sat Apr 29 13:06:27 2006 +0300

ip1000: iomem annotations

Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>

commit d79a8a846188eee278f5b490b7f15c070f1245d4
Author: Pekka Enberg <penberg@cs.helsinki.fi>
Date: Sat Apr 29 12:41:45 2006 +0300

ip1000: new gigabit ethernet device driver

Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>

----------------8<-----------------------------------------------------------
Patch of the day:

The patch shoehorns the driver into the usual mii/ethtool framework.
mii_mutex will prove useful when the link management tasks issued in
irq context are moved to user/workqueue context. Next step.

At least the current code should not be _too_ broken.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

---
drivers/net/ipg.c | 344 ++++++++++++++++++++---------------------------------
drivers/net/ipg.h | 3
2 files changed, 130 insertions(+), 217 deletions(-)
8e15d782fa4a0f483a71faec7ba17697d9397e76
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c
index 31cde6c..5d19269 100644
--- a/drivers/net/ipg.c
+++ b/drivers/net/ipg.c
@@ -15,7 +15,9 @@
* craig_rich@sundanceti.com
*/
#include <linux/crc32.h>
+#include <linux/ethtool.h>
#include <linux/mii.h>
+#include <linux/mutex.h>

#define IPG_RX_RING_BYTES (sizeof(struct RFD) * IPG_RFDLIST_LENGTH)
#define IPG_TX_RING_BYTES (sizeof(struct TFD) * IPG_TFDLIST_LENGTH)
@@ -161,8 +163,7 @@ static u16 read_phy_bit(void __iomem * i
return bit_data;
}

-u16 read_phy_register(struct net_device * dev,
- int phy_address, int phy_register)
+static int mdio_read(struct net_device * dev, int phy_address, int phy_register)
{
/* Read a register from the Physical Layer device located
* on the IPG NIC, using the IPG PHYCTRL register.
@@ -176,7 +177,7 @@ u16 read_phy_register(struct net_device
u8 databit;
u8 phyctrlpolarity;

- IPG_DEBUG_MSG("read_phy_register\n");
+ IPG_DEBUG_MSG("mdio_read\n");

/* The GMII mangement frame structure for a read is as follows:
*
@@ -274,8 +275,8 @@ u16 read_phy_register(struct net_device
return field[6];
}

-static void write_phy_register(struct net_device *dev,
- int phy_address, int phy_register, u16 writeval)
+static void mdio_write(struct net_device *dev,
+ int phy_address, int phy_register, int val)
{
/* Write to a register from the Physical Layer device located
* on the IPG NIC, using the IPG PHYCTRL register.
@@ -289,7 +290,7 @@ static void write_phy_register(struct ne
u8 databit;
u8 phyctrlpolarity;

- IPG_DEBUG_MSG("write_phy_register\n");
+ IPG_DEBUG_MSG("mdio_write\n");

/* The GMII mangement frame structure for a read is as follows:
*
@@ -318,7 +319,7 @@ static void write_phy_register(struct ne
fieldlen[4] = 5; /* REGAD */
field[5] = 0x0002;
fieldlen[5] = 2; /* TA */
- field[6] = writeval;
+ field[6] = val & 0xffff;
fieldlen[6] = 16; /* DATA */
field[7] = 0x0000;
fieldlen[7] = 1; /* IDLE */
@@ -486,7 +487,7 @@ static int ipg_tmi_fiber_detect(struct n

IPG_DEBUG_MSG("_tmi_fiber_detect\n");

- phyid = read_phy_register(dev, phyaddr, MII_PHYSID1);
+ phyid = mdio_read(dev, phyaddr, MII_PHYSID1);

IPG_DEBUG_MSG("PHY ID = %x\n", phyid);

@@ -497,15 +498,14 @@ static int ipg_tmi_fiber_detect(struct n
}
#endif

+/* Find the GMII PHY address. */
static int ipg_find_phyaddr(struct net_device *dev)
{
- /* Find the GMII PHY address. */
-
- int i;
- int phyaddr;
- u32 status;
+ int phyaddr, i;

for (i = 0; i < 32; i++) {
+ u32 status;
+
/* Search for the correct PHY address among 32 possible. */
phyaddr = (IPG_NIC_PHY_ADDRESS + i) % 32;

@@ -513,13 +513,13 @@ static int ipg_find_phyaddr(struct net_d
GMII_PHY_ID1
*/

- status = read_phy_register(dev, phyaddr, MII_BMSR);
+ status = mdio_read(dev, phyaddr, MII_BMSR);

if ((status != 0xFFFF) && (status != 0))
return phyaddr;
}

- return -1;
+ return 0x1f;
}

#ifdef NOTGRACE
@@ -618,10 +618,11 @@ #endif
dev->name);
return -EILSEQ;
}
+ sp->mii_if.phy_id = phyaddr;

IPG_DEBUG_MSG("GMII/MII PHY address = %x\n", phyaddr);

- status = read_phy_register(dev, phyaddr, MII_BMSR);
+ status = mdio_read(dev, phyaddr, MII_BMSR);

printk("PHYStatus = %x \n", status);
if ((status & BMSR_ANEGCAPABLE) == 0) {
@@ -631,8 +632,8 @@ #endif
return -EILSEQ;
}

- advertisement = read_phy_register(dev, phyaddr, MII_ADVERTISE);
- linkpartner_ability = read_phy_register(dev, phyaddr, MII_LPA);
+ advertisement = mdio_read(dev, phyaddr, MII_ADVERTISE);
+ linkpartner_ability = mdio_read(dev, phyaddr, MII_LPA);

printk("PHYadvertisement=%x LinkPartner=%x \n", advertisement,
linkpartner_ability);
@@ -660,8 +661,8 @@ #endif
/* In 1000BASE-X using IPG's internal PCS
* layer, so write to the GMII duplex bit.
*/
- write_phy_register(dev, phyaddr, MII_BMCR,
- read_phy_register(dev, phyaddr, MII_BMCR) |
+ mdio_write(dev, phyaddr, MII_BMCR,
+ mdio_read(dev, phyaddr, MII_BMCR) |
ADVERTISE_1000HALF); // Typo ?

} else {
@@ -670,8 +671,8 @@ #endif
/* In 1000BASE-X using IPG's internal PCS
* layer, so write to the GMII duplex bit.
*/
- write_phy_register(dev, phyaddr, MII_BMCR,
- read_phy_register(dev, phyaddr, MII_BMCR) &
+ mdio_write(dev, phyaddr, MII_BMCR,
+ mdio_read(dev, phyaddr, MII_BMCR) &
~ADVERTISE_1000HALF); // Typo ?
}
}
@@ -683,10 +684,8 @@ #endif
* link partner abilities exchanged via next page
* transfers.
*/
- gigadvertisement =
- read_phy_register(dev, phyaddr, MII_CTRL1000);
- giglinkpartner_ability =
- read_phy_register(dev, phyaddr, MII_STAT1000);
+ gigadvertisement = mdio_read(dev, phyaddr, MII_CTRL1000);
+ giglinkpartner_ability = mdio_read(dev, phyaddr, MII_STAT1000);

/* Compare the full duplex bits in the 1000BASE-T GMII
* registers for the local device, and the link partner.
@@ -795,11 +794,10 @@ #define LPA_PAUSE_ANY (LPA_1000XPAUSE_AS
/* PAUSE is not being advertised. Advertise
* PAUSE and restart auto-negotiation.
*/
- write_phy_register(dev, phyaddr, MII_ADVERTISE,
+ mdio_write(dev, phyaddr, MII_ADVERTISE,
(advertisement |
ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM));
- write_phy_register(dev, phyaddr, MII_BMCR,
- BMCR_ANRESTART);
+ mdio_write(dev, phyaddr, MII_BMCR, BMCR_ANRESTART);

return -EAGAIN;
}
@@ -845,10 +843,9 @@ #define LPA_PAUSE_ANY (LPA_1000XPAUSE_AS
/* PAUSE is not being advertised. Advertise
* PAUSE and restart auto-negotiation.
*/
- write_phy_register(dev, phyaddr, MII_ADVERTISE,
- advertisement | ADVERTISE_PAUSE_CAP);
- write_phy_register(dev, phyaddr, MII_BMCR,
- BMCR_ANRESTART);
+ mdio_write(dev, phyaddr, MII_ADVERTISE,
+ advertisement | ADVERTISE_PAUSE_CAP);
+ mdio_write(dev, phyaddr, MII_BMCR, BMCR_ANRESTART);
return -EAGAIN;
}

@@ -2671,8 +2668,7 @@ static void ipg_set_phy_default_param(un
address = *phy_param;
value = *(phy_param + 1);
phy_param += 2;
- write_phy_register(dev,
- phy_address, address, value);
+ mdio_write(dev, phy_address, address, value);
length -= 4;
}

@@ -2710,14 +2706,47 @@ static int read_eeprom(struct net_device
return ret;
}

+static void ipg_init_mii(struct net_device *dev)
+{
+ struct ipg_nic_private *sp = netdev_priv(dev);
+ struct mii_if_info *mii_if = &sp->mii_if;
+ int phyaddr;
+
+ mii_if->dev = dev;
+ mii_if->mdio_read = mdio_read;
+ mii_if->mdio_write = mdio_write;
+ mii_if->phy_id_mask = 0x1f;
+ mii_if->reg_num_mask = 0x1f;
+
+ mii_if->phy_id = phyaddr = ipg_find_phyaddr(dev);
+
+ if (phyaddr != 0x1f) {
+ u16 mii_phyctrl, mii_1000cr;
+ u8 revisionid = 0;
+
+ mii_1000cr = mdio_read(dev, phyaddr, MII_CTRL1000);
+ mii_1000cr |= ADVERTISE_1000FULL | ADVERTISE_1000HALF |
+ GMII_PHY_1000BASETCONTROL_PreferMaster;
+ mdio_write(dev, phyaddr, MII_CTRL1000, mii_1000cr);
+
+ mii_phyctrl = mdio_read(dev, phyaddr, MII_BMCR);
+
+ /* Set default phyparam */
+ pci_read_config_byte(sp->pdev, PCI_REVISION_ID, &revisionid);
+ ipg_set_phy_default_param(revisionid, dev, phyaddr);
+
+ /* Reset PHY */
+ mii_phyctrl |= BMCR_RESET | BMCR_ANRESTART;
+ mdio_write(dev, phyaddr, MII_BMCR, mii_phyctrl);
+
+ }
+}
+
static int ipg_hw_init(struct net_device *dev)
{
- int phyaddr = 0;
- int error = 0;
- int i;
- void __iomem *ioaddr = ipg_ioaddr(dev);
- u8 revisionid = 0;
struct ipg_nic_private *sp = netdev_priv(dev);
+ void __iomem *ioaddr = sp->ioaddr;
+ int i, rc;

/* Reset all functions within the IPG. Do not assert
* RST_OUT as not compatible with some PHYs.
@@ -2729,34 +2758,11 @@ static int ipg_hw_init(struct net_device
/* Read LED Mode Configuration from EEPROM */
sp->LED_Mode = read_eeprom(dev, 6);

- error = ipg_reset(dev, i);
- if (error < 0) {
- return error;
- }
-
- ioaddr = ipg_ioaddr(dev);
-
- /* Reset PHY. */
- phyaddr = ipg_find_phyaddr(dev);
-
- if (phyaddr != -1) {
- u16 mii_phyctrl, mii_1000cr;
- mii_1000cr =
- read_phy_register(dev, phyaddr, MII_CTRL1000);
- write_phy_register(dev, phyaddr, MII_CTRL1000,
- mii_1000cr | ADVERTISE_1000FULL | ADVERTISE_1000HALF |
- GMII_PHY_1000BASETCONTROL_PreferMaster);
-
- mii_phyctrl = read_phy_register(dev, phyaddr, MII_BMCR);
- /* Set default phyparam */
- pci_read_config_byte(sp->pdev, PCI_REVISION_ID, &revisionid);
- ipg_set_phy_default_param(revisionid, dev, phyaddr);
-
- /* reset Phy */
- write_phy_register(dev, phyaddr, MII_BMCR,
- (mii_phyctrl | BMCR_RESET | BMCR_ANRESTART));
+ rc = ipg_reset(dev, i);
+ if (rc < 0)
+ goto out;

- }
+ ipg_init_mii(dev);

/* Read MAC Address from EERPOM Jesse20040128EEPROM_VALUE */
sp->StationAddr0 = read_eeprom(dev, 16);
@@ -2774,161 +2780,21 @@ static int ipg_hw_init(struct net_device
dev->dev_addr[3] = (ioread16(ioaddr + STATION_ADDRESS_1) & 0xff00) >> 8;
dev->dev_addr[4] = ioread16(ioaddr + STATION_ADDRESS_2) & 0x00ff;
dev->dev_addr[5] = (ioread16(ioaddr + STATION_ADDRESS_2) & 0xff00) >> 8;
-
- return 0;
+out:
+ return rc;
}

-static int ipg_nic_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
+static int ipg_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
- /* IOCTL commands for IPG NIC.
- *
- * SIOCDEVPRIVATE nothing
- * SIOCDEVPRIVATE+1 register read
- * ifr_data[0] = 0x08, 0x10, 0x20
- * ifr_data[1] = register offset
- * ifr_data[2] = value read
- * SIOCDEVPRIVATE+2 register write
- * ifr_data[0] = 0x08, 0x10, 0x20
- * ifr_data[1] = register offset
- * ifr_data[2] = value to write
- * SIOCDEVPRIVATE+3 GMII register read
- * ifr_data[1] = register offset
- * SIOCDEVPRIVATE+4 GMII register write
- * ifr_data[1] = register offset
- * ifr_data[2] = value to write
- * SIOCDEVPRIVATE+5 PCI register read
- * ifr_data[0] = 0x08, 0x10, 0x20
- * ifr_data[1] = register offset
- * ifr_data[2] = value read
- * SIOCDEVPRIVATE+6 PCI register write
- * ifr_data[0] = 0x08, 0x10, 0x20
- * ifr_data[1] = register offset
- * ifr_data[2] = value to write
- *
- */
-
- u8 val8;
- u16 val16;
- u32 val32;
- unsigned int *data;
- int phyaddr = 0;
- void __iomem *ioaddr = ipg_ioaddr(dev);
struct ipg_nic_private *sp = netdev_priv(dev);
+ struct mii_ioctl_data *data = if_mii(ifr);
+ int rc;

- IPG_DEBUG_MSG("_nic_do_ioctl\n");
-
- data = (unsigned int *)&req->ifr_data;
-
- switch (cmd) {
- case SIOCDEVPRIVATE:
- return 0;
-
- case SIOCDEVPRIVATE + 1:
- switch (data[0]) {
- case 0x08:
- data[2] = ioread8(ioaddr + data[1]);
- return 0;
-
- case 0x10:
- data[2] = ioread16(ioaddr + data[1]);
- return 0;
-
- case 0x20:
- data[2] = ioread32(ioaddr + data[1]);
- return 0;
-
- default:
- data[2] = 0x00;
- return -EINVAL;
- }
-
- case SIOCDEVPRIVATE + 2:
- switch (data[0]) {
- case 0x08:
- iowrite8(data[2], ioaddr + data[1]);
- return 0;
-
- case 0x10:
- iowrite16(data[2], ioaddr + data[1]);
- return 0;
-
- case 0x20:
- iowrite32(data[2], ioaddr + data[1]);
- return 0;
-
- default:
- return -EINVAL;
- }
-
- case SIOCDEVPRIVATE + 3:
- phyaddr = ipg_find_phyaddr(dev);
-
- if (phyaddr == -1)
- return -EINVAL;
-
- data[2] = read_phy_register(dev, phyaddr, data[1]);
-
- return 0;
-
- case SIOCDEVPRIVATE + 4:
- phyaddr = ipg_find_phyaddr(dev);
-
- if (phyaddr == -1)
- return -EINVAL;
-
- write_phy_register(dev, phyaddr, data[1], (u16) data[2]);
-
- return 0;
-
- case SIOCDEVPRIVATE + 5:
- switch (data[0]) {
- case 0x08:
- pci_read_config_byte(sp->pdev, data[1], &val8);
- data[2] = (unsigned int)val8;
- return 0;
-
- case 0x10:
- pci_read_config_word(sp->pdev, data[1], &val16);
- data[2] = (unsigned int)val16;
- return 0;
-
- case 0x20:
- pci_read_config_dword(sp->pdev, data[1], &val32);
- data[2] = (unsigned int)val32;
- return 0;
-
- default:
- data[2] = 0x00;
- return -EINVAL;
- }
-
- case SIOCDEVPRIVATE + 6:
- switch (data[0]) {
- case 0x08:
- pci_write_config_byte(sp->pdev, data[1], (u8) data[2]);
- return 0;
-
- case 0x10:
- pci_write_config_word(sp->pdev, data[1], (u16) data[2]);
- return 0;
-
- case 0x20:
- pci_write_config_dword(sp->pdev, data[1],
- (u32) data[2]);
- return 0;
+ mutex_lock(&sp->mii_mutex);
+ rc = generic_mii_ioctl(&sp->mii_if, data, cmd, NULL);
+ mutex_unlock(&sp->mii_mutex);

- default:
- return -EINVAL;
- }
-
- case SIOCSIFMTU:
- {
- return 0;
- }
-
- default:
- return -EOPNOTSUPP;
- }
+ return rc;
}

static int ipg_nic_change_mtu(struct net_device *dev, int new_mtu)
@@ -2953,6 +2819,48 @@ static int ipg_nic_change_mtu(struct net
return 0;
}

+static int ipg_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct ipg_nic_private *sp = netdev_priv(dev);
+ int rc;
+
+ mutex_lock(&sp->mii_mutex);
+ rc = mii_ethtool_gset(&sp->mii_if, cmd);
+ mutex_unlock(&sp->mii_mutex);
+
+ return rc;
+}
+
+static int ipg_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct ipg_nic_private *sp = netdev_priv(dev);
+ int rc;
+
+ mutex_lock(&sp->mii_mutex);
+ rc = mii_ethtool_sset(&sp->mii_if, cmd);
+ mutex_unlock(&sp->mii_mutex);
+
+ return rc;
+}
+
+static int ipg_nway_reset(struct net_device *dev)
+{
+ struct ipg_nic_private *sp = netdev_priv(dev);
+ int rc;
+
+ mutex_lock(&sp->mii_mutex);
+ rc = mii_nway_restart(&sp->mii_if);
+ mutex_unlock(&sp->mii_mutex);
+
+ return rc;
+}
+
+static struct ethtool_ops ipg_ethtool_ops = {
+ .get_settings = ipg_get_settings,
+ .set_settings = ipg_set_settings,
+ .nway_reset = ipg_nway_reset,
+};
+
static void ipg_remove(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
@@ -3011,6 +2919,7 @@ static int __devinit ipg_probe(struct pc

sp = netdev_priv(dev);
spin_lock_init(&sp->lock);
+ mutex_init(&sp->mii_mutex);

/* Declare IPG NIC functions for Ethernet device methods.
*/
@@ -3019,11 +2928,12 @@ static int __devinit ipg_probe(struct pc
dev->hard_start_xmit = &ipg_nic_hard_start_xmit;
dev->get_stats = &ipg_nic_get_stats;
dev->set_multicast_list = &ipg_nic_set_multicast_list;
- dev->do_ioctl = &ipg_nic_do_ioctl;
+ dev->do_ioctl = ipg_ioctl;
dev->change_mtu = &ipg_nic_change_mtu;

SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
+ SET_ETHTOOL_OPS(dev, &ipg_ethtool_ops);

rc = pci_request_regions(pdev, DRV_NAME);
if (rc)
diff --git a/drivers/net/ipg.h b/drivers/net/ipg.h
index 6c55b0b..58b1417 100644
--- a/drivers/net/ipg.h
+++ b/drivers/net/ipg.h
@@ -870,6 +870,9 @@ #endif
u16 StationAddr1; /* Station Address in EEPROM Reg 0x11 */
u16 StationAddr2; /* Station Address in EEPROM Reg 0x12 */

+ struct mutex mii_mutex;
+ struct mii_if_info mii_if;
+
#ifdef IPG_DEBUG
int TFDunavailCount;
int RFDlistendCount;
--
1.3.1
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2006-05-05 02:02    [W:0.291 / U:0.024 seconds]
©2003-2011 Jasper Spaans