Hi Francois, Thanks for your feedback, I have a few questions.
> > + return serviced; > > +} > > + > > +/* Autodetects and initialises external phy for SMSC9115 and SMSC9117 flavors. > > + * If something goes wrong, returns -ENODEV to revert back to internal phy. */ > > +static int smsc911x_phy_initialise_external(struct smsc911x_data *pdata) > > +{ > > + unsigned int address; > > + unsigned int hwcfg; > > + unsigned int phyid1; > > + unsigned int phyid2; > > + > > + hwcfg = smsc911x_reg_read(pdata, HW_CFG); > > + > > + /* External phy is requested, supported, and detected */ > > + if (hwcfg & HW_CFG_EXT_PHY_DET_) { > > + > > + /* Attempt to switch to external phy for auto-detecting > > + * its address. Assuming tx and rx are stopped because > > + * smsc911x_phy_initialise is called before > > + * smsc911x_rx_initialise and tx_initialise. > > + */ > > + > > + /* Disable phy clocks to the MAC */ > > + hwcfg &= (~HW_CFG_PHY_CLK_SEL_); > > + hwcfg |= HW_CFG_PHY_CLK_SEL_CLK_DIS_; > > + smsc911x_reg_write(hwcfg, pdata, HW_CFG); > > + udelay(10); /* Enough time for clocks to stop */ > > I assume that writes are never posted, right ? > I don't understand the question, what do you mean? > > +static void smsc911x_rx_multicast_update(struct smsc911x_data *pdata) > > +{ > > + unsigned long flags; > > + unsigned int timeout; > > + unsigned int mac_cr; > > + > > + /* This function is only called for older LAN911x devices > > + * (revA or revB), where MAC_CR, HASHH and HASHL should not > > + * be modified during Rx - newer devices immediately update the > > + * registers */ > > + > > + local_irq_save(flags); > > + > > + /* Stop Rx */ > > + mac_cr = smsc911x_mac_read(pdata, MAC_CR); > > + mac_cr &= ~(MAC_CR_RXEN_); > > + smsc911x_mac_write(pdata, MAC_CR, mac_cr); > > + > > + /* Poll until Rx has stopped. If a frame is being recieved, this will > > + * block until the end of this frame. (this may take a long time at > > + * 10Mbps) */ > > + timeout = 2000; > > + while ((timeout--) > > + && (!(smsc911x_reg_read(pdata, INT_STS) & INT_STS_RXSTOP_INT_))) { > > + udelay(1); > > > In a completely ideal world the driver would probably race outside of an > irq disabled section until it grabs the napi poll handler, thus preserving > the nice low latency property of the kernel. > > Nevermind :o} Agreed, I would like to find a nicer way to do this. It's a nasty workaround to a nasty hardware issue :o} There are two problems. First, on older hardware revisions the multicast hash filters (as well as the promisc flag) cannot be modified while rx is active (bad things might happen). There is an interrupt which can be used to indicate RX has stopped, but on early hardware this is not 100% reliable. The current solution is the simplest option, and works. A better way could be to use the RX_STOP interrupt, but also schedule a task to run later "just in case"? Best Regards, -- Steve Glendinning SMSC GmbH m: +44 777 933 9124 e: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html