aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/atheros
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/atheros')
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c_hw.c189
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c_hw.h65
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c_main.c4
3 files changed, 197 insertions, 61 deletions
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
index bd1667cbffa..a17b5311dce 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
@@ -278,33 +278,158 @@ void atl1c_hash_set(struct atl1c_hw *hw, u32 hash_value)
278} 278}
279 279
280/* 280/*
281 * Reads the value from a PHY register 281 * wait mdio module be idle
282 * hw - Struct containing variables accessed by shared code 282 * return true: idle
283 * reg_addr - address of the PHY register to read 283 * false: still busy
284 */ 284 */
285int atl1c_read_phy_reg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data) 285bool atl1c_wait_mdio_idle(struct atl1c_hw *hw)
286{ 286{
287 u32 val; 287 u32 val;
288 int i; 288 int i;
289 289
290 val = ((u32)(reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT | 290 for (i = 0; i < MDIO_MAX_AC_TO; i++) {
291 MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | 291 AT_READ_REG(hw, REG_MDIO_CTRL, &val);
292 MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT; 292 if (!(val & (MDIO_CTRL_BUSY | MDIO_CTRL_START)))
293 break;
294 udelay(10);
295 }
296
297 return i != MDIO_MAX_AC_TO;
298}
299
300void atl1c_stop_phy_polling(struct atl1c_hw *hw)
301{
302 if (!(hw->ctrl_flags & ATL1C_FPGA_VERSION))
303 return;
304
305 AT_WRITE_REG(hw, REG_MDIO_CTRL, 0);
306 atl1c_wait_mdio_idle(hw);
307}
308
309void atl1c_start_phy_polling(struct atl1c_hw *hw, u16 clk_sel)
310{
311 u32 val;
293 312
313 if (!(hw->ctrl_flags & ATL1C_FPGA_VERSION))
314 return;
315
316 val = MDIO_CTRL_SPRES_PRMBL |
317 FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
318 FIELDX(MDIO_CTRL_REG, 1) |
319 MDIO_CTRL_START |
320 MDIO_CTRL_OP_READ;
321 AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
322 atl1c_wait_mdio_idle(hw);
323 val |= MDIO_CTRL_AP_EN;
324 val &= ~MDIO_CTRL_START;
294 AT_WRITE_REG(hw, REG_MDIO_CTRL, val); 325 AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
326 udelay(30);
327}
295 328
296 for (i = 0; i < MDIO_WAIT_TIMES; i++) { 329
297 udelay(2); 330/*
298 AT_READ_REG(hw, REG_MDIO_CTRL, &val); 331 * atl1c_read_phy_core
299 if (!(val & (MDIO_START | MDIO_BUSY))) 332 * core funtion to read register in PHY via MDIO control regsiter.
300 break; 333 * ext: extension register (see IEEE 802.3)
334 * dev: device address (see IEEE 802.3 DEVAD, PRTAD is fixed to 0)
335 * reg: reg to read
336 */
337int atl1c_read_phy_core(struct atl1c_hw *hw, bool ext, u8 dev,
338 u16 reg, u16 *phy_data)
339{
340 u32 val;
341 u16 clk_sel = MDIO_CTRL_CLK_25_4;
342
343 atl1c_stop_phy_polling(hw);
344
345 *phy_data = 0;
346
347 /* only l2c_b2 & l1d_2 could use slow clock */
348 if ((hw->nic_type == athr_l2c_b2 || hw->nic_type == athr_l1d_2) &&
349 hw->hibernate)
350 clk_sel = MDIO_CTRL_CLK_25_128;
351 if (ext) {
352 val = FIELDX(MDIO_EXTN_DEVAD, dev) | FIELDX(MDIO_EXTN_REG, reg);
353 AT_WRITE_REG(hw, REG_MDIO_EXTN, val);
354 val = MDIO_CTRL_SPRES_PRMBL |
355 FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
356 MDIO_CTRL_START |
357 MDIO_CTRL_MODE_EXT |
358 MDIO_CTRL_OP_READ;
359 } else {
360 val = MDIO_CTRL_SPRES_PRMBL |
361 FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
362 FIELDX(MDIO_CTRL_REG, reg) |
363 MDIO_CTRL_START |
364 MDIO_CTRL_OP_READ;
301 } 365 }
302 if (!(val & (MDIO_START | MDIO_BUSY))) { 366 AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
303 *phy_data = (u16)val; 367
304 return 0; 368 if (!atl1c_wait_mdio_idle(hw))
369 return -1;
370
371 AT_READ_REG(hw, REG_MDIO_CTRL, &val);
372 *phy_data = (u16)FIELD_GETX(val, MDIO_CTRL_DATA);
373
374 atl1c_start_phy_polling(hw, clk_sel);
375
376 return 0;
377}
378
379/*
380 * atl1c_write_phy_core
381 * core funtion to write to register in PHY via MDIO control regsiter.
382 * ext: extension register (see IEEE 802.3)
383 * dev: device address (see IEEE 802.3 DEVAD, PRTAD is fixed to 0)
384 * reg: reg to write
385 */
386int atl1c_write_phy_core(struct atl1c_hw *hw, bool ext, u8 dev,
387 u16 reg, u16 phy_data)
388{
389 u32 val;
390 u16 clk_sel = MDIO_CTRL_CLK_25_4;
391
392 atl1c_stop_phy_polling(hw);
393
394
395 /* only l2c_b2 & l1d_2 could use slow clock */
396 if ((hw->nic_type == athr_l2c_b2 || hw->nic_type == athr_l1d_2) &&
397 hw->hibernate)
398 clk_sel = MDIO_CTRL_CLK_25_128;
399
400 if (ext) {
401 val = FIELDX(MDIO_EXTN_DEVAD, dev) | FIELDX(MDIO_EXTN_REG, reg);
402 AT_WRITE_REG(hw, REG_MDIO_EXTN, val);
403 val = MDIO_CTRL_SPRES_PRMBL |
404 FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
405 FIELDX(MDIO_CTRL_DATA, phy_data) |
406 MDIO_CTRL_START |
407 MDIO_CTRL_MODE_EXT;
408 } else {
409 val = MDIO_CTRL_SPRES_PRMBL |
410 FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
411 FIELDX(MDIO_CTRL_DATA, phy_data) |
412 FIELDX(MDIO_CTRL_REG, reg) |
413 MDIO_CTRL_START;
305 } 414 }
415 AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
306 416
307 return -1; 417 if (!atl1c_wait_mdio_idle(hw))
418 return -1;
419
420 atl1c_start_phy_polling(hw, clk_sel);
421
422 return 0;
423}
424
425/*
426 * Reads the value from a PHY register
427 * hw - Struct containing variables accessed by shared code
428 * reg_addr - address of the PHY register to read
429 */
430int atl1c_read_phy_reg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data)
431{
432 return atl1c_read_phy_core(hw, false, 0, reg_addr, phy_data);
308} 433}
309 434
310/* 435/*
@@ -315,27 +440,21 @@ int atl1c_read_phy_reg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data)
315 */ 440 */
316int atl1c_write_phy_reg(struct atl1c_hw *hw, u32 reg_addr, u16 phy_data) 441int atl1c_write_phy_reg(struct atl1c_hw *hw, u32 reg_addr, u16 phy_data)
317{ 442{
318 int i; 443 return atl1c_write_phy_core(hw, false, 0, reg_addr, phy_data);
319 u32 val; 444}
320
321 val = ((u32)(phy_data & MDIO_DATA_MASK)) << MDIO_DATA_SHIFT |
322 (reg_addr & MDIO_REG_ADDR_MASK) << MDIO_REG_ADDR_SHIFT |
323 MDIO_SUP_PREAMBLE | MDIO_START |
324 MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT;
325
326 AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
327
328 for (i = 0; i < MDIO_WAIT_TIMES; i++) {
329 udelay(2);
330 AT_READ_REG(hw, REG_MDIO_CTRL, &val);
331 if (!(val & (MDIO_START | MDIO_BUSY)))
332 break;
333 }
334 445
335 if (!(val & (MDIO_START | MDIO_BUSY))) 446/* read from PHY extension register */
336 return 0; 447int atl1c_read_phy_ext(struct atl1c_hw *hw, u8 dev_addr,
448 u16 reg_addr, u16 *phy_data)
449{
450 return atl1c_read_phy_core(hw, true, dev_addr, reg_addr, phy_data);
451}
337 452
338 return -1; 453/* write to PHY extension register */
454int atl1c_write_phy_ext(struct atl1c_hw *hw, u8 dev_addr,
455 u16 reg_addr, u16 phy_data)
456{
457 return atl1c_write_phy_core(hw, true, dev_addr, reg_addr, phy_data);
339} 458}
340 459
341/* 460/*
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.h b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.h
index 459e141f002..cb2d20b6998 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.h
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.h
@@ -49,6 +49,17 @@ int atl1c_phy_init(struct atl1c_hw *hw);
49int atl1c_check_eeprom_exist(struct atl1c_hw *hw); 49int atl1c_check_eeprom_exist(struct atl1c_hw *hw);
50int atl1c_restart_autoneg(struct atl1c_hw *hw); 50int atl1c_restart_autoneg(struct atl1c_hw *hw);
51int atl1c_phy_power_saving(struct atl1c_hw *hw); 51int atl1c_phy_power_saving(struct atl1c_hw *hw);
52bool atl1c_wait_mdio_idle(struct atl1c_hw *hw);
53void atl1c_stop_phy_polling(struct atl1c_hw *hw);
54void atl1c_start_phy_polling(struct atl1c_hw *hw, u16 clk_sel);
55int atl1c_read_phy_core(struct atl1c_hw *hw, bool ext, u8 dev,
56 u16 reg, u16 *phy_data);
57int atl1c_write_phy_core(struct atl1c_hw *hw, bool ext, u8 dev,
58 u16 reg, u16 phy_data);
59int atl1c_read_phy_ext(struct atl1c_hw *hw, u8 dev_addr,
60 u16 reg_addr, u16 *phy_data);
61int atl1c_write_phy_ext(struct atl1c_hw *hw, u8 dev_addr,
62 u16 reg_addr, u16 phy_data);
52/* register definition */ 63/* register definition */
53#define REG_DEVICE_CAP 0x5C 64#define REG_DEVICE_CAP 0x5C
54#define DEVICE_CAP_MAX_PAYLOAD_MASK 0x7 65#define DEVICE_CAP_MAX_PAYLOAD_MASK 0x7
@@ -268,30 +279,36 @@ int atl1c_phy_power_saving(struct atl1c_hw *hw);
268 279
269/* MDIO Control Register */ 280/* MDIO Control Register */
270#define REG_MDIO_CTRL 0x1414 281#define REG_MDIO_CTRL 0x1414
271#define MDIO_DATA_MASK 0xffff /* On MDIO write, the 16-bit 282#define MDIO_CTRL_MODE_EXT BIT(30)
272 * control data to write to PHY 283#define MDIO_CTRL_POST_READ BIT(29)
273 * MII management register */ 284#define MDIO_CTRL_AP_EN BIT(28)
274#define MDIO_DATA_SHIFT 0 /* On MDIO read, the 16-bit 285#define MDIO_CTRL_BUSY BIT(27)
275 * status data that was read 286#define MDIO_CTRL_CLK_SEL_MASK 0x7UL
276 * from the PHY MII management register */ 287#define MDIO_CTRL_CLK_SEL_SHIFT 24
277#define MDIO_REG_ADDR_MASK 0x1f /* MDIO register address */ 288#define MDIO_CTRL_CLK_25_4 0 /* 25MHz divide 4 */
278#define MDIO_REG_ADDR_SHIFT 16 289#define MDIO_CTRL_CLK_25_6 2
279#define MDIO_RW 0x200000 /* 1: read, 0: write */ 290#define MDIO_CTRL_CLK_25_8 3
280#define MDIO_SUP_PREAMBLE 0x400000 /* Suppress preamble */ 291#define MDIO_CTRL_CLK_25_10 4
281#define MDIO_START 0x800000 /* Write 1 to initiate the MDIO 292#define MDIO_CTRL_CLK_25_32 5
282 * master. And this bit is self 293#define MDIO_CTRL_CLK_25_64 6
283 * cleared after one cycle */ 294#define MDIO_CTRL_CLK_25_128 7
284#define MDIO_CLK_SEL_SHIFT 24 295#define MDIO_CTRL_START BIT(23)
285#define MDIO_CLK_25_4 0 296#define MDIO_CTRL_SPRES_PRMBL BIT(22)
286#define MDIO_CLK_25_6 2 297#define MDIO_CTRL_OP_READ BIT(21) /* 1:read, 0:write */
287#define MDIO_CLK_25_8 3 298#define MDIO_CTRL_REG_MASK 0x1FUL
288#define MDIO_CLK_25_10 4 299#define MDIO_CTRL_REG_SHIFT 16
289#define MDIO_CLK_25_14 5 300#define MDIO_CTRL_DATA_MASK 0xFFFFUL
290#define MDIO_CLK_25_20 6 301#define MDIO_CTRL_DATA_SHIFT 0
291#define MDIO_CLK_25_28 7 302#define MDIO_MAX_AC_TO 120 /* 1.2ms timeout for slow clk */
292#define MDIO_BUSY 0x8000000 303
293#define MDIO_AP_EN 0x10000000 304/* for extension reg access */
294#define MDIO_WAIT_TIMES 10 305#define REG_MDIO_EXTN 0x1448
306#define MDIO_EXTN_PORTAD_MASK 0x1FUL
307#define MDIO_EXTN_PORTAD_SHIFT 21
308#define MDIO_EXTN_DEVAD_MASK 0x1FUL
309#define MDIO_EXTN_DEVAD_SHIFT 16
310#define MDIO_EXTN_REG_MASK 0xFFFFUL
311#define MDIO_EXTN_REG_SHIFT 0
295 312
296/* BIST Control and Status Register0 (for the Packet Memory) */ 313/* BIST Control and Status Register0 (for the Packet Memory) */
297#define REG_BIST0_CTRL 0x141c 314#define REG_BIST0_CTRL 0x141c
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index a6c3f05e5db..1f82880904d 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -2270,7 +2270,7 @@ static int atl1c_open(struct net_device *netdev)
2270 u32 phy_data; 2270 u32 phy_data;
2271 2271
2272 AT_READ_REG(&adapter->hw, REG_MDIO_CTRL, &phy_data); 2272 AT_READ_REG(&adapter->hw, REG_MDIO_CTRL, &phy_data);
2273 phy_data |= MDIO_AP_EN; 2273 phy_data |= MDIO_CTRL_AP_EN;
2274 AT_WRITE_REG(&adapter->hw, REG_MDIO_CTRL, phy_data); 2274 AT_WRITE_REG(&adapter->hw, REG_MDIO_CTRL, phy_data);
2275 } 2275 }
2276 return 0; 2276 return 0;
@@ -2558,7 +2558,7 @@ static int __devinit atl1c_probe(struct pci_dev *pdev,
2558 adapter->mii.mdio_read = atl1c_mdio_read; 2558 adapter->mii.mdio_read = atl1c_mdio_read;
2559 adapter->mii.mdio_write = atl1c_mdio_write; 2559 adapter->mii.mdio_write = atl1c_mdio_write;
2560 adapter->mii.phy_id_mask = 0x1f; 2560 adapter->mii.phy_id_mask = 0x1f;
2561 adapter->mii.reg_num_mask = MDIO_REG_ADDR_MASK; 2561 adapter->mii.reg_num_mask = MDIO_CTRL_REG_MASK;
2562 netif_napi_add(netdev, &adapter->napi, atl1c_clean, 64); 2562 netif_napi_add(netdev, &adapter->napi, atl1c_clean, 64);
2563 setup_timer(&adapter->phy_config_timer, atl1c_phy_config, 2563 setup_timer(&adapter->phy_config_timer, atl1c_phy_config,
2564 (unsigned long)adapter); 2564 (unsigned long)adapter);