diff options
Diffstat (limited to 'drivers/net/ks8851_mll.c')
| -rw-r--r-- | drivers/net/ks8851_mll.c | 142 |
1 files changed, 68 insertions, 74 deletions
diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c index 0be14d702beb..c146304d8d6c 100644 --- a/drivers/net/ks8851_mll.c +++ b/drivers/net/ks8851_mll.c | |||
| @@ -568,6 +568,16 @@ static inline void ks_outblk(struct ks_net *ks, u16 *wptr, u32 len) | |||
| 568 | iowrite16(*wptr++, ks->hw_addr); | 568 | iowrite16(*wptr++, ks->hw_addr); |
| 569 | } | 569 | } |
| 570 | 570 | ||
| 571 | static void ks_disable_int(struct ks_net *ks) | ||
| 572 | { | ||
| 573 | ks_wrreg16(ks, KS_IER, 0x0000); | ||
| 574 | } /* ks_disable_int */ | ||
| 575 | |||
| 576 | static void ks_enable_int(struct ks_net *ks) | ||
| 577 | { | ||
| 578 | ks_wrreg16(ks, KS_IER, ks->rc_ier); | ||
| 579 | } /* ks_enable_int */ | ||
| 580 | |||
| 571 | /** | 581 | /** |
| 572 | * ks_tx_fifo_space - return the available hardware buffer size. | 582 | * ks_tx_fifo_space - return the available hardware buffer size. |
| 573 | * @ks: The chip information | 583 | * @ks: The chip information |
| @@ -681,6 +691,47 @@ static void ks_soft_reset(struct ks_net *ks, unsigned op) | |||
| 681 | } | 691 | } |
| 682 | 692 | ||
| 683 | 693 | ||
| 694 | void ks_enable_qmu(struct ks_net *ks) | ||
| 695 | { | ||
| 696 | u16 w; | ||
| 697 | |||
| 698 | w = ks_rdreg16(ks, KS_TXCR); | ||
| 699 | /* Enables QMU Transmit (TXCR). */ | ||
| 700 | ks_wrreg16(ks, KS_TXCR, w | TXCR_TXE); | ||
| 701 | |||
| 702 | /* | ||
| 703 | * RX Frame Count Threshold Enable and Auto-Dequeue RXQ Frame | ||
| 704 | * Enable | ||
| 705 | */ | ||
| 706 | |||
| 707 | w = ks_rdreg16(ks, KS_RXQCR); | ||
| 708 | ks_wrreg16(ks, KS_RXQCR, w | RXQCR_RXFCTE); | ||
| 709 | |||
| 710 | /* Enables QMU Receive (RXCR1). */ | ||
| 711 | w = ks_rdreg16(ks, KS_RXCR1); | ||
| 712 | ks_wrreg16(ks, KS_RXCR1, w | RXCR1_RXE); | ||
| 713 | ks->enabled = true; | ||
| 714 | } /* ks_enable_qmu */ | ||
| 715 | |||
| 716 | static void ks_disable_qmu(struct ks_net *ks) | ||
| 717 | { | ||
| 718 | u16 w; | ||
| 719 | |||
| 720 | w = ks_rdreg16(ks, KS_TXCR); | ||
| 721 | |||
| 722 | /* Disables QMU Transmit (TXCR). */ | ||
| 723 | w &= ~TXCR_TXE; | ||
| 724 | ks_wrreg16(ks, KS_TXCR, w); | ||
| 725 | |||
| 726 | /* Disables QMU Receive (RXCR1). */ | ||
| 727 | w = ks_rdreg16(ks, KS_RXCR1); | ||
| 728 | w &= ~RXCR1_RXE ; | ||
| 729 | ks_wrreg16(ks, KS_RXCR1, w); | ||
| 730 | |||
| 731 | ks->enabled = false; | ||
| 732 | |||
| 733 | } /* ks_disable_qmu */ | ||
| 734 | |||
| 684 | /** | 735 | /** |
| 685 | * ks_read_qmu - read 1 pkt data from the QMU. | 736 | * ks_read_qmu - read 1 pkt data from the QMU. |
| 686 | * @ks: The chip information | 737 | * @ks: The chip information |
| @@ -752,7 +803,7 @@ static void ks_rcv(struct ks_net *ks, struct net_device *netdev) | |||
| 752 | (frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len)) { | 803 | (frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len)) { |
| 753 | skb_reserve(skb, 2); | 804 | skb_reserve(skb, 2); |
| 754 | /* read data block including CRC 4 bytes */ | 805 | /* read data block including CRC 4 bytes */ |
| 755 | ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len + 4); | 806 | ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len); |
| 756 | skb_put(skb, frame_hdr->len); | 807 | skb_put(skb, frame_hdr->len); |
| 757 | skb->dev = netdev; | 808 | skb->dev = netdev; |
| 758 | skb->protocol = eth_type_trans(skb, netdev); | 809 | skb->protocol = eth_type_trans(skb, netdev); |
| @@ -861,7 +912,7 @@ static int ks_net_open(struct net_device *netdev) | |||
| 861 | ks_dbg(ks, "%s - entry\n", __func__); | 912 | ks_dbg(ks, "%s - entry\n", __func__); |
| 862 | 913 | ||
| 863 | /* reset the HW */ | 914 | /* reset the HW */ |
| 864 | err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, ks); | 915 | err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, netdev); |
| 865 | 916 | ||
| 866 | if (err) { | 917 | if (err) { |
| 867 | printk(KERN_ERR "Failed to request IRQ: %d: %d\n", | 918 | printk(KERN_ERR "Failed to request IRQ: %d: %d\n", |
| @@ -869,6 +920,15 @@ static int ks_net_open(struct net_device *netdev) | |||
| 869 | return err; | 920 | return err; |
| 870 | } | 921 | } |
| 871 | 922 | ||
| 923 | /* wake up powermode to normal mode */ | ||
| 924 | ks_set_powermode(ks, PMECR_PM_NORMAL); | ||
| 925 | mdelay(1); /* wait for normal mode to take effect */ | ||
| 926 | |||
| 927 | ks_wrreg16(ks, KS_ISR, 0xffff); | ||
| 928 | ks_enable_int(ks); | ||
| 929 | ks_enable_qmu(ks); | ||
| 930 | netif_start_queue(ks->netdev); | ||
| 931 | |||
| 872 | if (netif_msg_ifup(ks)) | 932 | if (netif_msg_ifup(ks)) |
| 873 | ks_dbg(ks, "network device %s up\n", netdev->name); | 933 | ks_dbg(ks, "network device %s up\n", netdev->name); |
| 874 | 934 | ||
| @@ -892,19 +952,14 @@ static int ks_net_stop(struct net_device *netdev) | |||
| 892 | 952 | ||
| 893 | netif_stop_queue(netdev); | 953 | netif_stop_queue(netdev); |
| 894 | 954 | ||
| 895 | kfree(ks->frame_head_info); | ||
| 896 | |||
| 897 | mutex_lock(&ks->lock); | 955 | mutex_lock(&ks->lock); |
| 898 | 956 | ||
| 899 | /* turn off the IRQs and ack any outstanding */ | 957 | /* turn off the IRQs and ack any outstanding */ |
| 900 | ks_wrreg16(ks, KS_IER, 0x0000); | 958 | ks_wrreg16(ks, KS_IER, 0x0000); |
| 901 | ks_wrreg16(ks, KS_ISR, 0xffff); | 959 | ks_wrreg16(ks, KS_ISR, 0xffff); |
| 902 | 960 | ||
| 903 | /* shutdown RX process */ | 961 | /* shutdown RX/TX QMU */ |
| 904 | ks_wrreg16(ks, KS_RXCR1, 0x0000); | 962 | ks_disable_qmu(ks); |
| 905 | |||
| 906 | /* shutdown TX process */ | ||
| 907 | ks_wrreg16(ks, KS_TXCR, 0x0000); | ||
| 908 | 963 | ||
| 909 | /* set powermode to soft power down to save power */ | 964 | /* set powermode to soft power down to save power */ |
| 910 | ks_set_powermode(ks, PMECR_PM_SOFTDOWN); | 965 | ks_set_powermode(ks, PMECR_PM_SOFTDOWN); |
| @@ -929,17 +984,8 @@ static int ks_net_stop(struct net_device *netdev) | |||
| 929 | */ | 984 | */ |
| 930 | static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len) | 985 | static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len) |
| 931 | { | 986 | { |
| 932 | unsigned fid = ks->fid; | ||
| 933 | |||
| 934 | fid = ks->fid; | ||
| 935 | ks->fid = (ks->fid + 1) & TXFR_TXFID_MASK; | ||
| 936 | |||
| 937 | /* reduce the tx interrupt occurrances. */ | ||
| 938 | if (!fid) | ||
| 939 | fid |= TXFR_TXIC; /* irq on completion */ | ||
| 940 | |||
| 941 | /* start header at txb[0] to align txw entries */ | 987 | /* start header at txb[0] to align txw entries */ |
| 942 | ks->txh.txw[0] = cpu_to_le16(fid); | 988 | ks->txh.txw[0] = 0; |
| 943 | ks->txh.txw[1] = cpu_to_le16(len); | 989 | ks->txh.txw[1] = cpu_to_le16(len); |
| 944 | 990 | ||
| 945 | /* 1. set sudo-DMA mode */ | 991 | /* 1. set sudo-DMA mode */ |
| @@ -957,16 +1003,6 @@ static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len) | |||
| 957 | ; | 1003 | ; |
| 958 | } | 1004 | } |
| 959 | 1005 | ||
| 960 | static void ks_disable_int(struct ks_net *ks) | ||
| 961 | { | ||
| 962 | ks_wrreg16(ks, KS_IER, 0x0000); | ||
| 963 | } /* ks_disable_int */ | ||
| 964 | |||
| 965 | static void ks_enable_int(struct ks_net *ks) | ||
| 966 | { | ||
| 967 | ks_wrreg16(ks, KS_IER, ks->rc_ier); | ||
| 968 | } /* ks_enable_int */ | ||
| 969 | |||
| 970 | /** | 1006 | /** |
| 971 | * ks_start_xmit - transmit packet | 1007 | * ks_start_xmit - transmit packet |
| 972 | * @skb : The buffer to transmit | 1008 | * @skb : The buffer to transmit |
| @@ -1410,25 +1446,6 @@ static int ks_read_selftest(struct ks_net *ks) | |||
| 1410 | return ret; | 1446 | return ret; |
| 1411 | } | 1447 | } |
| 1412 | 1448 | ||
| 1413 | static void ks_disable(struct ks_net *ks) | ||
| 1414 | { | ||
| 1415 | u16 w; | ||
| 1416 | |||
| 1417 | w = ks_rdreg16(ks, KS_TXCR); | ||
| 1418 | |||
| 1419 | /* Disables QMU Transmit (TXCR). */ | ||
| 1420 | w &= ~TXCR_TXE; | ||
| 1421 | ks_wrreg16(ks, KS_TXCR, w); | ||
| 1422 | |||
| 1423 | /* Disables QMU Receive (RXCR1). */ | ||
| 1424 | w = ks_rdreg16(ks, KS_RXCR1); | ||
| 1425 | w &= ~RXCR1_RXE ; | ||
| 1426 | ks_wrreg16(ks, KS_RXCR1, w); | ||
| 1427 | |||
| 1428 | ks->enabled = false; | ||
| 1429 | |||
| 1430 | } /* ks_disable */ | ||
| 1431 | |||
| 1432 | static void ks_setup(struct ks_net *ks) | 1449 | static void ks_setup(struct ks_net *ks) |
| 1433 | { | 1450 | { |
| 1434 | u16 w; | 1451 | u16 w; |
| @@ -1463,7 +1480,7 @@ static void ks_setup(struct ks_net *ks) | |||
| 1463 | w = TXCR_TXFCE | TXCR_TXPE | TXCR_TXCRC | TXCR_TCGIP; | 1480 | w = TXCR_TXFCE | TXCR_TXPE | TXCR_TXCRC | TXCR_TCGIP; |
| 1464 | ks_wrreg16(ks, KS_TXCR, w); | 1481 | ks_wrreg16(ks, KS_TXCR, w); |
| 1465 | 1482 | ||
| 1466 | w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE; | 1483 | w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE | RXCR1_RXME | RXCR1_RXIPFCC; |
| 1467 | 1484 | ||
| 1468 | if (ks->promiscuous) /* bPromiscuous */ | 1485 | if (ks->promiscuous) /* bPromiscuous */ |
| 1469 | w |= (RXCR1_RXAE | RXCR1_RXINVF); | 1486 | w |= (RXCR1_RXAE | RXCR1_RXINVF); |
| @@ -1486,28 +1503,6 @@ static void ks_setup_int(struct ks_net *ks) | |||
| 1486 | ks->rc_ier = (IRQ_LCI | IRQ_TXI | IRQ_RXI); | 1503 | ks->rc_ier = (IRQ_LCI | IRQ_TXI | IRQ_RXI); |
| 1487 | } /* ks_setup_int */ | 1504 | } /* ks_setup_int */ |
| 1488 | 1505 | ||
| 1489 | void ks_enable(struct ks_net *ks) | ||
| 1490 | { | ||
| 1491 | u16 w; | ||
| 1492 | |||
| 1493 | w = ks_rdreg16(ks, KS_TXCR); | ||
| 1494 | /* Enables QMU Transmit (TXCR). */ | ||
| 1495 | ks_wrreg16(ks, KS_TXCR, w | TXCR_TXE); | ||
| 1496 | |||
| 1497 | /* | ||
| 1498 | * RX Frame Count Threshold Enable and Auto-Dequeue RXQ Frame | ||
| 1499 | * Enable | ||
| 1500 | */ | ||
| 1501 | |||
| 1502 | w = ks_rdreg16(ks, KS_RXQCR); | ||
| 1503 | ks_wrreg16(ks, KS_RXQCR, w | RXQCR_RXFCTE); | ||
| 1504 | |||
| 1505 | /* Enables QMU Receive (RXCR1). */ | ||
| 1506 | w = ks_rdreg16(ks, KS_RXCR1); | ||
| 1507 | ks_wrreg16(ks, KS_RXCR1, w | RXCR1_RXE); | ||
| 1508 | ks->enabled = true; | ||
| 1509 | } /* ks_enable */ | ||
| 1510 | |||
| 1511 | static int ks_hw_init(struct ks_net *ks) | 1506 | static int ks_hw_init(struct ks_net *ks) |
| 1512 | { | 1507 | { |
| 1513 | #define MHEADER_SIZE (sizeof(struct type_frame_head) * MAX_RECV_FRAMES) | 1508 | #define MHEADER_SIZE (sizeof(struct type_frame_head) * MAX_RECV_FRAMES) |
| @@ -1612,11 +1607,9 @@ static int __devinit ks8851_probe(struct platform_device *pdev) | |||
| 1612 | 1607 | ||
| 1613 | ks_soft_reset(ks, GRR_GSR); | 1608 | ks_soft_reset(ks, GRR_GSR); |
| 1614 | ks_hw_init(ks); | 1609 | ks_hw_init(ks); |
| 1615 | ks_disable(ks); | 1610 | ks_disable_qmu(ks); |
| 1616 | ks_setup(ks); | 1611 | ks_setup(ks); |
| 1617 | ks_setup_int(ks); | 1612 | ks_setup_int(ks); |
| 1618 | ks_enable_int(ks); | ||
| 1619 | ks_enable(ks); | ||
| 1620 | memcpy(netdev->dev_addr, ks->mac_addr, 6); | 1613 | memcpy(netdev->dev_addr, ks->mac_addr, 6); |
| 1621 | 1614 | ||
| 1622 | data = ks_rdreg16(ks, KS_OBCR); | 1615 | data = ks_rdreg16(ks, KS_OBCR); |
| @@ -1658,6 +1651,7 @@ static int __devexit ks8851_remove(struct platform_device *pdev) | |||
| 1658 | struct ks_net *ks = netdev_priv(netdev); | 1651 | struct ks_net *ks = netdev_priv(netdev); |
| 1659 | struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1652 | struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1660 | 1653 | ||
| 1654 | kfree(ks->frame_head_info); | ||
| 1661 | unregister_netdev(netdev); | 1655 | unregister_netdev(netdev); |
| 1662 | iounmap(ks->hw_addr); | 1656 | iounmap(ks->hw_addr); |
| 1663 | free_netdev(netdev); | 1657 | free_netdev(netdev); |
