@@ -263,13 +263,99 @@ static const struct net_device_ops mlxbf_gige_netdev_ops = {
263263 .ndo_get_stats64 = mlxbf_gige_get_stats64 ,
264264};
265265
266- static void mlxbf_gige_adjust_link (struct net_device * netdev )
266+ static void mlxbf_gige_bf2_adjust_link (struct net_device * netdev )
267267{
268268 struct phy_device * phydev = netdev -> phydev ;
269269
270270 phy_print_status (phydev );
271271}
272272
273+ static void mlxbf_gige_bf3_adjust_link (struct net_device * netdev )
274+ {
275+ struct mlxbf_gige * priv = netdev_priv (netdev );
276+ struct phy_device * phydev = netdev -> phydev ;
277+ u8 sgmii_mode ;
278+ u16 ipg_size ;
279+ u32 val ;
280+
281+ if (phydev -> link && phydev -> speed != priv -> prev_speed ) {
282+ switch (phydev -> speed ) {
283+ case 1000 :
284+ ipg_size = MLXBF_GIGE_1G_IPG_SIZE ;
285+ sgmii_mode = MLXBF_GIGE_1G_SGMII_MODE ;
286+ break ;
287+ case 100 :
288+ ipg_size = MLXBF_GIGE_100M_IPG_SIZE ;
289+ sgmii_mode = MLXBF_GIGE_100M_SGMII_MODE ;
290+ break ;
291+ case 10 :
292+ ipg_size = MLXBF_GIGE_10M_IPG_SIZE ;
293+ sgmii_mode = MLXBF_GIGE_10M_SGMII_MODE ;
294+ break ;
295+ default :
296+ return ;
297+ }
298+
299+ val = readl (priv -> plu_base + MLXBF_GIGE_PLU_TX_REG0 );
300+ val &= ~(MLXBF_GIGE_PLU_TX_IPG_SIZE_MASK | MLXBF_GIGE_PLU_TX_SGMII_MODE_MASK );
301+ val |= FIELD_PREP (MLXBF_GIGE_PLU_TX_IPG_SIZE_MASK , ipg_size );
302+ val |= FIELD_PREP (MLXBF_GIGE_PLU_TX_SGMII_MODE_MASK , sgmii_mode );
303+ writel (val , priv -> plu_base + MLXBF_GIGE_PLU_TX_REG0 );
304+
305+ val = readl (priv -> plu_base + MLXBF_GIGE_PLU_RX_REG0 );
306+ val &= ~MLXBF_GIGE_PLU_RX_SGMII_MODE_MASK ;
307+ val |= FIELD_PREP (MLXBF_GIGE_PLU_RX_SGMII_MODE_MASK , sgmii_mode );
308+ writel (val , priv -> plu_base + MLXBF_GIGE_PLU_RX_REG0 );
309+
310+ priv -> prev_speed = phydev -> speed ;
311+ }
312+
313+ phy_print_status (phydev );
314+ }
315+
316+ static void mlxbf_gige_bf2_set_phy_link_mode (struct phy_device * phydev )
317+ {
318+ /* MAC only supports 1000T full duplex mode */
319+ phy_remove_link_mode (phydev , ETHTOOL_LINK_MODE_1000baseT_Half_BIT );
320+ phy_remove_link_mode (phydev , ETHTOOL_LINK_MODE_100baseT_Full_BIT );
321+ phy_remove_link_mode (phydev , ETHTOOL_LINK_MODE_100baseT_Half_BIT );
322+ phy_remove_link_mode (phydev , ETHTOOL_LINK_MODE_10baseT_Full_BIT );
323+ phy_remove_link_mode (phydev , ETHTOOL_LINK_MODE_10baseT_Half_BIT );
324+
325+ /* Only symmetric pause with flow control enabled is supported so no
326+ * need to negotiate pause.
327+ */
328+ linkmode_clear_bit (ETHTOOL_LINK_MODE_Pause_BIT , phydev -> advertising );
329+ linkmode_clear_bit (ETHTOOL_LINK_MODE_Asym_Pause_BIT , phydev -> advertising );
330+ }
331+
332+ static void mlxbf_gige_bf3_set_phy_link_mode (struct phy_device * phydev )
333+ {
334+ /* MAC only supports full duplex mode */
335+ phy_remove_link_mode (phydev , ETHTOOL_LINK_MODE_1000baseT_Half_BIT );
336+ phy_remove_link_mode (phydev , ETHTOOL_LINK_MODE_100baseT_Half_BIT );
337+ phy_remove_link_mode (phydev , ETHTOOL_LINK_MODE_10baseT_Half_BIT );
338+
339+ /* Only symmetric pause with flow control enabled is supported so no
340+ * need to negotiate pause.
341+ */
342+ linkmode_clear_bit (ETHTOOL_LINK_MODE_Pause_BIT , phydev -> advertising );
343+ linkmode_clear_bit (ETHTOOL_LINK_MODE_Asym_Pause_BIT , phydev -> advertising );
344+ }
345+
346+ static struct mlxbf_gige_link_cfg mlxbf_gige_link_cfgs [] = {
347+ [MLXBF_GIGE_VERSION_BF2 ] = {
348+ .set_phy_link_mode = mlxbf_gige_bf2_set_phy_link_mode ,
349+ .adjust_link = mlxbf_gige_bf2_adjust_link ,
350+ .phy_mode = PHY_INTERFACE_MODE_GMII
351+ },
352+ [MLXBF_GIGE_VERSION_BF3 ] = {
353+ .set_phy_link_mode = mlxbf_gige_bf3_set_phy_link_mode ,
354+ .adjust_link = mlxbf_gige_bf3_adjust_link ,
355+ .phy_mode = PHY_INTERFACE_MODE_SGMII
356+ }
357+ };
358+
273359static int mlxbf_gige_probe (struct platform_device * pdev )
274360{
275361 struct phy_device * phydev ;
@@ -359,25 +445,14 @@ static int mlxbf_gige_probe(struct platform_device *pdev)
359445 phydev -> irq = phy_irq ;
360446
361447 err = phy_connect_direct (netdev , phydev ,
362- mlxbf_gige_adjust_link ,
363- PHY_INTERFACE_MODE_GMII );
448+ mlxbf_gige_link_cfgs [ priv -> hw_version ]. adjust_link ,
449+ mlxbf_gige_link_cfgs [ priv -> hw_version ]. phy_mode );
364450 if (err ) {
365451 dev_err (& pdev -> dev , "Could not attach to PHY\n" );
366452 goto out ;
367453 }
368454
369- /* MAC only supports 1000T full duplex mode */
370- phy_remove_link_mode (phydev , ETHTOOL_LINK_MODE_1000baseT_Half_BIT );
371- phy_remove_link_mode (phydev , ETHTOOL_LINK_MODE_100baseT_Full_BIT );
372- phy_remove_link_mode (phydev , ETHTOOL_LINK_MODE_100baseT_Half_BIT );
373- phy_remove_link_mode (phydev , ETHTOOL_LINK_MODE_10baseT_Full_BIT );
374- phy_remove_link_mode (phydev , ETHTOOL_LINK_MODE_10baseT_Half_BIT );
375-
376- /* Only symmetric pause with flow control enabled is supported so no
377- * need to negotiate pause.
378- */
379- linkmode_clear_bit (ETHTOOL_LINK_MODE_Pause_BIT , phydev -> advertising );
380- linkmode_clear_bit (ETHTOOL_LINK_MODE_Asym_Pause_BIT , phydev -> advertising );
455+ mlxbf_gige_link_cfgs [priv -> hw_version ].set_phy_link_mode (phydev );
381456
382457 /* Display information about attached PHY device */
383458 phy_attached_info (phydev );
0 commit comments