| To: | James Chapman <jchapman@xxxxxxxxxxx> |
|---|---|
| Subject: | Re: RFC: PHY Abstraction Layer II |
| From: | Andy Fleming <afleming@xxxxxxxxxxxxx> |
| Date: | Fri, 18 Mar 2005 17:14:19 -0600 |
| Cc: | netdev@xxxxxxxxxxx, "David S. Miller" <davem@xxxxxxxxxxxxx>, linuxppc-embedded@xxxxxxxxxx, Benjamin Herrenschmidt <benh@xxxxxxxxxxxxxxxxxxx> |
| In-reply-to: | <423734FB.40101@katalix.com> |
| References: | <1107b64b01fb8e9a6c84359bb56881a6@freescale.com> <1110334456.32556.21.camel@gaston> <20050308194229.41c23707.davem@davemloft.net> <1110340214.32524.32.camel@gaston> <57a429f8eb807987d88b06129861d507@freescale.com> <4230D1AC.5070506@katalix.com> <ba5d844255b5ba76b2685f9397faf689@freescale.com> <423734FB.40101@katalix.com> |
| Sender: | netdev-bounce@xxxxxxxxxxx |
Hi Andy,
Well, I didn't want to interfere with mii.c, since so many drivers use it already. This code is designed to be separate to not break anything, but also to serve as a superset of the mii.c functionality. So I think the PHY code should add the functionality provided by these functions: int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd) int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd) int generic_mii_ioctl(struct mii_if_info *mii_if, struct mii_ioctl_data *mii_data, int cmd, unsigned int *duplex_chg_out) While these functions are already handled by the existing PHY code: unsigned int mii_check_media (struct mii_if_info *mii, unsigned int ok_to_print, unsigned int init_media) // determines duplex/speed int mii_link_ok (struct mii_if_info *mii) // returns link status int mii_nway_restart (struct mii_if_info *mii) // does this do anything? void mii_check_link (struct mii_if_info *mii) // reads link, and updates carrier
For handling such interrupts, there are two options I can see: 1) Let the PHY code share the interrupt, and it will handle it, then the enet driver can clear it. 2) Have the enet code handle the interrupt. This is more difficult, in that it is absolutely verboten to access the PHYs from interrupt time. The reason I did this is to allow for PHY read/write mechanisms which block until an interrupt signals the operation is complete. 3) Set the PHY to poll. This is simple, just set phydev->irq to -1 before you call phy_start(). I will make sure to document this.
Ok. The reason I didn't do this (actually, I did, and then changed it) was to allow drivers which weren't net devices to use the code. I didn't have a particular use in mind. If no one thinks that would be useful (I'm not sure I do), then I will change it back.
The phy interrupt is a bit awkward. For the reasons mentioned above, I can't call phy read/write functions from interrupt context. The lock on phydev->state has the same issue. So the interrupt handler just disables the interrupt (because otherwise the PHY keeps generating it), and schedules a task to clear the interrupt, and tell the state machine there's a change. That task just sets phydev->state to CHANGELINK. When interrupts are being used, this is the only way state gets updated. When interrupts are off, this state gets hit every other interval (2 seconds, total).
int link_timeout; struct work_struct phy_queue; struct timer_list phy_timer; I'm not convinced it's worth creating a new file, and adding a new level of indirection for these three fields. However, I do see a couple function prototypes which probably could move into the C files, since they are internal functions: void phy_change(void *data); void phy_timer(unsigned long data); The rest of the functions and fields are public. Especially in the early stages of its existence, when I would hate to lock someone out of using the code in a certain way before it's clear what the best ways to use it are.
This code is there for the case where someone manually sets their controller to a certain speed/duplex setting which doesn't work. The sanitize function makes sure that the next highest setting supported by the PHY is chosen, and the force function is used to choose a new setting if the selected setting did not achieve a link. I added this functionality to enable recoverability (eg - when I change the setting on an NFS-rooted system, and choose one that doesn't work with the network I am on. This way, the network will eventually come up again)
Yeah. I think I got stuck in the mode, early on, when I was writing some functions for which their parameters weren't intuitively obvious. For consistency, I ended up with a lot of functions with: phydev: The phy device Which is really just a waste of space. I will attempt to prune out the ones I feel are obvious without the comment.
Andy |
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| ||
| Previous by Date: | Re: Reproducible panics with tulip, Francois Romieu |
|---|---|
| Next by Date: | [PATCH] remove unused netlink NL_EMULATE_DEV code, Chris Wright |
| Previous by Thread: | Re: RFC: PHY Abstraction Layer II, James Chapman |
| Next by Thread: | Re: RFC: PHY Abstraction Layer II, Andy Fleming |
| Indexes: | [Date] [Thread] [Top] [All Lists] |