37
37
#include <linux/io.h>
38
38
#include <linux/kernel.h>
39
39
#include <linux/module.h>
40
+ #include <linux/mii.h>
40
41
#include <linux/netdevice.h>
41
42
#include <linux/of_device.h>
42
43
#include <linux/of_mdio.h>
@@ -96,6 +97,27 @@ static inline u32 tse_tx_avail(struct altera_tse_private *priv)
96
97
return priv -> tx_cons + priv -> tx_ring_size - priv -> tx_prod - 1 ;
97
98
}
98
99
100
+ /* PCS Register read/write functions
101
+ */
102
+ static u16 sgmii_pcs_read (struct altera_tse_private * priv , int regnum )
103
+ {
104
+ return csrrd32 (priv -> mac_dev ,
105
+ tse_csroffs (mdio_phy0 ) + regnum * 4 ) & 0xffff ;
106
+ }
107
+
108
+ static void sgmii_pcs_write (struct altera_tse_private * priv , int regnum ,
109
+ u16 value )
110
+ {
111
+ csrwr32 (value , priv -> mac_dev , tse_csroffs (mdio_phy0 ) + regnum * 4 );
112
+ }
113
+
114
+ /* Check PCS scratch memory */
115
+ static int sgmii_pcs_scratch_test (struct altera_tse_private * priv , u16 value )
116
+ {
117
+ sgmii_pcs_write (priv , SGMII_PCS_SCRATCH , value );
118
+ return (sgmii_pcs_read (priv , SGMII_PCS_SCRATCH ) == value );
119
+ }
120
+
99
121
/* MDIO specific functions
100
122
*/
101
123
static int altera_tse_mdio_read (struct mii_bus * bus , int mii_id , int regnum )
@@ -1083,6 +1105,66 @@ static void tse_set_rx_mode(struct net_device *dev)
1083
1105
spin_unlock (& priv -> mac_cfg_lock );
1084
1106
}
1085
1107
1108
+ /* Initialise (if necessary) the SGMII PCS component
1109
+ */
1110
+ static int init_sgmii_pcs (struct net_device * dev )
1111
+ {
1112
+ struct altera_tse_private * priv = netdev_priv (dev );
1113
+ int n ;
1114
+ unsigned int tmp_reg = 0 ;
1115
+
1116
+ if (priv -> phy_iface != PHY_INTERFACE_MODE_SGMII )
1117
+ return 0 ; /* Nothing to do, not in SGMII mode */
1118
+
1119
+ /* The TSE SGMII PCS block looks a little like a PHY, it is
1120
+ * mapped into the zeroth MDIO space of the MAC and it has
1121
+ * ID registers like a PHY would. Sadly this is often
1122
+ * configured to zeroes, so don't be surprised if it does
1123
+ * show 0x00000000.
1124
+ */
1125
+
1126
+ if (sgmii_pcs_scratch_test (priv , 0x0000 ) &&
1127
+ sgmii_pcs_scratch_test (priv , 0xffff ) &&
1128
+ sgmii_pcs_scratch_test (priv , 0xa5a5 ) &&
1129
+ sgmii_pcs_scratch_test (priv , 0x5a5a )) {
1130
+ netdev_info (dev , "PCS PHY ID: 0x%04x%04x\n" ,
1131
+ sgmii_pcs_read (priv , MII_PHYSID1 ),
1132
+ sgmii_pcs_read (priv , MII_PHYSID2 ));
1133
+ } else {
1134
+ netdev_err (dev , "SGMII PCS Scratch memory test failed.\n" );
1135
+ return - ENOMEM ;
1136
+ }
1137
+
1138
+ /* Starting on page 5-29 of the MegaCore Function User Guide
1139
+ * Set SGMII Link timer to 1.6ms
1140
+ */
1141
+ sgmii_pcs_write (priv , SGMII_PCS_LINK_TIMER_0 , 0x0D40 );
1142
+ sgmii_pcs_write (priv , SGMII_PCS_LINK_TIMER_1 , 0x03 );
1143
+
1144
+ /* Enable SGMII Interface and Enable SGMII Auto Negotiation */
1145
+ sgmii_pcs_write (priv , SGMII_PCS_IF_MODE , 0x3 );
1146
+
1147
+ /* Enable Autonegotiation */
1148
+ tmp_reg = sgmii_pcs_read (priv , MII_BMCR );
1149
+ tmp_reg |= (BMCR_SPEED1000 | BMCR_FULLDPLX | BMCR_ANENABLE );
1150
+ sgmii_pcs_write (priv , MII_BMCR , tmp_reg );
1151
+
1152
+ /* Reset PCS block */
1153
+ tmp_reg |= BMCR_RESET ;
1154
+ sgmii_pcs_write (priv , MII_BMCR , tmp_reg );
1155
+ for (n = 0 ; n < SGMII_PCS_SW_RESET_TIMEOUT ; n ++ ) {
1156
+ if (!(sgmii_pcs_read (priv , MII_BMCR ) & BMCR_RESET )) {
1157
+ netdev_info (dev , "SGMII PCS block initialised OK\n" );
1158
+ return 0 ;
1159
+ }
1160
+ udelay (1 );
1161
+ }
1162
+
1163
+ /* We failed to reset the block, return a timeout */
1164
+ netdev_err (dev , "SGMII PCS block reset failed.\n" );
1165
+ return - ETIMEDOUT ;
1166
+ }
1167
+
1086
1168
/* Open and initialize the interface
1087
1169
*/
1088
1170
static int tse_open (struct net_device * dev )
@@ -1107,6 +1189,15 @@ static int tse_open(struct net_device *dev)
1107
1189
netdev_warn (dev , "TSE revision %x\n" , priv -> revision );
1108
1190
1109
1191
spin_lock (& priv -> mac_cfg_lock );
1192
+ /* no-op if MAC not operating in SGMII mode*/
1193
+ ret = init_sgmii_pcs (dev );
1194
+ if (ret ) {
1195
+ netdev_err (dev ,
1196
+ "Cannot init the SGMII PCS (error: %d)\n" , ret );
1197
+ spin_unlock (& priv -> mac_cfg_lock );
1198
+ goto phy_error ;
1199
+ }
1200
+
1110
1201
ret = reset_mac (priv );
1111
1202
/* Note that reset_mac will fail if the clocks are gated by the PHY
1112
1203
* due to the PHY being put into isolation or power down mode.
0 commit comments