diff options
Diffstat (limited to 'drivers/net/usb/r8152.c')
| -rw-r--r-- | drivers/net/usb/r8152.c | 126 |
1 files changed, 58 insertions, 68 deletions
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index ee13f9eb740c..11c51f275366 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c | |||
| @@ -344,17 +344,41 @@ static const int multicast_filter_limit = 32; | |||
| 344 | static | 344 | static |
| 345 | int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) | 345 | int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) |
| 346 | { | 346 | { |
| 347 | return usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0), | 347 | int ret; |
| 348 | void *tmp; | ||
| 349 | |||
| 350 | tmp = kmalloc(size, GFP_KERNEL); | ||
| 351 | if (!tmp) | ||
| 352 | return -ENOMEM; | ||
| 353 | |||
| 354 | ret = usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0), | ||
| 348 | RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, | 355 | RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, |
| 349 | value, index, data, size, 500); | 356 | value, index, tmp, size, 500); |
| 357 | |||
| 358 | memcpy(data, tmp, size); | ||
| 359 | kfree(tmp); | ||
| 360 | |||
| 361 | return ret; | ||
| 350 | } | 362 | } |
| 351 | 363 | ||
| 352 | static | 364 | static |
| 353 | int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) | 365 | int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) |
| 354 | { | 366 | { |
| 355 | return usb_control_msg(tp->udev, usb_sndctrlpipe(tp->udev, 0), | 367 | int ret; |
| 368 | void *tmp; | ||
| 369 | |||
| 370 | tmp = kmalloc(size, GFP_KERNEL); | ||
| 371 | if (!tmp) | ||
| 372 | return -ENOMEM; | ||
| 373 | |||
| 374 | memcpy(tmp, data, size); | ||
| 375 | |||
| 376 | ret = usb_control_msg(tp->udev, usb_sndctrlpipe(tp->udev, 0), | ||
| 356 | RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, | 377 | RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, |
| 357 | value, index, data, size, 500); | 378 | value, index, tmp, size, 500); |
| 379 | |||
| 380 | kfree(tmp); | ||
| 381 | return ret; | ||
| 358 | } | 382 | } |
| 359 | 383 | ||
| 360 | static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, | 384 | static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, |
| @@ -490,37 +514,31 @@ int usb_ocp_write(struct r8152 *tp, u16 index, u16 byteen, u16 size, void *data) | |||
| 490 | 514 | ||
| 491 | static u32 ocp_read_dword(struct r8152 *tp, u16 type, u16 index) | 515 | static u32 ocp_read_dword(struct r8152 *tp, u16 type, u16 index) |
| 492 | { | 516 | { |
| 493 | u32 data; | 517 | __le32 data; |
| 494 | 518 | ||
| 495 | if (type == MCU_TYPE_PLA) | 519 | generic_ocp_read(tp, index, sizeof(data), &data, type); |
| 496 | pla_ocp_read(tp, index, sizeof(data), &data); | ||
| 497 | else | ||
| 498 | usb_ocp_read(tp, index, sizeof(data), &data); | ||
| 499 | 520 | ||
| 500 | return __le32_to_cpu(data); | 521 | return __le32_to_cpu(data); |
| 501 | } | 522 | } |
| 502 | 523 | ||
| 503 | static void ocp_write_dword(struct r8152 *tp, u16 type, u16 index, u32 data) | 524 | static void ocp_write_dword(struct r8152 *tp, u16 type, u16 index, u32 data) |
| 504 | { | 525 | { |
| 505 | if (type == MCU_TYPE_PLA) | 526 | __le32 tmp = __cpu_to_le32(data); |
| 506 | pla_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(data), &data); | 527 | |
| 507 | else | 528 | generic_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(tmp), &tmp, type); |
| 508 | usb_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(data), &data); | ||
| 509 | } | 529 | } |
| 510 | 530 | ||
| 511 | static u16 ocp_read_word(struct r8152 *tp, u16 type, u16 index) | 531 | static u16 ocp_read_word(struct r8152 *tp, u16 type, u16 index) |
| 512 | { | 532 | { |
| 513 | u32 data; | 533 | u32 data; |
| 534 | __le32 tmp; | ||
| 514 | u8 shift = index & 2; | 535 | u8 shift = index & 2; |
| 515 | 536 | ||
| 516 | index &= ~3; | 537 | index &= ~3; |
| 517 | 538 | ||
| 518 | if (type == MCU_TYPE_PLA) | 539 | generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); |
| 519 | pla_ocp_read(tp, index, sizeof(data), &data); | ||
| 520 | else | ||
| 521 | usb_ocp_read(tp, index, sizeof(data), &data); | ||
| 522 | 540 | ||
| 523 | data = __le32_to_cpu(data); | 541 | data = __le32_to_cpu(tmp); |
| 524 | data >>= (shift * 8); | 542 | data >>= (shift * 8); |
| 525 | data &= 0xffff; | 543 | data &= 0xffff; |
| 526 | 544 | ||
| @@ -529,7 +547,8 @@ static u16 ocp_read_word(struct r8152 *tp, u16 type, u16 index) | |||
| 529 | 547 | ||
| 530 | static void ocp_write_word(struct r8152 *tp, u16 type, u16 index, u32 data) | 548 | static void ocp_write_word(struct r8152 *tp, u16 type, u16 index, u32 data) |
| 531 | { | 549 | { |
| 532 | u32 tmp, mask = 0xffff; | 550 | u32 mask = 0xffff; |
| 551 | __le32 tmp; | ||
| 533 | u16 byen = BYTE_EN_WORD; | 552 | u16 byen = BYTE_EN_WORD; |
| 534 | u8 shift = index & 2; | 553 | u8 shift = index & 2; |
| 535 | 554 | ||
| @@ -542,34 +561,25 @@ static void ocp_write_word(struct r8152 *tp, u16 type, u16 index, u32 data) | |||
| 542 | index &= ~3; | 561 | index &= ~3; |
| 543 | } | 562 | } |
| 544 | 563 | ||
| 545 | if (type == MCU_TYPE_PLA) | 564 | generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); |
| 546 | pla_ocp_read(tp, index, sizeof(tmp), &tmp); | ||
| 547 | else | ||
| 548 | usb_ocp_read(tp, index, sizeof(tmp), &tmp); | ||
| 549 | 565 | ||
| 550 | tmp = __le32_to_cpu(tmp) & ~mask; | 566 | data |= __le32_to_cpu(tmp) & ~mask; |
| 551 | tmp |= data; | 567 | tmp = __cpu_to_le32(data); |
| 552 | tmp = __cpu_to_le32(tmp); | ||
| 553 | 568 | ||
| 554 | if (type == MCU_TYPE_PLA) | 569 | generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type); |
| 555 | pla_ocp_write(tp, index, byen, sizeof(tmp), &tmp); | ||
| 556 | else | ||
| 557 | usb_ocp_write(tp, index, byen, sizeof(tmp), &tmp); | ||
| 558 | } | 570 | } |
| 559 | 571 | ||
| 560 | static u8 ocp_read_byte(struct r8152 *tp, u16 type, u16 index) | 572 | static u8 ocp_read_byte(struct r8152 *tp, u16 type, u16 index) |
| 561 | { | 573 | { |
| 562 | u32 data; | 574 | u32 data; |
| 575 | __le32 tmp; | ||
| 563 | u8 shift = index & 3; | 576 | u8 shift = index & 3; |
| 564 | 577 | ||
| 565 | index &= ~3; | 578 | index &= ~3; |
| 566 | 579 | ||
| 567 | if (type == MCU_TYPE_PLA) | 580 | generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); |
| 568 | pla_ocp_read(tp, index, sizeof(data), &data); | ||
| 569 | else | ||
| 570 | usb_ocp_read(tp, index, sizeof(data), &data); | ||
| 571 | 581 | ||
| 572 | data = __le32_to_cpu(data); | 582 | data = __le32_to_cpu(tmp); |
| 573 | data >>= (shift * 8); | 583 | data >>= (shift * 8); |
| 574 | data &= 0xff; | 584 | data &= 0xff; |
| 575 | 585 | ||
| @@ -578,7 +588,8 @@ static u8 ocp_read_byte(struct r8152 *tp, u16 type, u16 index) | |||
| 578 | 588 | ||
| 579 | static void ocp_write_byte(struct r8152 *tp, u16 type, u16 index, u32 data) | 589 | static void ocp_write_byte(struct r8152 *tp, u16 type, u16 index, u32 data) |
| 580 | { | 590 | { |
| 581 | u32 tmp, mask = 0xff; | 591 | u32 mask = 0xff; |
| 592 | __le32 tmp; | ||
| 582 | u16 byen = BYTE_EN_BYTE; | 593 | u16 byen = BYTE_EN_BYTE; |
| 583 | u8 shift = index & 3; | 594 | u8 shift = index & 3; |
| 584 | 595 | ||
| @@ -591,19 +602,12 @@ static void ocp_write_byte(struct r8152 *tp, u16 type, u16 index, u32 data) | |||
| 591 | index &= ~3; | 602 | index &= ~3; |
| 592 | } | 603 | } |
| 593 | 604 | ||
| 594 | if (type == MCU_TYPE_PLA) | 605 | generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); |
| 595 | pla_ocp_read(tp, index, sizeof(tmp), &tmp); | ||
| 596 | else | ||
| 597 | usb_ocp_read(tp, index, sizeof(tmp), &tmp); | ||
| 598 | 606 | ||
| 599 | tmp = __le32_to_cpu(tmp) & ~mask; | 607 | data |= __le32_to_cpu(tmp) & ~mask; |
| 600 | tmp |= data; | 608 | tmp = __cpu_to_le32(data); |
| 601 | tmp = __cpu_to_le32(tmp); | ||
| 602 | 609 | ||
| 603 | if (type == MCU_TYPE_PLA) | 610 | generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type); |
| 604 | pla_ocp_write(tp, index, byen, sizeof(tmp), &tmp); | ||
| 605 | else | ||
| 606 | usb_ocp_write(tp, index, byen, sizeof(tmp), &tmp); | ||
| 607 | } | 611 | } |
| 608 | 612 | ||
| 609 | static void r8152_mdio_write(struct r8152 *tp, u32 reg_addr, u32 value) | 613 | static void r8152_mdio_write(struct r8152 *tp, u32 reg_addr, u32 value) |
| @@ -685,21 +689,14 @@ static void ocp_reg_write(struct r8152 *tp, u16 addr, u16 data) | |||
| 685 | static inline void set_ethernet_addr(struct r8152 *tp) | 689 | static inline void set_ethernet_addr(struct r8152 *tp) |
| 686 | { | 690 | { |
| 687 | struct net_device *dev = tp->netdev; | 691 | struct net_device *dev = tp->netdev; |
| 688 | u8 *node_id; | 692 | u8 node_id[8] = {0}; |
| 689 | |||
| 690 | node_id = kmalloc(sizeof(u8) * 8, GFP_KERNEL); | ||
| 691 | if (!node_id) { | ||
| 692 | netif_err(tp, probe, dev, "out of memory"); | ||
| 693 | return; | ||
| 694 | } | ||
| 695 | 693 | ||
| 696 | if (pla_ocp_read(tp, PLA_IDR, sizeof(u8) * 8, node_id) < 0) | 694 | if (pla_ocp_read(tp, PLA_IDR, sizeof(node_id), node_id) < 0) |
| 697 | netif_notice(tp, probe, dev, "inet addr fail\n"); | 695 | netif_notice(tp, probe, dev, "inet addr fail\n"); |
| 698 | else { | 696 | else { |
| 699 | memcpy(dev->dev_addr, node_id, dev->addr_len); | 697 | memcpy(dev->dev_addr, node_id, dev->addr_len); |
| 700 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); | 698 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); |
| 701 | } | 699 | } |
| 702 | kfree(node_id); | ||
| 703 | } | 700 | } |
| 704 | 701 | ||
| 705 | static int rtl8152_set_mac_address(struct net_device *netdev, void *p) | 702 | static int rtl8152_set_mac_address(struct net_device *netdev, void *p) |
| @@ -882,15 +879,10 @@ static void rtl8152_set_rx_mode(struct net_device *netdev) | |||
| 882 | static void _rtl8152_set_rx_mode(struct net_device *netdev) | 879 | static void _rtl8152_set_rx_mode(struct net_device *netdev) |
| 883 | { | 880 | { |
| 884 | struct r8152 *tp = netdev_priv(netdev); | 881 | struct r8152 *tp = netdev_priv(netdev); |
| 885 | u32 tmp, *mc_filter; /* Multicast hash filter */ | 882 | u32 mc_filter[2]; /* Multicast hash filter */ |
| 883 | __le32 tmp[2]; | ||
| 886 | u32 ocp_data; | 884 | u32 ocp_data; |
| 887 | 885 | ||
| 888 | mc_filter = kmalloc(sizeof(u32) * 2, GFP_KERNEL); | ||
| 889 | if (!mc_filter) { | ||
| 890 | netif_err(tp, link, netdev, "out of memory"); | ||
| 891 | return; | ||
| 892 | } | ||
| 893 | |||
| 894 | clear_bit(RTL8152_SET_RX_MODE, &tp->flags); | 886 | clear_bit(RTL8152_SET_RX_MODE, &tp->flags); |
| 895 | netif_stop_queue(netdev); | 887 | netif_stop_queue(netdev); |
| 896 | ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); | 888 | ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); |
| @@ -918,14 +910,12 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev) | |||
| 918 | } | 910 | } |
| 919 | } | 911 | } |
| 920 | 912 | ||
| 921 | tmp = mc_filter[0]; | 913 | tmp[0] = __cpu_to_le32(swab32(mc_filter[1])); |
| 922 | mc_filter[0] = __cpu_to_le32(swab32(mc_filter[1])); | 914 | tmp[1] = __cpu_to_le32(swab32(mc_filter[0])); |
| 923 | mc_filter[1] = __cpu_to_le32(swab32(tmp)); | ||
| 924 | 915 | ||
| 925 | pla_ocp_write(tp, PLA_MAR, BYTE_EN_DWORD, sizeof(u32) * 2, mc_filter); | 916 | pla_ocp_write(tp, PLA_MAR, BYTE_EN_DWORD, sizeof(tmp), tmp); |
| 926 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); | 917 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); |
| 927 | netif_wake_queue(netdev); | 918 | netif_wake_queue(netdev); |
| 928 | kfree(mc_filter); | ||
| 929 | } | 919 | } |
| 930 | 920 | ||
| 931 | static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, | 921 | static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, |
