284
284
MVNETA_TXQ_BUCKET_REFILL_PERIOD))
285
285
286
286
#define MVNETA_LPI_CTRL_0 0x2cc0
287
+ #define MVNETA_LPI_CTRL_0_TS (0xff << 8)
287
288
#define MVNETA_LPI_CTRL_1 0x2cc4
288
- #define MVNETA_LPI_REQUEST_ENABLE BIT(0)
289
+ #define MVNETA_LPI_CTRL_1_REQUEST_ENABLE BIT(0)
290
+ #define MVNETA_LPI_CTRL_1_REQUEST_FORCE BIT(1)
291
+ #define MVNETA_LPI_CTRL_1_MANUAL_MODE BIT(2)
292
+ #define MVNETA_LPI_CTRL_1_TW (0xfff << 4)
289
293
#define MVNETA_LPI_CTRL_2 0x2cc8
290
294
#define MVNETA_LPI_STATUS 0x2ccc
291
295
@@ -541,10 +545,6 @@ struct mvneta_port {
541
545
struct mvneta_bm_pool * pool_short ;
542
546
int bm_win_id ;
543
547
544
- bool eee_enabled ;
545
- bool eee_active ;
546
- bool tx_lpi_enabled ;
547
-
548
548
u64 ethtool_stats [ARRAY_SIZE (mvneta_statistics )];
549
549
550
550
u32 indir [MVNETA_RSS_LU_TABLE_SIZE ];
@@ -4213,18 +4213,6 @@ static int mvneta_mac_finish(struct phylink_config *config, unsigned int mode,
4213
4213
return 0 ;
4214
4214
}
4215
4215
4216
- static void mvneta_set_eee (struct mvneta_port * pp , bool enable )
4217
- {
4218
- u32 lpi_ctl1 ;
4219
-
4220
- lpi_ctl1 = mvreg_read (pp , MVNETA_LPI_CTRL_1 );
4221
- if (enable )
4222
- lpi_ctl1 |= MVNETA_LPI_REQUEST_ENABLE ;
4223
- else
4224
- lpi_ctl1 &= ~MVNETA_LPI_REQUEST_ENABLE ;
4225
- mvreg_write (pp , MVNETA_LPI_CTRL_1 , lpi_ctl1 );
4226
- }
4227
-
4228
4216
static void mvneta_mac_link_down (struct phylink_config * config ,
4229
4217
unsigned int mode , phy_interface_t interface )
4230
4218
{
@@ -4240,9 +4228,6 @@ static void mvneta_mac_link_down(struct phylink_config *config,
4240
4228
val |= MVNETA_GMAC_FORCE_LINK_DOWN ;
4241
4229
mvreg_write (pp , MVNETA_GMAC_AUTONEG_CONFIG , val );
4242
4230
}
4243
-
4244
- pp -> eee_active = false;
4245
- mvneta_set_eee (pp , false);
4246
4231
}
4247
4232
4248
4233
static void mvneta_mac_link_up (struct phylink_config * config ,
@@ -4291,11 +4276,56 @@ static void mvneta_mac_link_up(struct phylink_config *config,
4291
4276
}
4292
4277
4293
4278
mvneta_port_up (pp );
4279
+ }
4294
4280
4295
- if (phy && pp -> eee_enabled ) {
4296
- pp -> eee_active = phy_init_eee (phy , false) >= 0 ;
4297
- mvneta_set_eee (pp , pp -> eee_active && pp -> tx_lpi_enabled );
4281
+ static void mvneta_mac_disable_tx_lpi (struct phylink_config * config )
4282
+ {
4283
+ struct mvneta_port * pp = netdev_priv (to_net_dev (config -> dev ));
4284
+ u32 lpi1 ;
4285
+
4286
+ lpi1 = mvreg_read (pp , MVNETA_LPI_CTRL_1 );
4287
+ lpi1 &= ~(MVNETA_LPI_CTRL_1_REQUEST_ENABLE |
4288
+ MVNETA_LPI_CTRL_1_REQUEST_FORCE |
4289
+ MVNETA_LPI_CTRL_1_MANUAL_MODE );
4290
+ mvreg_write (pp , MVNETA_LPI_CTRL_1 , lpi1 );
4291
+ }
4292
+
4293
+ static int mvneta_mac_enable_tx_lpi (struct phylink_config * config , u32 timer ,
4294
+ bool tx_clk_stop )
4295
+ {
4296
+ struct mvneta_port * pp = netdev_priv (to_net_dev (config -> dev ));
4297
+ u32 ts , tw , lpi0 , lpi1 , status ;
4298
+
4299
+ status = mvreg_read (pp , MVNETA_GMAC_STATUS );
4300
+ if (status & MVNETA_GMAC_SPEED_1000 ) {
4301
+ /* At 1G speeds, the timer resolution are 1us, and
4302
+ * 802.3 says tw is 16.5us. Round up to 17us.
4303
+ */
4304
+ tw = 17 ;
4305
+ ts = timer ;
4306
+ } else {
4307
+ /* At 100M speeds, the timer resolutions are 10us, and
4308
+ * 802.3 says tw is 30us.
4309
+ */
4310
+ tw = 3 ;
4311
+ ts = DIV_ROUND_UP (timer , 10 );
4298
4312
}
4313
+
4314
+ if (ts > 255 )
4315
+ ts = 255 ;
4316
+
4317
+ /* Configure ts */
4318
+ lpi0 = mvreg_read (pp , MVNETA_LPI_CTRL_0 );
4319
+ lpi0 = u32_replace_bits (lpi0 , ts , MVNETA_LPI_CTRL_0_TS );
4320
+ mvreg_write (pp , MVNETA_LPI_CTRL_0 , lpi0 );
4321
+
4322
+ /* Configure tw and enable LPI generation */
4323
+ lpi1 = mvreg_read (pp , MVNETA_LPI_CTRL_1 );
4324
+ lpi1 = u32_replace_bits (lpi1 , tw , MVNETA_LPI_CTRL_1_TW );
4325
+ lpi1 |= MVNETA_LPI_CTRL_1_REQUEST_ENABLE ;
4326
+ mvreg_write (pp , MVNETA_LPI_CTRL_1 , lpi1 );
4327
+
4328
+ return 0 ;
4299
4329
}
4300
4330
4301
4331
static const struct phylink_mac_ops mvneta_phylink_ops = {
@@ -4305,6 +4335,8 @@ static const struct phylink_mac_ops mvneta_phylink_ops = {
4305
4335
.mac_finish = mvneta_mac_finish ,
4306
4336
.mac_link_down = mvneta_mac_link_down ,
4307
4337
.mac_link_up = mvneta_mac_link_up ,
4338
+ .mac_disable_tx_lpi = mvneta_mac_disable_tx_lpi ,
4339
+ .mac_enable_tx_lpi = mvneta_mac_enable_tx_lpi ,
4308
4340
};
4309
4341
4310
4342
static int mvneta_mdio_probe (struct mvneta_port * pp )
@@ -5109,14 +5141,6 @@ static int mvneta_ethtool_get_eee(struct net_device *dev,
5109
5141
struct ethtool_keee * eee )
5110
5142
{
5111
5143
struct mvneta_port * pp = netdev_priv (dev );
5112
- u32 lpi_ctl0 ;
5113
-
5114
- lpi_ctl0 = mvreg_read (pp , MVNETA_LPI_CTRL_0 );
5115
-
5116
- eee -> eee_enabled = pp -> eee_enabled ;
5117
- eee -> eee_active = pp -> eee_active ;
5118
- eee -> tx_lpi_enabled = pp -> tx_lpi_enabled ;
5119
- eee -> tx_lpi_timer = (lpi_ctl0 ) >> 8 ; // * scale;
5120
5144
5121
5145
return phylink_ethtool_get_eee (pp -> phylink , eee );
5122
5146
}
@@ -5125,24 +5149,13 @@ static int mvneta_ethtool_set_eee(struct net_device *dev,
5125
5149
struct ethtool_keee * eee )
5126
5150
{
5127
5151
struct mvneta_port * pp = netdev_priv (dev );
5128
- u32 lpi_ctl0 ;
5129
5152
5130
5153
/* The Armada 37x documents do not give limits for this other than
5131
5154
* it being an 8-bit register.
5132
5155
*/
5133
5156
if (eee -> tx_lpi_enabled && eee -> tx_lpi_timer > 255 )
5134
5157
return - EINVAL ;
5135
5158
5136
- lpi_ctl0 = mvreg_read (pp , MVNETA_LPI_CTRL_0 );
5137
- lpi_ctl0 &= ~(0xff << 8 );
5138
- lpi_ctl0 |= eee -> tx_lpi_timer << 8 ;
5139
- mvreg_write (pp , MVNETA_LPI_CTRL_0 , lpi_ctl0 );
5140
-
5141
- pp -> eee_enabled = eee -> eee_enabled ;
5142
- pp -> tx_lpi_enabled = eee -> tx_lpi_enabled ;
5143
-
5144
- mvneta_set_eee (pp , eee -> tx_lpi_enabled && eee -> eee_enabled );
5145
-
5146
5159
return phylink_ethtool_set_eee (pp -> phylink , eee );
5147
5160
}
5148
5161
@@ -5456,6 +5469,9 @@ static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode)
5456
5469
!phy_interface_mode_is_rgmii (phy_mode ))
5457
5470
return - EINVAL ;
5458
5471
5472
+ /* Ensure LPI is disabled */
5473
+ mvneta_mac_disable_tx_lpi (& pp -> phylink_config );
5474
+
5459
5475
return 0 ;
5460
5476
}
5461
5477
@@ -5547,6 +5563,13 @@ static int mvneta_probe(struct platform_device *pdev)
5547
5563
pp -> phylink_config .mac_capabilities = MAC_SYM_PAUSE | MAC_10 |
5548
5564
MAC_100 | MAC_1000FD | MAC_2500FD ;
5549
5565
5566
+ /* Setup EEE. Choose 250us idle. Only supported in SGMII modes. */
5567
+ __set_bit (PHY_INTERFACE_MODE_QSGMII , pp -> phylink_config .lpi_interfaces );
5568
+ __set_bit (PHY_INTERFACE_MODE_SGMII , pp -> phylink_config .lpi_interfaces );
5569
+ pp -> phylink_config .lpi_capabilities = MAC_100FD | MAC_1000FD ;
5570
+ pp -> phylink_config .lpi_timer_default = 250 ;
5571
+ pp -> phylink_config .eee_enabled_default = true;
5572
+
5550
5573
phy_interface_set_rgmii (pp -> phylink_config .supported_interfaces );
5551
5574
__set_bit (PHY_INTERFACE_MODE_QSGMII ,
5552
5575
pp -> phylink_config .supported_interfaces );
0 commit comments