@@ -1114,13 +1114,35 @@ mvpp2_shared_interrupt_mask_unmask(struct mvpp2_port *port, bool mask)
11141114 }
11151115}
11161116
1117+ /* Only GOP port 0 has an XLG MAC */
1118+ static bool mvpp2_port_supports_xlg (struct mvpp2_port * port )
1119+ {
1120+ return port -> gop_id == 0 ;
1121+ }
1122+
1123+ static bool mvpp2_port_supports_rgmii (struct mvpp2_port * port )
1124+ {
1125+ return !(port -> priv -> hw_version == MVPP22 && port -> gop_id == 0 );
1126+ }
1127+
11171128/* Port configuration routines */
11181129static bool mvpp2_is_xlg (phy_interface_t interface )
11191130{
11201131 return interface == PHY_INTERFACE_MODE_10GBASER ||
11211132 interface == PHY_INTERFACE_MODE_XAUI ;
11221133}
11231134
1135+ static void mvpp2_modify (void __iomem * ptr , u32 mask , u32 set )
1136+ {
1137+ u32 old , val ;
1138+
1139+ old = val = readl (ptr );
1140+ val &= ~mask ;
1141+ val |= set ;
1142+ if (old != val )
1143+ writel (val , ptr );
1144+ }
1145+
11241146static void mvpp22_gop_init_rgmii (struct mvpp2_port * port )
11251147{
11261148 struct mvpp2 * priv = port -> priv ;
@@ -1194,7 +1216,7 @@ static int mvpp22_gop_init(struct mvpp2_port *port)
11941216 case PHY_INTERFACE_MODE_RGMII_ID :
11951217 case PHY_INTERFACE_MODE_RGMII_RXID :
11961218 case PHY_INTERFACE_MODE_RGMII_TXID :
1197- if (port -> gop_id == 0 )
1219+ if (! mvpp2_port_supports_rgmii ( port ) )
11981220 goto invalid_conf ;
11991221 mvpp22_gop_init_rgmii (port );
12001222 break ;
@@ -1204,7 +1226,7 @@ static int mvpp22_gop_init(struct mvpp2_port *port)
12041226 mvpp22_gop_init_sgmii (port );
12051227 break ;
12061228 case PHY_INTERFACE_MODE_10GBASER :
1207- if (port -> gop_id != 0 )
1229+ if (! mvpp2_port_supports_xlg ( port ) )
12081230 goto invalid_conf ;
12091231 mvpp22_gop_init_10gkr (port );
12101232 break ;
@@ -1246,7 +1268,7 @@ static void mvpp22_gop_unmask_irq(struct mvpp2_port *port)
12461268 writel (val , port -> base + MVPP22_GMAC_INT_SUM_MASK );
12471269 }
12481270
1249- if (port -> gop_id == 0 ) {
1271+ if (mvpp2_port_supports_xlg ( port ) ) {
12501272 /* Enable the XLG/GIG irqs for this port */
12511273 val = readl (port -> base + MVPP22_XLG_EXT_INT_MASK );
12521274 if (mvpp2_is_xlg (port -> phy_interface ))
@@ -1261,7 +1283,7 @@ static void mvpp22_gop_mask_irq(struct mvpp2_port *port)
12611283{
12621284 u32 val ;
12631285
1264- if (port -> gop_id == 0 ) {
1286+ if (mvpp2_port_supports_xlg ( port ) ) {
12651287 val = readl (port -> base + MVPP22_XLG_EXT_INT_MASK );
12661288 val &= ~(MVPP22_XLG_EXT_INT_MASK_XLG |
12671289 MVPP22_XLG_EXT_INT_MASK_GIG );
@@ -1290,7 +1312,7 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port)
12901312 writel (val , port -> base + MVPP22_GMAC_INT_MASK );
12911313 }
12921314
1293- if (port -> gop_id == 0 ) {
1315+ if (mvpp2_port_supports_xlg ( port ) ) {
12941316 val = readl (port -> base + MVPP22_XLG_INT_MASK );
12951317 val |= MVPP22_XLG_INT_MASK_LINK ;
12961318 writel (val , port -> base + MVPP22_XLG_INT_MASK );
@@ -1328,8 +1350,8 @@ static void mvpp2_port_enable(struct mvpp2_port *port)
13281350{
13291351 u32 val ;
13301352
1331- /* Only GOP port 0 has an XLG MAC */
1332- if ( port -> gop_id == 0 && mvpp2_is_xlg (port -> phy_interface )) {
1353+ if ( mvpp2_port_supports_xlg ( port ) &&
1354+ mvpp2_is_xlg (port -> phy_interface )) {
13331355 val = readl (port -> base + MVPP22_XLG_CTRL0_REG );
13341356 val |= MVPP22_XLG_CTRL0_PORT_EN ;
13351357 val &= ~MVPP22_XLG_CTRL0_MIB_CNT_DIS ;
@@ -1346,8 +1368,8 @@ static void mvpp2_port_disable(struct mvpp2_port *port)
13461368{
13471369 u32 val ;
13481370
1349- /* Only GOP port 0 has an XLG MAC */
1350- if ( port -> gop_id == 0 && mvpp2_is_xlg (port -> phy_interface )) {
1371+ if ( mvpp2_port_supports_xlg ( port ) &&
1372+ mvpp2_is_xlg (port -> phy_interface )) {
13511373 val = readl (port -> base + MVPP22_XLG_CTRL0_REG );
13521374 val &= ~MVPP22_XLG_CTRL0_PORT_EN ;
13531375 writel (val , port -> base + MVPP22_XLG_CTRL0_REG );
@@ -2740,7 +2762,8 @@ static irqreturn_t mvpp2_link_status_isr(int irq, void *dev_id)
27402762
27412763 mvpp22_gop_mask_irq (port );
27422764
2743- if (port -> gop_id == 0 && mvpp2_is_xlg (port -> phy_interface )) {
2765+ if (mvpp2_port_supports_xlg (port ) &&
2766+ mvpp2_is_xlg (port -> phy_interface )) {
27442767 val = readl (port -> base + MVPP22_XLG_INT_STAT );
27452768 if (val & MVPP22_XLG_INT_STAT_LINK ) {
27462769 event = true;
@@ -3430,8 +3453,7 @@ static void mvpp22_mode_reconfigure(struct mvpp2_port *port)
34303453
34313454 mvpp22_pcs_reset_deassert (port );
34323455
3433- /* Only GOP port 0 has an XLG MAC */
3434- if (port -> gop_id == 0 ) {
3456+ if (mvpp2_port_supports_xlg (port )) {
34353457 ctrl3 = readl (port -> base + MVPP22_XLG_CTRL3_REG );
34363458 ctrl3 &= ~MVPP22_XLG_CTRL3_MACMODESELECT_MASK ;
34373459
@@ -3443,7 +3465,7 @@ static void mvpp22_mode_reconfigure(struct mvpp2_port *port)
34433465 writel (ctrl3 , port -> base + MVPP22_XLG_CTRL3_REG );
34443466 }
34453467
3446- if (port -> gop_id == 0 && mvpp2_is_xlg (port -> phy_interface ))
3468+ if (mvpp2_port_supports_xlg ( port ) && mvpp2_is_xlg (port -> phy_interface ))
34473469 mvpp2_xlg_max_rx_size_set (port );
34483470 else
34493471 mvpp2_gmac_max_rx_size_set (port );
@@ -4756,26 +4778,30 @@ static void mvpp2_port_copy_mac_addr(struct net_device *dev, struct mvpp2 *priv,
47564778 eth_hw_addr_random (dev );
47574779}
47584780
4781+ static struct mvpp2_port * mvpp2_phylink_to_port (struct phylink_config * config )
4782+ {
4783+ return container_of (config , struct mvpp2_port , phylink_config );
4784+ }
4785+
47594786static void mvpp2_phylink_validate (struct phylink_config * config ,
47604787 unsigned long * supported ,
47614788 struct phylink_link_state * state )
47624789{
4763- struct mvpp2_port * port = container_of (config , struct mvpp2_port ,
4764- phylink_config );
4790+ struct mvpp2_port * port = mvpp2_phylink_to_port (config );
47654791 __ETHTOOL_DECLARE_LINK_MODE_MASK (mask ) = { 0 , };
47664792
47674793 /* Invalid combinations */
47684794 switch (state -> interface ) {
47694795 case PHY_INTERFACE_MODE_10GBASER :
47704796 case PHY_INTERFACE_MODE_XAUI :
4771- if (port -> gop_id != 0 )
4797+ if (! mvpp2_port_supports_xlg ( port ) )
47724798 goto empty_set ;
47734799 break ;
47744800 case PHY_INTERFACE_MODE_RGMII :
47754801 case PHY_INTERFACE_MODE_RGMII_ID :
47764802 case PHY_INTERFACE_MODE_RGMII_RXID :
47774803 case PHY_INTERFACE_MODE_RGMII_TXID :
4778- if (port -> priv -> hw_version == MVPP22 && port -> gop_id == 0 )
4804+ if (! mvpp2_port_supports_rgmii ( port ) )
47794805 goto empty_set ;
47804806 break ;
47814807 default :
@@ -4791,7 +4817,7 @@ static void mvpp2_phylink_validate(struct phylink_config *config,
47914817 case PHY_INTERFACE_MODE_10GBASER :
47924818 case PHY_INTERFACE_MODE_XAUI :
47934819 case PHY_INTERFACE_MODE_NA :
4794- if (port -> gop_id == 0 ) {
4820+ if (mvpp2_port_supports_xlg ( port ) ) {
47954821 phylink_set (mask , 10000b aseT_Full );
47964822 phylink_set (mask , 10000b aseCR_Full );
47974823 phylink_set (mask , 10000b aseSR_Full );
@@ -4902,8 +4928,7 @@ static void mvpp2_gmac_pcs_get_state(struct mvpp2_port *port,
49024928static void mvpp2_phylink_mac_pcs_get_state (struct phylink_config * config ,
49034929 struct phylink_link_state * state )
49044930{
4905- struct mvpp2_port * port = container_of (config , struct mvpp2_port ,
4906- phylink_config );
4931+ struct mvpp2_port * port = mvpp2_phylink_to_port (config );
49074932
49084933 if (port -> priv -> hw_version == MVPP22 && port -> gop_id == 0 ) {
49094934 u32 mode = readl (port -> base + MVPP22_XLG_CTRL3_REG );
@@ -4920,8 +4945,7 @@ static void mvpp2_phylink_mac_pcs_get_state(struct phylink_config *config,
49204945
49214946static void mvpp2_mac_an_restart (struct phylink_config * config )
49224947{
4923- struct mvpp2_port * port = container_of (config , struct mvpp2_port ,
4924- phylink_config );
4948+ struct mvpp2_port * port = mvpp2_phylink_to_port (config );
49254949 u32 val = readl (port -> base + MVPP2_GMAC_AUTONEG_CONFIG );
49264950
49274951 writel (val | MVPP2_GMAC_IN_BAND_RESTART_AN ,
@@ -4933,38 +4957,21 @@ static void mvpp2_mac_an_restart(struct phylink_config *config)
49334957static void mvpp2_xlg_config (struct mvpp2_port * port , unsigned int mode ,
49344958 const struct phylink_link_state * state )
49354959{
4936- u32 old_ctrl0 , ctrl0 ;
4937- u32 old_ctrl4 , ctrl4 ;
4938-
4939- old_ctrl0 = ctrl0 = readl (port -> base + MVPP22_XLG_CTRL0_REG );
4940- old_ctrl4 = ctrl4 = readl (port -> base + MVPP22_XLG_CTRL4_REG );
4941-
4942- ctrl0 |= MVPP22_XLG_CTRL0_MAC_RESET_DIS ;
4943-
4944- if (state -> pause & MLO_PAUSE_TX )
4945- ctrl0 |= MVPP22_XLG_CTRL0_TX_FLOW_CTRL_EN ;
4946- else
4947- ctrl0 &= ~MVPP22_XLG_CTRL0_TX_FLOW_CTRL_EN ;
4948-
4949- if (state -> pause & MLO_PAUSE_RX )
4950- ctrl0 |= MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN ;
4951- else
4952- ctrl0 &= ~MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN ;
4953-
4954- ctrl4 &= ~(MVPP22_XLG_CTRL4_MACMODSELECT_GMAC |
4955- MVPP22_XLG_CTRL4_EN_IDLE_CHECK );
4956- ctrl4 |= MVPP22_XLG_CTRL4_FWD_FC | MVPP22_XLG_CTRL4_FWD_PFC ;
4960+ u32 val ;
49574961
4958- if (old_ctrl0 != ctrl0 )
4959- writel (ctrl0 , port -> base + MVPP22_XLG_CTRL0_REG );
4960- if (old_ctrl4 != ctrl4 )
4961- writel (ctrl4 , port -> base + MVPP22_XLG_CTRL4_REG );
4962+ mvpp2_modify (port -> base + MVPP22_XLG_CTRL0_REG ,
4963+ MVPP22_XLG_CTRL0_MAC_RESET_DIS ,
4964+ MVPP22_XLG_CTRL0_MAC_RESET_DIS );
4965+ mvpp2_modify (port -> base + MVPP22_XLG_CTRL4_REG ,
4966+ MVPP22_XLG_CTRL4_MACMODSELECT_GMAC |
4967+ MVPP22_XLG_CTRL4_EN_IDLE_CHECK |
4968+ MVPP22_XLG_CTRL4_FWD_FC | MVPP22_XLG_CTRL4_FWD_PFC ,
4969+ MVPP22_XLG_CTRL4_FWD_FC | MVPP22_XLG_CTRL4_FWD_PFC );
49624970
4963- if (!(old_ctrl0 & MVPP22_XLG_CTRL0_MAC_RESET_DIS )) {
4964- while (!(readl (port -> base + MVPP22_XLG_CTRL0_REG ) &
4965- MVPP22_XLG_CTRL0_MAC_RESET_DIS ))
4966- continue ;
4967- }
4971+ /* Wait for reset to deassert */
4972+ do {
4973+ val = readl (port -> base + MVPP22_XLG_CTRL0_REG );
4974+ } while (!(val & MVPP22_XLG_CTRL0_MAC_RESET_DIS ));
49684975}
49694976
49704977static void mvpp2_gmac_config (struct mvpp2_port * port , unsigned int mode ,
@@ -5094,13 +5101,12 @@ static void mvpp2_gmac_config(struct mvpp2_port *port, unsigned int mode,
50945101static void mvpp2_mac_config (struct phylink_config * config , unsigned int mode ,
50955102 const struct phylink_link_state * state )
50965103{
5097- struct net_device * dev = to_net_dev (config -> dev );
5098- struct mvpp2_port * port = netdev_priv (dev );
5104+ struct mvpp2_port * port = mvpp2_phylink_to_port (config );
50995105 bool change_interface = port -> phy_interface != state -> interface ;
51005106
51015107 /* Check for invalid configuration */
51025108 if (mvpp2_is_xlg (state -> interface ) && port -> gop_id != 0 ) {
5103- netdev_err (dev , "Invalid mode on %s\n" , dev -> name );
5109+ netdev_err (port -> dev , "Invalid mode on %s\n" , port -> dev -> name );
51045110 return ;
51055111 }
51065112
@@ -5140,25 +5146,26 @@ static void mvpp2_mac_link_up(struct phylink_config *config,
51405146 int speed , int duplex ,
51415147 bool tx_pause , bool rx_pause )
51425148{
5143- struct net_device * dev = to_net_dev (config -> dev );
5144- struct mvpp2_port * port = netdev_priv (dev );
5149+ struct mvpp2_port * port = mvpp2_phylink_to_port (config );
51455150 u32 val ;
51465151
51475152 if (mvpp2_is_xlg (interface )) {
51485153 if (!phylink_autoneg_inband (mode )) {
5149- val = readl (port -> base + MVPP22_XLG_CTRL0_REG );
5150- val &= ~MVPP22_XLG_CTRL0_FORCE_LINK_DOWN ;
5151- val |= MVPP22_XLG_CTRL0_FORCE_LINK_PASS ;
5152- writel (val , port -> base + MVPP22_XLG_CTRL0_REG );
5154+ val = MVPP22_XLG_CTRL0_FORCE_LINK_PASS ;
5155+ if (tx_pause )
5156+ val |= MVPP22_XLG_CTRL0_TX_FLOW_CTRL_EN ;
5157+ if (rx_pause )
5158+ val |= MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN ;
5159+
5160+ mvpp2_modify (port -> base + MVPP22_XLG_CTRL0_REG ,
5161+ MVPP22_XLG_CTRL0_FORCE_LINK_DOWN |
5162+ MVPP22_XLG_CTRL0_FORCE_LINK_PASS |
5163+ MVPP22_XLG_CTRL0_TX_FLOW_CTRL_EN |
5164+ MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN , val );
51535165 }
51545166 } else {
51555167 if (!phylink_autoneg_inband (mode )) {
5156- val = readl (port -> base + MVPP2_GMAC_AUTONEG_CONFIG );
5157- val &= ~(MVPP2_GMAC_FORCE_LINK_DOWN |
5158- MVPP2_GMAC_CONFIG_MII_SPEED |
5159- MVPP2_GMAC_CONFIG_GMII_SPEED |
5160- MVPP2_GMAC_CONFIG_FULL_DUPLEX );
5161- val |= MVPP2_GMAC_FORCE_LINK_PASS ;
5168+ val = MVPP2_GMAC_FORCE_LINK_PASS ;
51625169
51635170 if (speed == SPEED_1000 || speed == SPEED_2500 )
51645171 val |= MVPP2_GMAC_CONFIG_GMII_SPEED ;
@@ -5168,34 +5175,40 @@ static void mvpp2_mac_link_up(struct phylink_config *config,
51685175 if (duplex == DUPLEX_FULL )
51695176 val |= MVPP2_GMAC_CONFIG_FULL_DUPLEX ;
51705177
5171- writel (val , port -> base + MVPP2_GMAC_AUTONEG_CONFIG );
5178+ mvpp2_modify (port -> base + MVPP2_GMAC_AUTONEG_CONFIG ,
5179+ MVPP2_GMAC_FORCE_LINK_DOWN |
5180+ MVPP2_GMAC_FORCE_LINK_PASS |
5181+ MVPP2_GMAC_CONFIG_MII_SPEED |
5182+ MVPP2_GMAC_CONFIG_GMII_SPEED |
5183+ MVPP2_GMAC_CONFIG_FULL_DUPLEX , val );
51725184 }
51735185
51745186 /* We can always update the flow control enable bits;
51755187 * these will only be effective if flow control AN
51765188 * (MVPP2_GMAC_FLOW_CTRL_AUTONEG) is disabled.
51775189 */
5178- val = readl (port -> base + MVPP22_GMAC_CTRL_4_REG );
5179- val &= ~(MVPP22_CTRL4_RX_FC_EN | MVPP22_CTRL4_TX_FC_EN );
5190+ val = 0 ;
51805191 if (tx_pause )
51815192 val |= MVPP22_CTRL4_TX_FC_EN ;
51825193 if (rx_pause )
51835194 val |= MVPP22_CTRL4_RX_FC_EN ;
5184- writel (val , port -> base + MVPP22_GMAC_CTRL_4_REG );
5195+
5196+ mvpp2_modify (port -> base + MVPP22_GMAC_CTRL_4_REG ,
5197+ MVPP22_CTRL4_RX_FC_EN | MVPP22_CTRL4_TX_FC_EN ,
5198+ val );
51855199 }
51865200
51875201 mvpp2_port_enable (port );
51885202
51895203 mvpp2_egress_enable (port );
51905204 mvpp2_ingress_enable (port );
5191- netif_tx_wake_all_queues (dev );
5205+ netif_tx_wake_all_queues (port -> dev );
51925206}
51935207
51945208static void mvpp2_mac_link_down (struct phylink_config * config ,
51955209 unsigned int mode , phy_interface_t interface )
51965210{
5197- struct net_device * dev = to_net_dev (config -> dev );
5198- struct mvpp2_port * port = netdev_priv (dev );
5211+ struct mvpp2_port * port = mvpp2_phylink_to_port (config );
51995212 u32 val ;
52005213
52015214 if (!phylink_autoneg_inband (mode )) {
@@ -5212,7 +5225,7 @@ static void mvpp2_mac_link_down(struct phylink_config *config,
52125225 }
52135226 }
52145227
5215- netif_tx_stop_all_queues (dev );
5228+ netif_tx_stop_all_queues (port -> dev );
52165229 mvpp2_egress_disable (port );
52175230 mvpp2_ingress_disable (port );
52185231
0 commit comments