@@ -157,6 +157,9 @@ enum {
157157#define NVREG_XMITCTL_HOST_SEMA_ACQ 0x0000f000
158158#define NVREG_XMITCTL_HOST_LOADED 0x00004000
159159#define NVREG_XMITCTL_TX_PATH_EN 0x01000000
160+ #define NVREG_XMITCTL_DATA_START 0x00100000
161+ #define NVREG_XMITCTL_DATA_READY 0x00010000
162+ #define NVREG_XMITCTL_DATA_ERROR 0x00020000
160163 NvRegTransmitterStatus = 0x088 ,
161164#define NVREG_XMITSTAT_BUSY 0x01
162165
@@ -289,8 +292,10 @@ enum {
289292#define NVREG_WAKEUPFLAGS_ACCEPT_LINKCHANGE 0x04
290293#define NVREG_WAKEUPFLAGS_ENABLE 0x1111
291294
292- NvRegPatternCRC = 0x204 ,
293- NvRegPatternMask = 0x208 ,
295+ NvRegMgmtUnitGetVersion = 0x204 ,
296+ #define NVREG_MGMTUNITGETVERSION 0x01
297+ NvRegMgmtUnitVersion = 0x208 ,
298+ #define NVREG_MGMTUNITVERSION 0x08
294299 NvRegPowerCap = 0x268 ,
295300#define NVREG_POWERCAP_D3SUPP (1<<30)
296301#define NVREG_POWERCAP_D2SUPP (1<<26)
@@ -303,6 +308,8 @@ enum {
303308#define NVREG_POWERSTATE_D1 0x0001
304309#define NVREG_POWERSTATE_D2 0x0002
305310#define NVREG_POWERSTATE_D3 0x0003
311+ NvRegMgmtUnitControl = 0x278 ,
312+ #define NVREG_MGMTUNITCONTROL_INUSE 0x20000
306313 NvRegTxCnt = 0x280 ,
307314 NvRegTxZeroReXmt = 0x284 ,
308315 NvRegTxOneReXmt = 0x288 ,
@@ -758,6 +765,8 @@ struct fe_priv {
758765 u32 register_size ;
759766 int rx_csum ;
760767 u32 mac_in_use ;
768+ int mgmt_version ;
769+ int mgmt_sema ;
761770
762771 void __iomem * base ;
763772
@@ -5182,6 +5191,7 @@ static void nv_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
51825191/* The mgmt unit and driver use a semaphore to access the phy during init */
51835192static int nv_mgmt_acquire_sema (struct net_device * dev )
51845193{
5194+ struct fe_priv * np = netdev_priv (dev );
51855195 u8 __iomem * base = get_hwbase (dev );
51865196 int i ;
51875197 u32 tx_ctrl , mgmt_sema ;
@@ -5204,15 +5214,62 @@ static int nv_mgmt_acquire_sema(struct net_device *dev)
52045214 /* verify that semaphore was acquired */
52055215 tx_ctrl = readl (base + NvRegTransmitterControl );
52065216 if (((tx_ctrl & NVREG_XMITCTL_HOST_SEMA_MASK ) == NVREG_XMITCTL_HOST_SEMA_ACQ ) &&
5207- ((tx_ctrl & NVREG_XMITCTL_MGMT_SEMA_MASK ) == NVREG_XMITCTL_MGMT_SEMA_FREE ))
5217+ ((tx_ctrl & NVREG_XMITCTL_MGMT_SEMA_MASK ) == NVREG_XMITCTL_MGMT_SEMA_FREE )) {
5218+ np -> mgmt_sema = 1 ;
52085219 return 1 ;
5220+ }
52095221 else
52105222 udelay (50 );
52115223 }
52125224
52135225 return 0 ;
52145226}
52155227
5228+ static void nv_mgmt_release_sema (struct net_device * dev )
5229+ {
5230+ struct fe_priv * np = netdev_priv (dev );
5231+ u8 __iomem * base = get_hwbase (dev );
5232+ u32 tx_ctrl ;
5233+
5234+ if (np -> driver_data & DEV_HAS_MGMT_UNIT ) {
5235+ if (np -> mgmt_sema ) {
5236+ tx_ctrl = readl (base + NvRegTransmitterControl );
5237+ tx_ctrl &= ~NVREG_XMITCTL_HOST_SEMA_ACQ ;
5238+ writel (tx_ctrl , base + NvRegTransmitterControl );
5239+ }
5240+ }
5241+ }
5242+
5243+
5244+ static int nv_mgmt_get_version (struct net_device * dev )
5245+ {
5246+ struct fe_priv * np = netdev_priv (dev );
5247+ u8 __iomem * base = get_hwbase (dev );
5248+ u32 data_ready = readl (base + NvRegTransmitterControl );
5249+ u32 data_ready2 = 0 ;
5250+ unsigned long start ;
5251+ int ready = 0 ;
5252+
5253+ writel (NVREG_MGMTUNITGETVERSION , base + NvRegMgmtUnitGetVersion );
5254+ writel (data_ready ^ NVREG_XMITCTL_DATA_START , base + NvRegTransmitterControl );
5255+ start = jiffies ;
5256+ while (time_before (jiffies , start + 5 * HZ )) {
5257+ data_ready2 = readl (base + NvRegTransmitterControl );
5258+ if ((data_ready & NVREG_XMITCTL_DATA_READY ) != (data_ready2 & NVREG_XMITCTL_DATA_READY )) {
5259+ ready = 1 ;
5260+ break ;
5261+ }
5262+ schedule_timeout_uninterruptible (1 );
5263+ }
5264+
5265+ if (!ready || (data_ready2 & NVREG_XMITCTL_DATA_ERROR ))
5266+ return 0 ;
5267+
5268+ np -> mgmt_version = readl (base + NvRegMgmtUnitVersion ) & NVREG_MGMTUNITVERSION ;
5269+
5270+ return 1 ;
5271+ }
5272+
52165273static int nv_open (struct net_device * dev )
52175274{
52185275 struct fe_priv * np = netdev_priv (dev );
@@ -5784,19 +5841,26 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
57845841
57855842 if (id -> driver_data & DEV_HAS_MGMT_UNIT ) {
57865843 /* management unit running on the mac? */
5787- if (readl (base + NvRegTransmitterControl ) & NVREG_XMITCTL_SYNC_PHY_INIT ) {
5788- np -> mac_in_use = readl (base + NvRegTransmitterControl ) & NVREG_XMITCTL_MGMT_ST ;
5789- dprintk (KERN_INFO "%s: mgmt unit is running. mac in use %x.\n" , pci_name (pci_dev ), np -> mac_in_use );
5790- if (nv_mgmt_acquire_sema (dev )) {
5791- /* management unit setup the phy already? */
5792- if ((readl (base + NvRegTransmitterControl ) & NVREG_XMITCTL_SYNC_MASK ) ==
5793- NVREG_XMITCTL_SYNC_PHY_INIT ) {
5794- /* phy is inited by mgmt unit */
5795- phyinitialized = 1 ;
5796- dprintk (KERN_INFO "%s: Phy already initialized by mgmt unit.\n" , pci_name (pci_dev ));
5797- } else {
5798- /* we need to init the phy */
5799- }
5844+ if ((readl (base + NvRegTransmitterControl ) & NVREG_XMITCTL_MGMT_ST ) &&
5845+ (readl (base + NvRegTransmitterControl ) & NVREG_XMITCTL_SYNC_PHY_INIT ) &&
5846+ nv_mgmt_acquire_sema (dev ) &&
5847+ nv_mgmt_get_version (dev )) {
5848+ np -> mac_in_use = 1 ;
5849+ if (np -> mgmt_version > 0 ) {
5850+ np -> mac_in_use = readl (base + NvRegMgmtUnitControl ) & NVREG_MGMTUNITCONTROL_INUSE ;
5851+ }
5852+ dprintk (KERN_INFO "%s: mgmt unit is running. mac in use %x.\n" ,
5853+ pci_name (pci_dev ), np -> mac_in_use );
5854+ /* management unit setup the phy already? */
5855+ if (np -> mac_in_use &&
5856+ ((readl (base + NvRegTransmitterControl ) & NVREG_XMITCTL_SYNC_MASK ) ==
5857+ NVREG_XMITCTL_SYNC_PHY_INIT )) {
5858+ /* phy is inited by mgmt unit */
5859+ phyinitialized = 1 ;
5860+ dprintk (KERN_INFO "%s: Phy already initialized by mgmt unit.\n" ,
5861+ pci_name (pci_dev ));
5862+ } else {
5863+ /* we need to init the phy */
58005864 }
58015865 }
58025866 }
@@ -5958,6 +6022,8 @@ static void __devexit nv_remove(struct pci_dev *pci_dev)
59586022 /* restore any phy related changes */
59596023 nv_restore_phy (dev );
59606024
6025+ nv_mgmt_release_sema (dev );
6026+
59616027 /* free all structures */
59626028 free_rings (dev );
59636029 iounmap (get_hwbase (dev ));
0 commit comments