diff options
author | Petko Manolov <petkan@nucleusys.com> | 2013-04-25 18:41:36 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-29 13:57:49 -0400 |
commit | 2bd647018fe1b20c5c11dd1c508baea5771cd074 (patch) | |
tree | a69ed85f2a3f070c7c2c4a4da141b43d0b15b07f /drivers/net | |
parent | 313a58e487ab3eb80e7e1f9baddc75968288aad9 (diff) |
drivers: net: usb: pegasus: read/write_mii_word optimised
Duplicated code in routines reading and writing MII registers is now
packed in __mii_op().
Signed-off-by: Petko Manolov <petkan@nucleusys.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/usb/pegasus.c | 85 |
1 files changed, 35 insertions, 50 deletions
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index ff7b84d4c9fd..352b4dcee61c 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c | |||
@@ -323,36 +323,50 @@ static int update_eth_regs_async(pegasus_t *pegasus) | |||
323 | return ret; | 323 | return ret; |
324 | } | 324 | } |
325 | 325 | ||
326 | /* Returns 0 on success, error on failure */ | 326 | static int __mii_op(pegasus_t *p, __u8 phy, __u8 indx, __u16 *regd, __u8 cmd) |
327 | static int read_mii_word(pegasus_t *pegasus, __u8 phy, __u8 indx, __u16 *regd) | ||
328 | { | 327 | { |
329 | int i; | 328 | int i; |
330 | __u8 data[4] = { phy, 0, 0, indx }; | 329 | __u8 data[4] = { phy, 0, 0, indx }; |
331 | __le16 regdi; | 330 | __le16 regdi; |
332 | int ret; | 331 | int ret = -ETIMEDOUT; |
333 | 332 | ||
334 | set_register(pegasus, PhyCtrl, 0); | 333 | if (cmd & PHY_WRITE) { |
335 | set_registers(pegasus, PhyAddr, sizeof(data), data); | 334 | __le16 *t = (__le16 *) & data[1]; |
336 | set_register(pegasus, PhyCtrl, (indx | PHY_READ)); | 335 | *t = cpu_to_le16(*regd); |
336 | } | ||
337 | set_register(p, PhyCtrl, 0); | ||
338 | set_registers(p, PhyAddr, sizeof(data), data); | ||
339 | set_register(p, PhyCtrl, (indx | cmd)); | ||
337 | for (i = 0; i < REG_TIMEOUT; i++) { | 340 | for (i = 0; i < REG_TIMEOUT; i++) { |
338 | ret = get_registers(pegasus, PhyCtrl, 1, data); | 341 | ret = get_registers(p, PhyCtrl, 1, data); |
339 | if (ret == -ESHUTDOWN) | 342 | if (ret < 0) |
340 | goto fail; | 343 | goto fail; |
341 | if (data[0] & PHY_DONE) | 344 | if (data[0] & PHY_DONE) |
342 | break; | 345 | break; |
343 | } | 346 | } |
344 | |||
345 | if (i >= REG_TIMEOUT) | 347 | if (i >= REG_TIMEOUT) |
346 | goto fail; | 348 | goto fail; |
347 | 349 | if (cmd & PHY_READ) { | |
348 | ret = get_registers(pegasus, PhyData, 2, ®di); | 350 | ret = get_registers(p, PhyData, 2, ®di); |
349 | *regd = le16_to_cpu(regdi); | 351 | *regd = le16_to_cpu(regdi); |
352 | return ret; | ||
353 | } | ||
354 | return 0; | ||
355 | fail: | ||
356 | netif_dbg(p, drv, p->net, "%s failed\n", __func__); | ||
350 | return ret; | 357 | return ret; |
358 | } | ||
351 | 359 | ||
352 | fail: | 360 | /* Returns non-negative int on success, error on failure */ |
353 | netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__); | 361 | static int read_mii_word(pegasus_t *pegasus, __u8 phy, __u8 indx, __u16 *regd) |
362 | { | ||
363 | return __mii_op(pegasus, phy, indx, regd, PHY_READ); | ||
364 | } | ||
354 | 365 | ||
355 | return ret; | 366 | /* Returns zero on success, error on failure */ |
367 | static int write_mii_word(pegasus_t *pegasus, __u8 phy, __u8 indx, __u16 *regd) | ||
368 | { | ||
369 | return __mii_op(pegasus, phy, indx, regd, PHY_WRITE); | ||
356 | } | 370 | } |
357 | 371 | ||
358 | static int mdio_read(struct net_device *dev, int phy_id, int loc) | 372 | static int mdio_read(struct net_device *dev, int phy_id, int loc) |
@@ -364,40 +378,11 @@ static int mdio_read(struct net_device *dev, int phy_id, int loc) | |||
364 | return (int)res; | 378 | return (int)res; |
365 | } | 379 | } |
366 | 380 | ||
367 | static int write_mii_word(pegasus_t *pegasus, __u8 phy, __u8 indx, __u16 regd) | ||
368 | { | ||
369 | int i; | ||
370 | __u8 data[4] = { phy, 0, 0, indx }; | ||
371 | int ret; | ||
372 | |||
373 | data[1] = (u8) regd; | ||
374 | data[2] = (u8) (regd >> 8); | ||
375 | set_register(pegasus, PhyCtrl, 0); | ||
376 | set_registers(pegasus, PhyAddr, sizeof(data), data); | ||
377 | set_register(pegasus, PhyCtrl, (indx | PHY_WRITE)); | ||
378 | for (i = 0; i < REG_TIMEOUT; i++) { | ||
379 | ret = get_registers(pegasus, PhyCtrl, 1, data); | ||
380 | if (ret == -ESHUTDOWN) | ||
381 | goto fail; | ||
382 | if (data[0] & PHY_DONE) | ||
383 | break; | ||
384 | } | ||
385 | |||
386 | if (i >= REG_TIMEOUT) | ||
387 | goto fail; | ||
388 | |||
389 | return ret; | ||
390 | |||
391 | fail: | ||
392 | netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__); | ||
393 | return -ETIMEDOUT; | ||
394 | } | ||
395 | |||
396 | static void mdio_write(struct net_device *dev, int phy_id, int loc, int val) | 381 | static void mdio_write(struct net_device *dev, int phy_id, int loc, int val) |
397 | { | 382 | { |
398 | pegasus_t *pegasus = netdev_priv(dev); | 383 | pegasus_t *pegasus = netdev_priv(dev); |
399 | 384 | ||
400 | write_mii_word(pegasus, phy_id, loc, val); | 385 | write_mii_word(pegasus, phy_id, loc, (__u16 *)&val); |
401 | } | 386 | } |
402 | 387 | ||
403 | static int read_eprom_word(pegasus_t *pegasus, __u8 index, __u16 *retdata) | 388 | static int read_eprom_word(pegasus_t *pegasus, __u8 index, __u16 *retdata) |
@@ -434,7 +419,6 @@ fail: | |||
434 | static inline void enable_eprom_write(pegasus_t *pegasus) | 419 | static inline void enable_eprom_write(pegasus_t *pegasus) |
435 | { | 420 | { |
436 | __u8 tmp; | 421 | __u8 tmp; |
437 | int ret; | ||
438 | 422 | ||
439 | get_registers(pegasus, EthCtrl2, 1, &tmp); | 423 | get_registers(pegasus, EthCtrl2, 1, &tmp); |
440 | set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE); | 424 | set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE); |
@@ -443,7 +427,6 @@ static inline void enable_eprom_write(pegasus_t *pegasus) | |||
443 | static inline void disable_eprom_write(pegasus_t *pegasus) | 427 | static inline void disable_eprom_write(pegasus_t *pegasus) |
444 | { | 428 | { |
445 | __u8 tmp; | 429 | __u8 tmp; |
446 | int ret; | ||
447 | 430 | ||
448 | get_registers(pegasus, EthCtrl2, 1, &tmp); | 431 | get_registers(pegasus, EthCtrl2, 1, &tmp); |
449 | set_register(pegasus, EpromCtrl, 0); | 432 | set_register(pegasus, EpromCtrl, 0); |
@@ -537,7 +520,8 @@ static inline int reset_mac(pegasus_t *pegasus) | |||
537 | if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) { | 520 | if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) { |
538 | __u16 auxmode; | 521 | __u16 auxmode; |
539 | read_mii_word(pegasus, 3, 0x1b, &auxmode); | 522 | read_mii_word(pegasus, 3, 0x1b, &auxmode); |
540 | write_mii_word(pegasus, 3, 0x1b, auxmode | 4); | 523 | auxmode |= 4; |
524 | write_mii_word(pegasus, 3, 0x1b, &auxmode); | ||
541 | } | 525 | } |
542 | 526 | ||
543 | return 0; | 527 | return 0; |
@@ -569,7 +553,8 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb) | |||
569 | usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) { | 553 | usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) { |
570 | u16 auxmode; | 554 | u16 auxmode; |
571 | read_mii_word(pegasus, 0, 0x1b, &auxmode); | 555 | read_mii_word(pegasus, 0, 0x1b, &auxmode); |
572 | write_mii_word(pegasus, 0, 0x1b, auxmode | 4); | 556 | auxmode |= 4; |
557 | write_mii_word(pegasus, 0, 0x1b, &auxmode); | ||
573 | } | 558 | } |
574 | 559 | ||
575 | return ret; | 560 | return ret; |
@@ -1144,7 +1129,7 @@ static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd) | |||
1144 | case SIOCDEVPRIVATE + 2: | 1129 | case SIOCDEVPRIVATE + 2: |
1145 | if (!capable(CAP_NET_ADMIN)) | 1130 | if (!capable(CAP_NET_ADMIN)) |
1146 | return -EPERM; | 1131 | return -EPERM; |
1147 | write_mii_word(pegasus, pegasus->phy, data[1] & 0x1f, data[2]); | 1132 | write_mii_word(pegasus, pegasus->phy, data[1] & 0x1f, &data[2]); |
1148 | res = 0; | 1133 | res = 0; |
1149 | break; | 1134 | break; |
1150 | default: | 1135 | default: |