aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2008-12-13 00:48:57 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-13 00:58:16 -0500
commit356eebb2b3af24cc701823f1e025f04eef333239 (patch)
tree62f8e4e24e1e421d617fe08775dfd15b79862fdc
parent04300d248bd5166c00a59fa18efc1f7d041e9b32 (diff)
sfc: Clean up MDIO flag setting
We often want to set or clear a flag in an MDIO register, but avoid writing if no change is required since this can have side-effects. Encapsulate this in a function, mdio_clause45_set_flag(). Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/sfc/mdio_10g.c87
-rw-r--r--drivers/net/sfc/mdio_10g.h4
2 files changed, 32 insertions, 59 deletions
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index 1eed48407ed8..8d91131aa5ab 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -205,61 +205,24 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
205 205
206void mdio_clause45_transmit_disable(struct efx_nic *efx) 206void mdio_clause45_transmit_disable(struct efx_nic *efx)
207{ 207{
208 int phy_id = efx->mii.phy_id; 208 mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
209 int ctrl1, ctrl2; 209 MDIO_MMDREG_TXDIS, MDIO_MMDREG_TXDIS_GLOBAL_LBN,
210 210 efx->phy_mode & PHY_MODE_TX_DISABLED);
211 ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
212 MDIO_MMDREG_TXDIS);
213 if (efx->phy_mode & PHY_MODE_TX_DISABLED)
214 ctrl2 |= (1 << MDIO_MMDREG_TXDIS_GLOBAL_LBN);
215 else
216 ctrl1 &= ~(1 << MDIO_MMDREG_TXDIS_GLOBAL_LBN);
217 if (ctrl1 != ctrl2)
218 mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
219 MDIO_MMDREG_TXDIS, ctrl2);
220} 211}
221 212
222void mdio_clause45_phy_reconfigure(struct efx_nic *efx) 213void mdio_clause45_phy_reconfigure(struct efx_nic *efx)
223{ 214{
224 int phy_id = efx->mii.phy_id; 215 int phy_id = efx->mii.phy_id;
225 int ctrl1, ctrl2;
226
227 /* Handle (with debouncing) PMA/PMD loopback */
228 ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
229 MDIO_MMDREG_CTRL1);
230
231 if (efx->loopback_mode == LOOPBACK_PMAPMD)
232 ctrl2 |= (1 << MDIO_PMAPMD_CTRL1_LBACK_LBN);
233 else
234 ctrl2 &= ~(1 << MDIO_PMAPMD_CTRL1_LBACK_LBN);
235
236 if (ctrl1 != ctrl2)
237 mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
238 MDIO_MMDREG_CTRL1, ctrl2);
239
240 /* Handle (with debouncing) PCS loopback */
241 ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
242 MDIO_MMDREG_CTRL1);
243 if (efx->loopback_mode == LOOPBACK_PCS)
244 ctrl2 |= (1 << MDIO_MMDREG_CTRL1_LBACK_LBN);
245 else
246 ctrl2 &= ~(1 << MDIO_MMDREG_CTRL1_LBACK_LBN);
247 216
248 if (ctrl1 != ctrl2) 217 mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD,
249 mdio_clause45_write(efx, phy_id, MDIO_MMD_PCS, 218 MDIO_MMDREG_CTRL1, MDIO_PMAPMD_CTRL1_LBACK_LBN,
250 MDIO_MMDREG_CTRL1, ctrl2); 219 efx->loopback_mode == LOOPBACK_PMAPMD);
251 220 mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PCS,
252 /* Handle (with debouncing) PHYXS network loopback */ 221 MDIO_MMDREG_CTRL1, MDIO_MMDREG_CTRL1_LBACK_LBN,
253 ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS, 222 efx->loopback_mode == LOOPBACK_PCS);
254 MDIO_MMDREG_CTRL1); 223 mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PHYXS,
255 if (efx->loopback_mode == LOOPBACK_NETWORK) 224 MDIO_MMDREG_CTRL1, MDIO_MMDREG_CTRL1_LBACK_LBN,
256 ctrl2 |= (1 << MDIO_MMDREG_CTRL1_LBACK_LBN); 225 efx->loopback_mode == LOOPBACK_NETWORK);
257 else
258 ctrl2 &= ~(1 << MDIO_MMDREG_CTRL1_LBACK_LBN);
259
260 if (ctrl1 != ctrl2)
261 mdio_clause45_write(efx, phy_id, MDIO_MMD_PHYXS,
262 MDIO_MMDREG_CTRL1, ctrl2);
263} 226}
264 227
265static void mdio_clause45_set_mmd_lpower(struct efx_nic *efx, 228static void mdio_clause45_set_mmd_lpower(struct efx_nic *efx,
@@ -267,21 +230,13 @@ static void mdio_clause45_set_mmd_lpower(struct efx_nic *efx,
267{ 230{
268 int phy = efx->mii.phy_id; 231 int phy = efx->mii.phy_id;
269 int stat = mdio_clause45_read(efx, phy, mmd, MDIO_MMDREG_STAT1); 232 int stat = mdio_clause45_read(efx, phy, mmd, MDIO_MMDREG_STAT1);
270 int ctrl1, ctrl2;
271 233
272 EFX_TRACE(efx, "Setting low power mode for MMD %d to %d\n", 234 EFX_TRACE(efx, "Setting low power mode for MMD %d to %d\n",
273 mmd, lpower); 235 mmd, lpower);
274 236
275 if (stat & (1 << MDIO_MMDREG_STAT1_LPABLE_LBN)) { 237 if (stat & (1 << MDIO_MMDREG_STAT1_LPABLE_LBN)) {
276 ctrl1 = ctrl2 = mdio_clause45_read(efx, phy, 238 mdio_clause45_set_flag(efx, phy, mmd, MDIO_MMDREG_CTRL1,
277 mmd, MDIO_MMDREG_CTRL1); 239 MDIO_MMDREG_CTRL1_LPOWER_LBN, lpower);
278 if (lpower)
279 ctrl2 |= (1 << MDIO_MMDREG_CTRL1_LPOWER_LBN);
280 else
281 ctrl2 &= ~(1 << MDIO_MMDREG_CTRL1_LPOWER_LBN);
282 if (ctrl1 != ctrl2)
283 mdio_clause45_write(efx, phy, mmd,
284 MDIO_MMDREG_CTRL1, ctrl2);
285 } 240 }
286} 241}
287 242
@@ -395,3 +350,17 @@ int mdio_clause45_set_settings(struct efx_nic *efx,
395 return 0; 350 return 0;
396 return -EOPNOTSUPP; 351 return -EOPNOTSUPP;
397} 352}
353
354void mdio_clause45_set_flag(struct efx_nic *efx, u8 prt, u8 dev,
355 u16 addr, int bit, bool sense)
356{
357 int old_val = mdio_clause45_read(efx, prt, dev, addr);
358 int new_val;
359
360 if (sense)
361 new_val = old_val | (1 << bit);
362 else
363 new_val = old_val & ~(1 << bit);
364 if (old_val != new_val)
365 mdio_clause45_write(efx, prt, dev, addr, new_val);
366}
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h
index 45163838130e..4830e0c1da0b 100644
--- a/drivers/net/sfc/mdio_10g.h
+++ b/drivers/net/sfc/mdio_10g.h
@@ -259,4 +259,8 @@ extern int mdio_clause45_set_settings(struct efx_nic *efx,
259extern int mdio_clause45_wait_reset_mmds(struct efx_nic *efx, 259extern int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
260 unsigned int mmd_mask); 260 unsigned int mmd_mask);
261 261
262/* Set or clear flag, debouncing */
263extern void mdio_clause45_set_flag(struct efx_nic *efx, u8 prt, u8 dev,
264 u16 addr, int bit, bool sense);
265
262#endif /* EFX_MDIO_10G_H */ 266#endif /* EFX_MDIO_10G_H */