diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/8139cp.c | 100 | ||||
-rw-r--r-- | drivers/net/8139too.c | 194 | ||||
-rw-r--r-- | drivers/net/Kconfig | 12 | ||||
-rw-r--r-- | drivers/net/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/dm9000.c | 1219 | ||||
-rw-r--r-- | drivers/net/dm9000.h | 135 | ||||
-rw-r--r-- | drivers/net/hamradio/baycom_epp.c | 126 | ||||
-rw-r--r-- | drivers/net/ppp_generic.c | 177 | ||||
-rw-r--r-- | drivers/net/shaper.c | 86 | ||||
-rw-r--r-- | drivers/net/tg3.c | 571 | ||||
-rw-r--r-- | drivers/net/wan/hdlc_fr.c | 320 | ||||
-rw-r--r-- | drivers/net/wan/hdlc_generic.c | 16 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco.c | 332 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco.h | 1 |
14 files changed, 2500 insertions, 790 deletions
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index d639cb8dc461..72cdf19e1be1 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c | |||
@@ -54,6 +54,7 @@ | |||
54 | 54 | ||
55 | #include <linux/config.h> | 55 | #include <linux/config.h> |
56 | #include <linux/module.h> | 56 | #include <linux/module.h> |
57 | #include <linux/moduleparam.h> | ||
57 | #include <linux/kernel.h> | 58 | #include <linux/kernel.h> |
58 | #include <linux/compiler.h> | 59 | #include <linux/compiler.h> |
59 | #include <linux/netdevice.h> | 60 | #include <linux/netdevice.h> |
@@ -91,16 +92,17 @@ KERN_INFO DRV_NAME ": 10/100 PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE | |||
91 | 92 | ||
92 | MODULE_AUTHOR("Jeff Garzik <jgarzik@pobox.com>"); | 93 | MODULE_AUTHOR("Jeff Garzik <jgarzik@pobox.com>"); |
93 | MODULE_DESCRIPTION("RealTek RTL-8139C+ series 10/100 PCI Ethernet driver"); | 94 | MODULE_DESCRIPTION("RealTek RTL-8139C+ series 10/100 PCI Ethernet driver"); |
95 | MODULE_VERSION(DRV_VERSION); | ||
94 | MODULE_LICENSE("GPL"); | 96 | MODULE_LICENSE("GPL"); |
95 | 97 | ||
96 | static int debug = -1; | 98 | static int debug = -1; |
97 | MODULE_PARM (debug, "i"); | 99 | module_param(debug, int, 0); |
98 | MODULE_PARM_DESC (debug, "8139cp: bitmapped message enable number"); | 100 | MODULE_PARM_DESC (debug, "8139cp: bitmapped message enable number"); |
99 | 101 | ||
100 | /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). | 102 | /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). |
101 | The RTL chips use a 64 element hash table based on the Ethernet CRC. */ | 103 | The RTL chips use a 64 element hash table based on the Ethernet CRC. */ |
102 | static int multicast_filter_limit = 32; | 104 | static int multicast_filter_limit = 32; |
103 | MODULE_PARM (multicast_filter_limit, "i"); | 105 | module_param(multicast_filter_limit, int, 0); |
104 | MODULE_PARM_DESC (multicast_filter_limit, "8139cp: maximum number of filtered multicast addresses"); | 106 | MODULE_PARM_DESC (multicast_filter_limit, "8139cp: maximum number of filtered multicast addresses"); |
105 | 107 | ||
106 | #define PFX DRV_NAME ": " | 108 | #define PFX DRV_NAME ": " |
@@ -186,6 +188,9 @@ enum { | |||
186 | RingEnd = (1 << 30), /* End of descriptor ring */ | 188 | RingEnd = (1 << 30), /* End of descriptor ring */ |
187 | FirstFrag = (1 << 29), /* First segment of a packet */ | 189 | FirstFrag = (1 << 29), /* First segment of a packet */ |
188 | LastFrag = (1 << 28), /* Final segment of a packet */ | 190 | LastFrag = (1 << 28), /* Final segment of a packet */ |
191 | LargeSend = (1 << 27), /* TCP Large Send Offload (TSO) */ | ||
192 | MSSShift = 16, /* MSS value position */ | ||
193 | MSSMask = 0xfff, /* MSS value: 11 bits */ | ||
189 | TxError = (1 << 23), /* Tx error summary */ | 194 | TxError = (1 << 23), /* Tx error summary */ |
190 | RxError = (1 << 20), /* Rx error summary */ | 195 | RxError = (1 << 20), /* Rx error summary */ |
191 | IPCS = (1 << 18), /* Calculate IP checksum */ | 196 | IPCS = (1 << 18), /* Calculate IP checksum */ |
@@ -312,7 +317,7 @@ struct cp_desc { | |||
312 | struct ring_info { | 317 | struct ring_info { |
313 | struct sk_buff *skb; | 318 | struct sk_buff *skb; |
314 | dma_addr_t mapping; | 319 | dma_addr_t mapping; |
315 | unsigned frag; | 320 | u32 len; |
316 | }; | 321 | }; |
317 | 322 | ||
318 | struct cp_dma_stats { | 323 | struct cp_dma_stats { |
@@ -394,6 +399,9 @@ struct cp_private { | |||
394 | static void __cp_set_rx_mode (struct net_device *dev); | 399 | static void __cp_set_rx_mode (struct net_device *dev); |
395 | static void cp_tx (struct cp_private *cp); | 400 | static void cp_tx (struct cp_private *cp); |
396 | static void cp_clean_rings (struct cp_private *cp); | 401 | static void cp_clean_rings (struct cp_private *cp); |
402 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
403 | static void cp_poll_controller(struct net_device *dev); | ||
404 | #endif | ||
397 | 405 | ||
398 | static struct pci_device_id cp_pci_tbl[] = { | 406 | static struct pci_device_id cp_pci_tbl[] = { |
399 | { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139, | 407 | { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139, |
@@ -688,6 +696,19 @@ cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs) | |||
688 | return IRQ_HANDLED; | 696 | return IRQ_HANDLED; |
689 | } | 697 | } |
690 | 698 | ||
699 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
700 | /* | ||
701 | * Polling receive - used by netconsole and other diagnostic tools | ||
702 | * to allow network i/o with interrupts disabled. | ||
703 | */ | ||
704 | static void cp_poll_controller(struct net_device *dev) | ||
705 | { | ||
706 | disable_irq(dev->irq); | ||
707 | cp_interrupt(dev->irq, dev, NULL); | ||
708 | enable_irq(dev->irq); | ||
709 | } | ||
710 | #endif | ||
711 | |||
691 | static void cp_tx (struct cp_private *cp) | 712 | static void cp_tx (struct cp_private *cp) |
692 | { | 713 | { |
693 | unsigned tx_head = cp->tx_head; | 714 | unsigned tx_head = cp->tx_head; |
@@ -707,7 +728,7 @@ static void cp_tx (struct cp_private *cp) | |||
707 | BUG(); | 728 | BUG(); |
708 | 729 | ||
709 | pci_unmap_single(cp->pdev, cp->tx_skb[tx_tail].mapping, | 730 | pci_unmap_single(cp->pdev, cp->tx_skb[tx_tail].mapping, |
710 | skb->len, PCI_DMA_TODEVICE); | 731 | cp->tx_skb[tx_tail].len, PCI_DMA_TODEVICE); |
711 | 732 | ||
712 | if (status & LastFrag) { | 733 | if (status & LastFrag) { |
713 | if (status & (TxError | TxFIFOUnder)) { | 734 | if (status & (TxError | TxFIFOUnder)) { |
@@ -749,10 +770,11 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) | |||
749 | { | 770 | { |
750 | struct cp_private *cp = netdev_priv(dev); | 771 | struct cp_private *cp = netdev_priv(dev); |
751 | unsigned entry; | 772 | unsigned entry; |
752 | u32 eor; | 773 | u32 eor, flags; |
753 | #if CP_VLAN_TAG_USED | 774 | #if CP_VLAN_TAG_USED |
754 | u32 vlan_tag = 0; | 775 | u32 vlan_tag = 0; |
755 | #endif | 776 | #endif |
777 | int mss = 0; | ||
756 | 778 | ||
757 | spin_lock_irq(&cp->lock); | 779 | spin_lock_irq(&cp->lock); |
758 | 780 | ||
@@ -772,6 +794,9 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) | |||
772 | 794 | ||
773 | entry = cp->tx_head; | 795 | entry = cp->tx_head; |
774 | eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; | 796 | eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; |
797 | if (dev->features & NETIF_F_TSO) | ||
798 | mss = skb_shinfo(skb)->tso_size; | ||
799 | |||
775 | if (skb_shinfo(skb)->nr_frags == 0) { | 800 | if (skb_shinfo(skb)->nr_frags == 0) { |
776 | struct cp_desc *txd = &cp->tx_ring[entry]; | 801 | struct cp_desc *txd = &cp->tx_ring[entry]; |
777 | u32 len; | 802 | u32 len; |
@@ -783,26 +808,26 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) | |||
783 | txd->addr = cpu_to_le64(mapping); | 808 | txd->addr = cpu_to_le64(mapping); |
784 | wmb(); | 809 | wmb(); |
785 | 810 | ||
786 | if (skb->ip_summed == CHECKSUM_HW) { | 811 | flags = eor | len | DescOwn | FirstFrag | LastFrag; |
812 | |||
813 | if (mss) | ||
814 | flags |= LargeSend | ((mss & MSSMask) << MSSShift); | ||
815 | else if (skb->ip_summed == CHECKSUM_HW) { | ||
787 | const struct iphdr *ip = skb->nh.iph; | 816 | const struct iphdr *ip = skb->nh.iph; |
788 | if (ip->protocol == IPPROTO_TCP) | 817 | if (ip->protocol == IPPROTO_TCP) |
789 | txd->opts1 = cpu_to_le32(eor | len | DescOwn | | 818 | flags |= IPCS | TCPCS; |
790 | FirstFrag | LastFrag | | ||
791 | IPCS | TCPCS); | ||
792 | else if (ip->protocol == IPPROTO_UDP) | 819 | else if (ip->protocol == IPPROTO_UDP) |
793 | txd->opts1 = cpu_to_le32(eor | len | DescOwn | | 820 | flags |= IPCS | UDPCS; |
794 | FirstFrag | LastFrag | | ||
795 | IPCS | UDPCS); | ||
796 | else | 821 | else |
797 | BUG(); | 822 | WARN_ON(1); /* we need a WARN() */ |
798 | } else | 823 | } |
799 | txd->opts1 = cpu_to_le32(eor | len | DescOwn | | 824 | |
800 | FirstFrag | LastFrag); | 825 | txd->opts1 = cpu_to_le32(flags); |
801 | wmb(); | 826 | wmb(); |
802 | 827 | ||
803 | cp->tx_skb[entry].skb = skb; | 828 | cp->tx_skb[entry].skb = skb; |
804 | cp->tx_skb[entry].mapping = mapping; | 829 | cp->tx_skb[entry].mapping = mapping; |
805 | cp->tx_skb[entry].frag = 0; | 830 | cp->tx_skb[entry].len = len; |
806 | entry = NEXT_TX(entry); | 831 | entry = NEXT_TX(entry); |
807 | } else { | 832 | } else { |
808 | struct cp_desc *txd; | 833 | struct cp_desc *txd; |
@@ -820,7 +845,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) | |||
820 | first_len, PCI_DMA_TODEVICE); | 845 | first_len, PCI_DMA_TODEVICE); |
821 | cp->tx_skb[entry].skb = skb; | 846 | cp->tx_skb[entry].skb = skb; |
822 | cp->tx_skb[entry].mapping = first_mapping; | 847 | cp->tx_skb[entry].mapping = first_mapping; |
823 | cp->tx_skb[entry].frag = 1; | 848 | cp->tx_skb[entry].len = first_len; |
824 | entry = NEXT_TX(entry); | 849 | entry = NEXT_TX(entry); |
825 | 850 | ||
826 | for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { | 851 | for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { |
@@ -836,16 +861,19 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) | |||
836 | len, PCI_DMA_TODEVICE); | 861 | len, PCI_DMA_TODEVICE); |
837 | eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; | 862 | eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; |
838 | 863 | ||
839 | if (skb->ip_summed == CHECKSUM_HW) { | 864 | ctrl = eor | len | DescOwn; |
840 | ctrl = eor | len | DescOwn | IPCS; | 865 | |
866 | if (mss) | ||
867 | ctrl |= LargeSend | | ||
868 | ((mss & MSSMask) << MSSShift); | ||
869 | else if (skb->ip_summed == CHECKSUM_HW) { | ||
841 | if (ip->protocol == IPPROTO_TCP) | 870 | if (ip->protocol == IPPROTO_TCP) |
842 | ctrl |= TCPCS; | 871 | ctrl |= IPCS | TCPCS; |
843 | else if (ip->protocol == IPPROTO_UDP) | 872 | else if (ip->protocol == IPPROTO_UDP) |
844 | ctrl |= UDPCS; | 873 | ctrl |= IPCS | UDPCS; |
845 | else | 874 | else |
846 | BUG(); | 875 | BUG(); |
847 | } else | 876 | } |
848 | ctrl = eor | len | DescOwn; | ||
849 | 877 | ||
850 | if (frag == skb_shinfo(skb)->nr_frags - 1) | 878 | if (frag == skb_shinfo(skb)->nr_frags - 1) |
851 | ctrl |= LastFrag; | 879 | ctrl |= LastFrag; |
@@ -860,7 +888,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) | |||
860 | 888 | ||
861 | cp->tx_skb[entry].skb = skb; | 889 | cp->tx_skb[entry].skb = skb; |
862 | cp->tx_skb[entry].mapping = mapping; | 890 | cp->tx_skb[entry].mapping = mapping; |
863 | cp->tx_skb[entry].frag = frag + 2; | 891 | cp->tx_skb[entry].len = len; |
864 | entry = NEXT_TX(entry); | 892 | entry = NEXT_TX(entry); |
865 | } | 893 | } |
866 | 894 | ||
@@ -1074,7 +1102,6 @@ static int cp_refill_rx (struct cp_private *cp) | |||
1074 | cp->rx_skb[i].mapping = pci_map_single(cp->pdev, | 1102 | cp->rx_skb[i].mapping = pci_map_single(cp->pdev, |
1075 | skb->tail, cp->rx_buf_sz, PCI_DMA_FROMDEVICE); | 1103 | skb->tail, cp->rx_buf_sz, PCI_DMA_FROMDEVICE); |
1076 | cp->rx_skb[i].skb = skb; | 1104 | cp->rx_skb[i].skb = skb; |
1077 | cp->rx_skb[i].frag = 0; | ||
1078 | 1105 | ||
1079 | cp->rx_ring[i].opts2 = 0; | 1106 | cp->rx_ring[i].opts2 = 0; |
1080 | cp->rx_ring[i].addr = cpu_to_le64(cp->rx_skb[i].mapping); | 1107 | cp->rx_ring[i].addr = cpu_to_le64(cp->rx_skb[i].mapping); |
@@ -1126,9 +1153,6 @@ static void cp_clean_rings (struct cp_private *cp) | |||
1126 | { | 1153 | { |
1127 | unsigned i; | 1154 | unsigned i; |
1128 | 1155 | ||
1129 | memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE); | ||
1130 | memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE); | ||
1131 | |||
1132 | for (i = 0; i < CP_RX_RING_SIZE; i++) { | 1156 | for (i = 0; i < CP_RX_RING_SIZE; i++) { |
1133 | if (cp->rx_skb[i].skb) { | 1157 | if (cp->rx_skb[i].skb) { |
1134 | pci_unmap_single(cp->pdev, cp->rx_skb[i].mapping, | 1158 | pci_unmap_single(cp->pdev, cp->rx_skb[i].mapping, |
@@ -1140,13 +1164,18 @@ static void cp_clean_rings (struct cp_private *cp) | |||
1140 | for (i = 0; i < CP_TX_RING_SIZE; i++) { | 1164 | for (i = 0; i < CP_TX_RING_SIZE; i++) { |
1141 | if (cp->tx_skb[i].skb) { | 1165 | if (cp->tx_skb[i].skb) { |
1142 | struct sk_buff *skb = cp->tx_skb[i].skb; | 1166 | struct sk_buff *skb = cp->tx_skb[i].skb; |
1167 | |||
1143 | pci_unmap_single(cp->pdev, cp->tx_skb[i].mapping, | 1168 | pci_unmap_single(cp->pdev, cp->tx_skb[i].mapping, |
1144 | skb->len, PCI_DMA_TODEVICE); | 1169 | cp->tx_skb[i].len, PCI_DMA_TODEVICE); |
1145 | dev_kfree_skb(skb); | 1170 | if (le32_to_cpu(cp->tx_ring[i].opts1) & LastFrag) |
1171 | dev_kfree_skb(skb); | ||
1146 | cp->net_stats.tx_dropped++; | 1172 | cp->net_stats.tx_dropped++; |
1147 | } | 1173 | } |
1148 | } | 1174 | } |
1149 | 1175 | ||
1176 | memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE); | ||
1177 | memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE); | ||
1178 | |||
1150 | memset(&cp->rx_skb, 0, sizeof(struct ring_info) * CP_RX_RING_SIZE); | 1179 | memset(&cp->rx_skb, 0, sizeof(struct ring_info) * CP_RX_RING_SIZE); |
1151 | memset(&cp->tx_skb, 0, sizeof(struct ring_info) * CP_TX_RING_SIZE); | 1180 | memset(&cp->tx_skb, 0, sizeof(struct ring_info) * CP_TX_RING_SIZE); |
1152 | } | 1181 | } |
@@ -1538,6 +1567,8 @@ static struct ethtool_ops cp_ethtool_ops = { | |||
1538 | .set_tx_csum = ethtool_op_set_tx_csum, /* local! */ | 1567 | .set_tx_csum = ethtool_op_set_tx_csum, /* local! */ |
1539 | .get_sg = ethtool_op_get_sg, | 1568 | .get_sg = ethtool_op_get_sg, |
1540 | .set_sg = ethtool_op_set_sg, | 1569 | .set_sg = ethtool_op_set_sg, |
1570 | .get_tso = ethtool_op_get_tso, | ||
1571 | .set_tso = ethtool_op_set_tso, | ||
1541 | .get_regs = cp_get_regs, | 1572 | .get_regs = cp_get_regs, |
1542 | .get_wol = cp_get_wol, | 1573 | .get_wol = cp_get_wol, |
1543 | .set_wol = cp_set_wol, | 1574 | .set_wol = cp_set_wol, |
@@ -1749,6 +1780,9 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1749 | dev->get_stats = cp_get_stats; | 1780 | dev->get_stats = cp_get_stats; |
1750 | dev->do_ioctl = cp_ioctl; | 1781 | dev->do_ioctl = cp_ioctl; |
1751 | dev->poll = cp_rx_poll; | 1782 | dev->poll = cp_rx_poll; |
1783 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
1784 | dev->poll_controller = cp_poll_controller; | ||
1785 | #endif | ||
1752 | dev->weight = 16; /* arbitrary? from NAPI_HOWTO.txt. */ | 1786 | dev->weight = 16; /* arbitrary? from NAPI_HOWTO.txt. */ |
1753 | #ifdef BROKEN | 1787 | #ifdef BROKEN |
1754 | dev->change_mtu = cp_change_mtu; | 1788 | dev->change_mtu = cp_change_mtu; |
@@ -1768,6 +1802,10 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1768 | if (pci_using_dac) | 1802 | if (pci_using_dac) |
1769 | dev->features |= NETIF_F_HIGHDMA; | 1803 | dev->features |= NETIF_F_HIGHDMA; |
1770 | 1804 | ||
1805 | #if 0 /* disabled by default until verified */ | ||
1806 | dev->features |= NETIF_F_TSO; | ||
1807 | #endif | ||
1808 | |||
1771 | dev->irq = pdev->irq; | 1809 | dev->irq = pdev->irq; |
1772 | 1810 | ||
1773 | rc = register_netdev(dev); | 1811 | rc = register_netdev(dev); |
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index d4bd20c21a1f..047202c4d9a8 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c | |||
@@ -569,7 +569,7 @@ struct rtl_extra_stats { | |||
569 | }; | 569 | }; |
570 | 570 | ||
571 | struct rtl8139_private { | 571 | struct rtl8139_private { |
572 | void *mmio_addr; | 572 | void __iomem *mmio_addr; |
573 | int drv_flags; | 573 | int drv_flags; |
574 | struct pci_dev *pci_dev; | 574 | struct pci_dev *pci_dev; |
575 | u32 msg_enable; | 575 | u32 msg_enable; |
@@ -614,7 +614,7 @@ MODULE_PARM_DESC (multicast_filter_limit, "8139too maximum number of filtered mu | |||
614 | MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps"); | 614 | MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps"); |
615 | MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)"); | 615 | MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)"); |
616 | 616 | ||
617 | static int read_eeprom (void *ioaddr, int location, int addr_len); | 617 | static int read_eeprom (void __iomem *ioaddr, int location, int addr_len); |
618 | static int rtl8139_open (struct net_device *dev); | 618 | static int rtl8139_open (struct net_device *dev); |
619 | static int mdio_read (struct net_device *dev, int phy_id, int location); | 619 | static int mdio_read (struct net_device *dev, int phy_id, int location); |
620 | static void mdio_write (struct net_device *dev, int phy_id, int location, | 620 | static void mdio_write (struct net_device *dev, int phy_id, int location, |
@@ -638,46 +638,20 @@ static void __set_rx_mode (struct net_device *dev); | |||
638 | static void rtl8139_hw_start (struct net_device *dev); | 638 | static void rtl8139_hw_start (struct net_device *dev); |
639 | static struct ethtool_ops rtl8139_ethtool_ops; | 639 | static struct ethtool_ops rtl8139_ethtool_ops; |
640 | 640 | ||
641 | #ifdef USE_IO_OPS | ||
642 | |||
643 | #define RTL_R8(reg) inb (((unsigned long)ioaddr) + (reg)) | ||
644 | #define RTL_R16(reg) inw (((unsigned long)ioaddr) + (reg)) | ||
645 | #define RTL_R32(reg) ((unsigned long) inl (((unsigned long)ioaddr) + (reg))) | ||
646 | #define RTL_W8(reg, val8) outb ((val8), ((unsigned long)ioaddr) + (reg)) | ||
647 | #define RTL_W16(reg, val16) outw ((val16), ((unsigned long)ioaddr) + (reg)) | ||
648 | #define RTL_W32(reg, val32) outl ((val32), ((unsigned long)ioaddr) + (reg)) | ||
649 | #define RTL_W8_F RTL_W8 | ||
650 | #define RTL_W16_F RTL_W16 | ||
651 | #define RTL_W32_F RTL_W32 | ||
652 | #undef readb | ||
653 | #undef readw | ||
654 | #undef readl | ||
655 | #undef writeb | ||
656 | #undef writew | ||
657 | #undef writel | ||
658 | #define readb(addr) inb((unsigned long)(addr)) | ||
659 | #define readw(addr) inw((unsigned long)(addr)) | ||
660 | #define readl(addr) inl((unsigned long)(addr)) | ||
661 | #define writeb(val,addr) outb((val),(unsigned long)(addr)) | ||
662 | #define writew(val,addr) outw((val),(unsigned long)(addr)) | ||
663 | #define writel(val,addr) outl((val),(unsigned long)(addr)) | ||
664 | |||
665 | #else | ||
666 | |||
667 | /* write MMIO register, with flush */ | 641 | /* write MMIO register, with flush */ |
668 | /* Flush avoids rtl8139 bug w/ posted MMIO writes */ | 642 | /* Flush avoids rtl8139 bug w/ posted MMIO writes */ |
669 | #define RTL_W8_F(reg, val8) do { writeb ((val8), ioaddr + (reg)); readb (ioaddr + (reg)); } while (0) | 643 | #define RTL_W8_F(reg, val8) do { iowrite8 ((val8), ioaddr + (reg)); ioread8 (ioaddr + (reg)); } while (0) |
670 | #define RTL_W16_F(reg, val16) do { writew ((val16), ioaddr + (reg)); readw (ioaddr + (reg)); } while (0) | 644 | #define RTL_W16_F(reg, val16) do { iowrite16 ((val16), ioaddr + (reg)); ioread16 (ioaddr + (reg)); } while (0) |
671 | #define RTL_W32_F(reg, val32) do { writel ((val32), ioaddr + (reg)); readl (ioaddr + (reg)); } while (0) | 645 | #define RTL_W32_F(reg, val32) do { iowrite32 ((val32), ioaddr + (reg)); ioread32 (ioaddr + (reg)); } while (0) |
672 | 646 | ||
673 | 647 | ||
674 | #define MMIO_FLUSH_AUDIT_COMPLETE 1 | 648 | #define MMIO_FLUSH_AUDIT_COMPLETE 1 |
675 | #if MMIO_FLUSH_AUDIT_COMPLETE | 649 | #if MMIO_FLUSH_AUDIT_COMPLETE |
676 | 650 | ||
677 | /* write MMIO register */ | 651 | /* write MMIO register */ |
678 | #define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) | 652 | #define RTL_W8(reg, val8) iowrite8 ((val8), ioaddr + (reg)) |
679 | #define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg)) | 653 | #define RTL_W16(reg, val16) iowrite16 ((val16), ioaddr + (reg)) |
680 | #define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg)) | 654 | #define RTL_W32(reg, val32) iowrite32 ((val32), ioaddr + (reg)) |
681 | 655 | ||
682 | #else | 656 | #else |
683 | 657 | ||
@@ -689,11 +663,9 @@ static struct ethtool_ops rtl8139_ethtool_ops; | |||
689 | #endif /* MMIO_FLUSH_AUDIT_COMPLETE */ | 663 | #endif /* MMIO_FLUSH_AUDIT_COMPLETE */ |
690 | 664 | ||
691 | /* read MMIO register */ | 665 | /* read MMIO register */ |
692 | #define RTL_R8(reg) readb (ioaddr + (reg)) | 666 | #define RTL_R8(reg) ioread8 (ioaddr + (reg)) |
693 | #define RTL_R16(reg) readw (ioaddr + (reg)) | 667 | #define RTL_R16(reg) ioread16 (ioaddr + (reg)) |
694 | #define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) | 668 | #define RTL_R32(reg) ((unsigned long) ioread32 (ioaddr + (reg))) |
695 | |||
696 | #endif /* USE_IO_OPS */ | ||
697 | 669 | ||
698 | 670 | ||
699 | static const u16 rtl8139_intr_mask = | 671 | static const u16 rtl8139_intr_mask = |
@@ -740,10 +712,13 @@ static void __rtl8139_cleanup_dev (struct net_device *dev) | |||
740 | assert (tp->pci_dev != NULL); | 712 | assert (tp->pci_dev != NULL); |
741 | pdev = tp->pci_dev; | 713 | pdev = tp->pci_dev; |
742 | 714 | ||
743 | #ifndef USE_IO_OPS | 715 | #ifdef USE_IO_OPS |
716 | if (tp->mmio_addr) | ||
717 | ioport_unmap (tp->mmio_addr); | ||
718 | #else | ||
744 | if (tp->mmio_addr) | 719 | if (tp->mmio_addr) |
745 | iounmap (tp->mmio_addr); | 720 | pci_iounmap (pdev, tp->mmio_addr); |
746 | #endif /* !USE_IO_OPS */ | 721 | #endif /* USE_IO_OPS */ |
747 | 722 | ||
748 | /* it's ok to call this even if we have no regions to free */ | 723 | /* it's ok to call this even if we have no regions to free */ |
749 | pci_release_regions (pdev); | 724 | pci_release_regions (pdev); |
@@ -753,7 +728,7 @@ static void __rtl8139_cleanup_dev (struct net_device *dev) | |||
753 | } | 728 | } |
754 | 729 | ||
755 | 730 | ||
756 | static void rtl8139_chip_reset (void *ioaddr) | 731 | static void rtl8139_chip_reset (void __iomem *ioaddr) |
757 | { | 732 | { |
758 | int i; | 733 | int i; |
759 | 734 | ||
@@ -773,7 +748,7 @@ static void rtl8139_chip_reset (void *ioaddr) | |||
773 | static int __devinit rtl8139_init_board (struct pci_dev *pdev, | 748 | static int __devinit rtl8139_init_board (struct pci_dev *pdev, |
774 | struct net_device **dev_out) | 749 | struct net_device **dev_out) |
775 | { | 750 | { |
776 | void *ioaddr; | 751 | void __iomem *ioaddr; |
777 | struct net_device *dev; | 752 | struct net_device *dev; |
778 | struct rtl8139_private *tp; | 753 | struct rtl8139_private *tp; |
779 | u8 tmp8; | 754 | u8 tmp8; |
@@ -855,13 +830,18 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev, | |||
855 | pci_set_master (pdev); | 830 | pci_set_master (pdev); |
856 | 831 | ||
857 | #ifdef USE_IO_OPS | 832 | #ifdef USE_IO_OPS |
858 | ioaddr = (void *) pio_start; | 833 | ioaddr = ioport_map(pio_start, pio_len); |
834 | if (!ioaddr) { | ||
835 | printk (KERN_ERR PFX "%s: cannot map PIO, aborting\n", pci_name(pdev)); | ||
836 | rc = -EIO; | ||
837 | goto err_out; | ||
838 | } | ||
859 | dev->base_addr = pio_start; | 839 | dev->base_addr = pio_start; |
860 | tp->mmio_addr = ioaddr; | 840 | tp->mmio_addr = ioaddr; |
861 | tp->regs_len = pio_len; | 841 | tp->regs_len = pio_len; |
862 | #else | 842 | #else |
863 | /* ioremap MMIO region */ | 843 | /* ioremap MMIO region */ |
864 | ioaddr = ioremap (mmio_start, mmio_len); | 844 | ioaddr = pci_iomap(pdev, 1, 0); |
865 | if (ioaddr == NULL) { | 845 | if (ioaddr == NULL) { |
866 | printk (KERN_ERR PFX "%s: cannot remap MMIO, aborting\n", pci_name(pdev)); | 846 | printk (KERN_ERR PFX "%s: cannot remap MMIO, aborting\n", pci_name(pdev)); |
867 | rc = -EIO; | 847 | rc = -EIO; |
@@ -947,7 +927,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev, | |||
947 | struct net_device *dev = NULL; | 927 | struct net_device *dev = NULL; |
948 | struct rtl8139_private *tp; | 928 | struct rtl8139_private *tp; |
949 | int i, addr_len, option; | 929 | int i, addr_len, option; |
950 | void *ioaddr; | 930 | void __iomem *ioaddr; |
951 | static int board_idx = -1; | 931 | static int board_idx = -1; |
952 | u8 pci_rev; | 932 | u8 pci_rev; |
953 | 933 | ||
@@ -1147,47 +1127,46 @@ static void __devexit rtl8139_remove_one (struct pci_dev *pdev) | |||
1147 | No extra delay is needed with 33Mhz PCI, but 66Mhz may change this. | 1127 | No extra delay is needed with 33Mhz PCI, but 66Mhz may change this. |
1148 | */ | 1128 | */ |
1149 | 1129 | ||
1150 | #define eeprom_delay() readl(ee_addr) | 1130 | #define eeprom_delay() RTL_R32(Cfg9346) |
1151 | 1131 | ||
1152 | /* The EEPROM commands include the alway-set leading bit. */ | 1132 | /* The EEPROM commands include the alway-set leading bit. */ |
1153 | #define EE_WRITE_CMD (5) | 1133 | #define EE_WRITE_CMD (5) |
1154 | #define EE_READ_CMD (6) | 1134 | #define EE_READ_CMD (6) |
1155 | #define EE_ERASE_CMD (7) | 1135 | #define EE_ERASE_CMD (7) |
1156 | 1136 | ||
1157 | static int __devinit read_eeprom (void *ioaddr, int location, int addr_len) | 1137 | static int __devinit read_eeprom (void __iomem *ioaddr, int location, int addr_len) |
1158 | { | 1138 | { |
1159 | int i; | 1139 | int i; |
1160 | unsigned retval = 0; | 1140 | unsigned retval = 0; |
1161 | void *ee_addr = ioaddr + Cfg9346; | ||
1162 | int read_cmd = location | (EE_READ_CMD << addr_len); | 1141 | int read_cmd = location | (EE_READ_CMD << addr_len); |
1163 | 1142 | ||
1164 | writeb (EE_ENB & ~EE_CS, ee_addr); | 1143 | RTL_W8 (Cfg9346, EE_ENB & ~EE_CS); |
1165 | writeb (EE_ENB, ee_addr); | 1144 | RTL_W8 (Cfg9346, EE_ENB); |
1166 | eeprom_delay (); | 1145 | eeprom_delay (); |
1167 | 1146 | ||
1168 | /* Shift the read command bits out. */ | 1147 | /* Shift the read command bits out. */ |
1169 | for (i = 4 + addr_len; i >= 0; i--) { | 1148 | for (i = 4 + addr_len; i >= 0; i--) { |
1170 | int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; | 1149 | int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; |
1171 | writeb (EE_ENB | dataval, ee_addr); | 1150 | RTL_W8 (Cfg9346, EE_ENB | dataval); |
1172 | eeprom_delay (); | 1151 | eeprom_delay (); |
1173 | writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); | 1152 | RTL_W8 (Cfg9346, EE_ENB | dataval | EE_SHIFT_CLK); |
1174 | eeprom_delay (); | 1153 | eeprom_delay (); |
1175 | } | 1154 | } |
1176 | writeb (EE_ENB, ee_addr); | 1155 | RTL_W8 (Cfg9346, EE_ENB); |
1177 | eeprom_delay (); | 1156 | eeprom_delay (); |
1178 | 1157 | ||
1179 | for (i = 16; i > 0; i--) { | 1158 | for (i = 16; i > 0; i--) { |
1180 | writeb (EE_ENB | EE_SHIFT_CLK, ee_addr); | 1159 | RTL_W8 (Cfg9346, EE_ENB | EE_SHIFT_CLK); |
1181 | eeprom_delay (); | 1160 | eeprom_delay (); |
1182 | retval = | 1161 | retval = |
1183 | (retval << 1) | ((readb (ee_addr) & EE_DATA_READ) ? 1 : | 1162 | (retval << 1) | ((RTL_R8 (Cfg9346) & EE_DATA_READ) ? 1 : |
1184 | 0); | 1163 | 0); |
1185 | writeb (EE_ENB, ee_addr); | 1164 | RTL_W8 (Cfg9346, EE_ENB); |
1186 | eeprom_delay (); | 1165 | eeprom_delay (); |
1187 | } | 1166 | } |
1188 | 1167 | ||
1189 | /* Terminate the EEPROM access. */ | 1168 | /* Terminate the EEPROM access. */ |
1190 | writeb (~EE_CS, ee_addr); | 1169 | RTL_W8 (Cfg9346, ~EE_CS); |
1191 | eeprom_delay (); | 1170 | eeprom_delay (); |
1192 | 1171 | ||
1193 | return retval; | 1172 | return retval; |
@@ -1206,7 +1185,7 @@ static int __devinit read_eeprom (void *ioaddr, int location, int addr_len) | |||
1206 | #define MDIO_WRITE0 (MDIO_DIR) | 1185 | #define MDIO_WRITE0 (MDIO_DIR) |
1207 | #define MDIO_WRITE1 (MDIO_DIR | MDIO_DATA_OUT) | 1186 | #define MDIO_WRITE1 (MDIO_DIR | MDIO_DATA_OUT) |
1208 | 1187 | ||
1209 | #define mdio_delay(mdio_addr) readb(mdio_addr) | 1188 | #define mdio_delay() RTL_R8(Config4) |
1210 | 1189 | ||
1211 | 1190 | ||
1212 | static char mii_2_8139_map[8] = { | 1191 | static char mii_2_8139_map[8] = { |
@@ -1223,15 +1202,15 @@ static char mii_2_8139_map[8] = { | |||
1223 | 1202 | ||
1224 | #ifdef CONFIG_8139TOO_8129 | 1203 | #ifdef CONFIG_8139TOO_8129 |
1225 | /* Syncronize the MII management interface by shifting 32 one bits out. */ | 1204 | /* Syncronize the MII management interface by shifting 32 one bits out. */ |
1226 | static void mdio_sync (void *mdio_addr) | 1205 | static void mdio_sync (void __iomem *ioaddr) |
1227 | { | 1206 | { |
1228 | int i; | 1207 | int i; |
1229 | 1208 | ||
1230 | for (i = 32; i >= 0; i--) { | 1209 | for (i = 32; i >= 0; i--) { |
1231 | writeb (MDIO_WRITE1, mdio_addr); | 1210 | RTL_W8 (Config4, MDIO_WRITE1); |
1232 | mdio_delay (mdio_addr); | 1211 | mdio_delay (); |
1233 | writeb (MDIO_WRITE1 | MDIO_CLK, mdio_addr); | 1212 | RTL_W8 (Config4, MDIO_WRITE1 | MDIO_CLK); |
1234 | mdio_delay (mdio_addr); | 1213 | mdio_delay (); |
1235 | } | 1214 | } |
1236 | } | 1215 | } |
1237 | #endif | 1216 | #endif |
@@ -1241,35 +1220,36 @@ static int mdio_read (struct net_device *dev, int phy_id, int location) | |||
1241 | struct rtl8139_private *tp = netdev_priv(dev); | 1220 | struct rtl8139_private *tp = netdev_priv(dev); |
1242 | int retval = 0; | 1221 | int retval = 0; |
1243 | #ifdef CONFIG_8139TOO_8129 | 1222 | #ifdef CONFIG_8139TOO_8129 |
1244 | void *mdio_addr = tp->mmio_addr + Config4; | 1223 | void __iomem *ioaddr = tp->mmio_addr; |
1245 | int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location; | 1224 | int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location; |
1246 | int i; | 1225 | int i; |
1247 | #endif | 1226 | #endif |
1248 | 1227 | ||
1249 | if (phy_id > 31) { /* Really a 8139. Use internal registers. */ | 1228 | if (phy_id > 31) { /* Really a 8139. Use internal registers. */ |
1229 | void __iomem *ioaddr = tp->mmio_addr; | ||
1250 | return location < 8 && mii_2_8139_map[location] ? | 1230 | return location < 8 && mii_2_8139_map[location] ? |
1251 | readw (tp->mmio_addr + mii_2_8139_map[location]) : 0; | 1231 | RTL_R16 (mii_2_8139_map[location]) : 0; |
1252 | } | 1232 | } |
1253 | 1233 | ||
1254 | #ifdef CONFIG_8139TOO_8129 | 1234 | #ifdef CONFIG_8139TOO_8129 |
1255 | mdio_sync (mdio_addr); | 1235 | mdio_sync (ioaddr); |
1256 | /* Shift the read command bits out. */ | 1236 | /* Shift the read command bits out. */ |
1257 | for (i = 15; i >= 0; i--) { | 1237 | for (i = 15; i >= 0; i--) { |
1258 | int dataval = (mii_cmd & (1 << i)) ? MDIO_DATA_OUT : 0; | 1238 | int dataval = (mii_cmd & (1 << i)) ? MDIO_DATA_OUT : 0; |
1259 | 1239 | ||
1260 | writeb (MDIO_DIR | dataval, mdio_addr); | 1240 | RTL_W8 (Config4, MDIO_DIR | dataval); |
1261 | mdio_delay (mdio_addr); | 1241 | mdio_delay (); |
1262 | writeb (MDIO_DIR | dataval | MDIO_CLK, mdio_addr); | 1242 | RTL_W8 (Config4, MDIO_DIR | dataval | MDIO_CLK); |
1263 | mdio_delay (mdio_addr); | 1243 | mdio_delay (); |
1264 | } | 1244 | } |
1265 | 1245 | ||
1266 | /* Read the two transition, 16 data, and wire-idle bits. */ | 1246 | /* Read the two transition, 16 data, and wire-idle bits. */ |
1267 | for (i = 19; i > 0; i--) { | 1247 | for (i = 19; i > 0; i--) { |
1268 | writeb (0, mdio_addr); | 1248 | RTL_W8 (Config4, 0); |
1269 | mdio_delay (mdio_addr); | 1249 | mdio_delay (); |
1270 | retval = (retval << 1) | ((readb (mdio_addr) & MDIO_DATA_IN) ? 1 : 0); | 1250 | retval = (retval << 1) | ((RTL_R8 (Config4) & MDIO_DATA_IN) ? 1 : 0); |
1271 | writeb (MDIO_CLK, mdio_addr); | 1251 | RTL_W8 (Config4, MDIO_CLK); |
1272 | mdio_delay (mdio_addr); | 1252 | mdio_delay (); |
1273 | } | 1253 | } |
1274 | #endif | 1254 | #endif |
1275 | 1255 | ||
@@ -1282,13 +1262,13 @@ static void mdio_write (struct net_device *dev, int phy_id, int location, | |||
1282 | { | 1262 | { |
1283 | struct rtl8139_private *tp = netdev_priv(dev); | 1263 | struct rtl8139_private *tp = netdev_priv(dev); |
1284 | #ifdef CONFIG_8139TOO_8129 | 1264 | #ifdef CONFIG_8139TOO_8129 |
1285 | void *mdio_addr = tp->mmio_addr + Config4; | 1265 | void __iomem *ioaddr = tp->mmio_addr; |
1286 | int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location << 18) | value; | 1266 | int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location << 18) | value; |
1287 | int i; | 1267 | int i; |
1288 | #endif | 1268 | #endif |
1289 | 1269 | ||
1290 | if (phy_id > 31) { /* Really a 8139. Use internal registers. */ | 1270 | if (phy_id > 31) { /* Really a 8139. Use internal registers. */ |
1291 | void *ioaddr = tp->mmio_addr; | 1271 | void __iomem *ioaddr = tp->mmio_addr; |
1292 | if (location == 0) { | 1272 | if (location == 0) { |
1293 | RTL_W8 (Cfg9346, Cfg9346_Unlock); | 1273 | RTL_W8 (Cfg9346, Cfg9346_Unlock); |
1294 | RTL_W16 (BasicModeCtrl, value); | 1274 | RTL_W16 (BasicModeCtrl, value); |
@@ -1299,23 +1279,23 @@ static void mdio_write (struct net_device *dev, int phy_id, int location, | |||
1299 | } | 1279 | } |
1300 | 1280 | ||
1301 | #ifdef CONFIG_8139TOO_8129 | 1281 | #ifdef CONFIG_8139TOO_8129 |
1302 | mdio_sync (mdio_addr); | 1282 | mdio_sync (ioaddr); |
1303 | 1283 | ||
1304 | /* Shift the command bits out. */ | 1284 | /* Shift the command bits out. */ |
1305 | for (i = 31; i >= 0; i--) { | 1285 | for (i = 31; i >= 0; i--) { |
1306 | int dataval = | 1286 | int dataval = |
1307 | (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0; | 1287 | (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0; |
1308 | writeb (dataval, mdio_addr); | 1288 | RTL_W8 (Config4, dataval); |
1309 | mdio_delay (mdio_addr); | 1289 | mdio_delay (); |
1310 | writeb (dataval | MDIO_CLK, mdio_addr); | 1290 | RTL_W8 (Config4, dataval | MDIO_CLK); |
1311 | mdio_delay (mdio_addr); | 1291 | mdio_delay (); |
1312 | } | 1292 | } |
1313 | /* Clear out extra bits. */ | 1293 | /* Clear out extra bits. */ |
1314 | for (i = 2; i > 0; i--) { | 1294 | for (i = 2; i > 0; i--) { |
1315 | writeb (0, mdio_addr); | 1295 | RTL_W8 (Config4, 0); |
1316 | mdio_delay (mdio_addr); | 1296 | mdio_delay (); |
1317 | writeb (MDIO_CLK, mdio_addr); | 1297 | RTL_W8 (Config4, MDIO_CLK); |
1318 | mdio_delay (mdio_addr); | 1298 | mdio_delay (); |
1319 | } | 1299 | } |
1320 | #endif | 1300 | #endif |
1321 | } | 1301 | } |
@@ -1325,7 +1305,7 @@ static int rtl8139_open (struct net_device *dev) | |||
1325 | { | 1305 | { |
1326 | struct rtl8139_private *tp = netdev_priv(dev); | 1306 | struct rtl8139_private *tp = netdev_priv(dev); |
1327 | int retval; | 1307 | int retval; |
1328 | void *ioaddr = tp->mmio_addr; | 1308 | void __iomem *ioaddr = tp->mmio_addr; |
1329 | 1309 | ||
1330 | retval = request_irq (dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev); | 1310 | retval = request_irq (dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev); |
1331 | if (retval) | 1311 | if (retval) |
@@ -1382,7 +1362,7 @@ static void rtl_check_media (struct net_device *dev, unsigned int init_media) | |||
1382 | static void rtl8139_hw_start (struct net_device *dev) | 1362 | static void rtl8139_hw_start (struct net_device *dev) |
1383 | { | 1363 | { |
1384 | struct rtl8139_private *tp = netdev_priv(dev); | 1364 | struct rtl8139_private *tp = netdev_priv(dev); |
1385 | void *ioaddr = tp->mmio_addr; | 1365 | void __iomem *ioaddr = tp->mmio_addr; |
1386 | u32 i; | 1366 | u32 i; |
1387 | u8 tmp; | 1367 | u8 tmp; |
1388 | 1368 | ||
@@ -1484,7 +1464,7 @@ static void rtl8139_tune_twister (struct net_device *dev, | |||
1484 | struct rtl8139_private *tp) | 1464 | struct rtl8139_private *tp) |
1485 | { | 1465 | { |
1486 | int linkcase; | 1466 | int linkcase; |
1487 | void *ioaddr = tp->mmio_addr; | 1467 | void __iomem *ioaddr = tp->mmio_addr; |
1488 | 1468 | ||
1489 | /* This is a complicated state machine to configure the "twister" for | 1469 | /* This is a complicated state machine to configure the "twister" for |
1490 | impedance/echos based on the cable length. | 1470 | impedance/echos based on the cable length. |
@@ -1568,7 +1548,7 @@ static void rtl8139_tune_twister (struct net_device *dev, | |||
1568 | 1548 | ||
1569 | static inline void rtl8139_thread_iter (struct net_device *dev, | 1549 | static inline void rtl8139_thread_iter (struct net_device *dev, |
1570 | struct rtl8139_private *tp, | 1550 | struct rtl8139_private *tp, |
1571 | void *ioaddr) | 1551 | void __iomem *ioaddr) |
1572 | { | 1552 | { |
1573 | int mii_lpa; | 1553 | int mii_lpa; |
1574 | 1554 | ||
@@ -1676,7 +1656,7 @@ static inline void rtl8139_tx_clear (struct rtl8139_private *tp) | |||
1676 | static void rtl8139_tx_timeout (struct net_device *dev) | 1656 | static void rtl8139_tx_timeout (struct net_device *dev) |
1677 | { | 1657 | { |
1678 | struct rtl8139_private *tp = netdev_priv(dev); | 1658 | struct rtl8139_private *tp = netdev_priv(dev); |
1679 | void *ioaddr = tp->mmio_addr; | 1659 | void __iomem *ioaddr = tp->mmio_addr; |
1680 | int i; | 1660 | int i; |
1681 | u8 tmp8; | 1661 | u8 tmp8; |
1682 | unsigned long flags; | 1662 | unsigned long flags; |
@@ -1721,7 +1701,7 @@ static void rtl8139_tx_timeout (struct net_device *dev) | |||
1721 | static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev) | 1701 | static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev) |
1722 | { | 1702 | { |
1723 | struct rtl8139_private *tp = netdev_priv(dev); | 1703 | struct rtl8139_private *tp = netdev_priv(dev); |
1724 | void *ioaddr = tp->mmio_addr; | 1704 | void __iomem *ioaddr = tp->mmio_addr; |
1725 | unsigned int entry; | 1705 | unsigned int entry; |
1726 | unsigned int len = skb->len; | 1706 | unsigned int len = skb->len; |
1727 | 1707 | ||
@@ -1763,7 +1743,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev) | |||
1763 | 1743 | ||
1764 | static void rtl8139_tx_interrupt (struct net_device *dev, | 1744 | static void rtl8139_tx_interrupt (struct net_device *dev, |
1765 | struct rtl8139_private *tp, | 1745 | struct rtl8139_private *tp, |
1766 | void *ioaddr) | 1746 | void __iomem *ioaddr) |
1767 | { | 1747 | { |
1768 | unsigned long dirty_tx, tx_left; | 1748 | unsigned long dirty_tx, tx_left; |
1769 | 1749 | ||
@@ -1833,7 +1813,7 @@ static void rtl8139_tx_interrupt (struct net_device *dev, | |||
1833 | 1813 | ||
1834 | /* TODO: clean this up! Rx reset need not be this intensive */ | 1814 | /* TODO: clean this up! Rx reset need not be this intensive */ |
1835 | static void rtl8139_rx_err (u32 rx_status, struct net_device *dev, | 1815 | static void rtl8139_rx_err (u32 rx_status, struct net_device *dev, |
1836 | struct rtl8139_private *tp, void *ioaddr) | 1816 | struct rtl8139_private *tp, void __iomem *ioaddr) |
1837 | { | 1817 | { |
1838 | u8 tmp8; | 1818 | u8 tmp8; |
1839 | #ifdef CONFIG_8139_OLD_RX_RESET | 1819 | #ifdef CONFIG_8139_OLD_RX_RESET |
@@ -1930,7 +1910,7 @@ static __inline__ void wrap_copy(struct sk_buff *skb, const unsigned char *ring, | |||
1930 | 1910 | ||
1931 | static void rtl8139_isr_ack(struct rtl8139_private *tp) | 1911 | static void rtl8139_isr_ack(struct rtl8139_private *tp) |
1932 | { | 1912 | { |
1933 | void *ioaddr = tp->mmio_addr; | 1913 | void __iomem *ioaddr = tp->mmio_addr; |
1934 | u16 status; | 1914 | u16 status; |
1935 | 1915 | ||
1936 | status = RTL_R16 (IntrStatus) & RxAckBits; | 1916 | status = RTL_R16 (IntrStatus) & RxAckBits; |
@@ -1949,7 +1929,7 @@ static void rtl8139_isr_ack(struct rtl8139_private *tp) | |||
1949 | static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp, | 1929 | static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp, |
1950 | int budget) | 1930 | int budget) |
1951 | { | 1931 | { |
1952 | void *ioaddr = tp->mmio_addr; | 1932 | void __iomem *ioaddr = tp->mmio_addr; |
1953 | int received = 0; | 1933 | int received = 0; |
1954 | unsigned char *rx_ring = tp->rx_ring; | 1934 | unsigned char *rx_ring = tp->rx_ring; |
1955 | unsigned int cur_rx = tp->cur_rx; | 1935 | unsigned int cur_rx = tp->cur_rx; |
@@ -2087,7 +2067,7 @@ out: | |||
2087 | 2067 | ||
2088 | static void rtl8139_weird_interrupt (struct net_device *dev, | 2068 | static void rtl8139_weird_interrupt (struct net_device *dev, |
2089 | struct rtl8139_private *tp, | 2069 | struct rtl8139_private *tp, |
2090 | void *ioaddr, | 2070 | void __iomem *ioaddr, |
2091 | int status, int link_changed) | 2071 | int status, int link_changed) |
2092 | { | 2072 | { |
2093 | DPRINTK ("%s: Abnormal interrupt, status %8.8x.\n", | 2073 | DPRINTK ("%s: Abnormal interrupt, status %8.8x.\n", |
@@ -2127,7 +2107,7 @@ static void rtl8139_weird_interrupt (struct net_device *dev, | |||
2127 | static int rtl8139_poll(struct net_device *dev, int *budget) | 2107 | static int rtl8139_poll(struct net_device *dev, int *budget) |
2128 | { | 2108 | { |
2129 | struct rtl8139_private *tp = netdev_priv(dev); | 2109 | struct rtl8139_private *tp = netdev_priv(dev); |
2130 | void *ioaddr = tp->mmio_addr; | 2110 | void __iomem *ioaddr = tp->mmio_addr; |
2131 | int orig_budget = min(*budget, dev->quota); | 2111 | int orig_budget = min(*budget, dev->quota); |
2132 | int done = 1; | 2112 | int done = 1; |
2133 | 2113 | ||
@@ -2165,7 +2145,7 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance, | |||
2165 | { | 2145 | { |
2166 | struct net_device *dev = (struct net_device *) dev_instance; | 2146 | struct net_device *dev = (struct net_device *) dev_instance; |
2167 | struct rtl8139_private *tp = netdev_priv(dev); | 2147 | struct rtl8139_private *tp = netdev_priv(dev); |
2168 | void *ioaddr = tp->mmio_addr; | 2148 | void __iomem *ioaddr = tp->mmio_addr; |
2169 | u16 status, ackstat; | 2149 | u16 status, ackstat; |
2170 | int link_changed = 0; /* avoid bogus "uninit" warning */ | 2150 | int link_changed = 0; /* avoid bogus "uninit" warning */ |
2171 | int handled = 0; | 2151 | int handled = 0; |
@@ -2241,7 +2221,7 @@ static void rtl8139_poll_controller(struct net_device *dev) | |||
2241 | static int rtl8139_close (struct net_device *dev) | 2221 | static int rtl8139_close (struct net_device *dev) |
2242 | { | 2222 | { |
2243 | struct rtl8139_private *tp = netdev_priv(dev); | 2223 | struct rtl8139_private *tp = netdev_priv(dev); |
2244 | void *ioaddr = tp->mmio_addr; | 2224 | void __iomem *ioaddr = tp->mmio_addr; |
2245 | int ret = 0; | 2225 | int ret = 0; |
2246 | unsigned long flags; | 2226 | unsigned long flags; |
2247 | 2227 | ||
@@ -2304,7 +2284,7 @@ static int rtl8139_close (struct net_device *dev) | |||
2304 | static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | 2284 | static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) |
2305 | { | 2285 | { |
2306 | struct rtl8139_private *np = netdev_priv(dev); | 2286 | struct rtl8139_private *np = netdev_priv(dev); |
2307 | void *ioaddr = np->mmio_addr; | 2287 | void __iomem *ioaddr = np->mmio_addr; |
2308 | 2288 | ||
2309 | spin_lock_irq(&np->lock); | 2289 | spin_lock_irq(&np->lock); |
2310 | if (rtl_chip_info[np->chipset].flags & HasLWake) { | 2290 | if (rtl_chip_info[np->chipset].flags & HasLWake) { |
@@ -2338,7 +2318,7 @@ static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
2338 | static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | 2318 | static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) |
2339 | { | 2319 | { |
2340 | struct rtl8139_private *np = netdev_priv(dev); | 2320 | struct rtl8139_private *np = netdev_priv(dev); |
2341 | void *ioaddr = np->mmio_addr; | 2321 | void __iomem *ioaddr = np->mmio_addr; |
2342 | u32 support; | 2322 | u32 support; |
2343 | u8 cfg3, cfg5; | 2323 | u8 cfg3, cfg5; |
2344 | 2324 | ||
@@ -2506,7 +2486,7 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
2506 | static struct net_device_stats *rtl8139_get_stats (struct net_device *dev) | 2486 | static struct net_device_stats *rtl8139_get_stats (struct net_device *dev) |
2507 | { | 2487 | { |
2508 | struct rtl8139_private *tp = netdev_priv(dev); | 2488 | struct rtl8139_private *tp = netdev_priv(dev); |
2509 | void *ioaddr = tp->mmio_addr; | 2489 | void __iomem *ioaddr = tp->mmio_addr; |
2510 | unsigned long flags; | 2490 | unsigned long flags; |
2511 | 2491 | ||
2512 | if (netif_running(dev)) { | 2492 | if (netif_running(dev)) { |
@@ -2525,7 +2505,7 @@ static struct net_device_stats *rtl8139_get_stats (struct net_device *dev) | |||
2525 | static void __set_rx_mode (struct net_device *dev) | 2505 | static void __set_rx_mode (struct net_device *dev) |
2526 | { | 2506 | { |
2527 | struct rtl8139_private *tp = netdev_priv(dev); | 2507 | struct rtl8139_private *tp = netdev_priv(dev); |
2528 | void *ioaddr = tp->mmio_addr; | 2508 | void __iomem *ioaddr = tp->mmio_addr; |
2529 | u32 mc_filter[2]; /* Multicast hash filter */ | 2509 | u32 mc_filter[2]; /* Multicast hash filter */ |
2530 | int i, rx_mode; | 2510 | int i, rx_mode; |
2531 | u32 tmp; | 2511 | u32 tmp; |
@@ -2586,7 +2566,7 @@ static int rtl8139_suspend (struct pci_dev *pdev, pm_message_t state) | |||
2586 | { | 2566 | { |
2587 | struct net_device *dev = pci_get_drvdata (pdev); | 2567 | struct net_device *dev = pci_get_drvdata (pdev); |
2588 | struct rtl8139_private *tp = netdev_priv(dev); | 2568 | struct rtl8139_private *tp = netdev_priv(dev); |
2589 | void *ioaddr = tp->mmio_addr; | 2569 | void __iomem *ioaddr = tp->mmio_addr; |
2590 | unsigned long flags; | 2570 | unsigned long flags; |
2591 | 2571 | ||
2592 | pci_save_state (pdev); | 2572 | pci_save_state (pdev); |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index f08e01b2fd19..cebee528f3c7 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -824,6 +824,18 @@ config SMC9194 | |||
824 | <file:Documentation/networking/net-modules.txt>. The module | 824 | <file:Documentation/networking/net-modules.txt>. The module |
825 | will be called smc9194. | 825 | will be called smc9194. |
826 | 826 | ||
827 | config DM9000 | ||
828 | tristate "DM9000 support" | ||
829 | depends on ARM && NET_ETHERNET | ||
830 | select CRC32 | ||
831 | select MII | ||
832 | ---help--- | ||
833 | Support for DM9000 chipset. | ||
834 | |||
835 | To compile this driver as a module, choose M here and read | ||
836 | <file:Documentation/networking/net-modules.txt>. The module will be | ||
837 | called dm9000. | ||
838 | |||
827 | config NET_VENDOR_RACAL | 839 | config NET_VENDOR_RACAL |
828 | bool "Racal-Interlan (Micom) NI cards" | 840 | bool "Racal-Interlan (Micom) NI cards" |
829 | depends on NET_ETHERNET && ISA | 841 | depends on NET_ETHERNET && ISA |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 30c7567001fe..0d97be0c77d4 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
@@ -180,6 +180,7 @@ obj-$(CONFIG_AMD8111_ETH) += amd8111e.o | |||
180 | obj-$(CONFIG_IBMVETH) += ibmveth.o | 180 | obj-$(CONFIG_IBMVETH) += ibmveth.o |
181 | obj-$(CONFIG_S2IO) += s2io.o | 181 | obj-$(CONFIG_S2IO) += s2io.o |
182 | obj-$(CONFIG_SMC91X) += smc91x.o | 182 | obj-$(CONFIG_SMC91X) += smc91x.o |
183 | obj-$(CONFIG_DM9000) += dm9000.o | ||
183 | obj-$(CONFIG_FEC_8XX) += fec_8xx/ | 184 | obj-$(CONFIG_FEC_8XX) += fec_8xx/ |
184 | 185 | ||
185 | obj-$(CONFIG_ARM) += arm/ | 186 | obj-$(CONFIG_ARM) += arm/ |
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c new file mode 100644 index 000000000000..f4ba0ffb8637 --- /dev/null +++ b/drivers/net/dm9000.c | |||
@@ -0,0 +1,1219 @@ | |||
1 | /* | ||
2 | * dm9000.c: Version 1.2 03/18/2003 | ||
3 | * | ||
4 | * A Davicom DM9000 ISA NIC fast Ethernet driver for Linux. | ||
5 | * Copyright (C) 1997 Sten Wang | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version 2 | ||
10 | * of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved. | ||
18 | * | ||
19 | * V0.11 06/20/2001 REG_0A bit3=1, default enable BP with DA match | ||
20 | * 06/22/2001 Support DM9801 progrmming | ||
21 | * E3: R25 = ((R24 + NF) & 0x00ff) | 0xf000 | ||
22 | * E4: R25 = ((R24 + NF) & 0x00ff) | 0xc200 | ||
23 | * R17 = (R17 & 0xfff0) | NF + 3 | ||
24 | * E5: R25 = ((R24 + NF - 3) & 0x00ff) | 0xc200 | ||
25 | * R17 = (R17 & 0xfff0) | NF | ||
26 | * | ||
27 | * v1.00 modify by simon 2001.9.5 | ||
28 | * change for kernel 2.4.x | ||
29 | * | ||
30 | * v1.1 11/09/2001 fix force mode bug | ||
31 | * | ||
32 | * v1.2 03/18/2003 Weilun Huang <weilun_huang@davicom.com.tw>: | ||
33 | * Fixed phy reset. | ||
34 | * Added tx/rx 32 bit mode. | ||
35 | * Cleaned up for kernel merge. | ||
36 | * | ||
37 | * 03/03/2004 Sascha Hauer <s.hauer@pengutronix.de> | ||
38 | * Port to 2.6 kernel | ||
39 | * | ||
40 | * 24-Sep-2004 Ben Dooks <ben@simtec.co.uk> | ||
41 | * Cleanup of code to remove ifdefs | ||
42 | * Allowed platform device data to influence access width | ||
43 | * Reformatting areas of code | ||
44 | * | ||
45 | * 17-Mar-2005 Sascha Hauer <s.hauer@pengutronix.de> | ||
46 | * * removed 2.4 style module parameters | ||
47 | * * removed removed unused stat counter and fixed | ||
48 | * net_device_stats | ||
49 | * * introduced tx_timeout function | ||
50 | * * reworked locking | ||
51 | */ | ||
52 | |||
53 | #include <linux/module.h> | ||
54 | #include <linux/ioport.h> | ||
55 | #include <linux/netdevice.h> | ||
56 | #include <linux/etherdevice.h> | ||
57 | #include <linux/init.h> | ||
58 | #include <linux/skbuff.h> | ||
59 | #include <linux/version.h> | ||
60 | #include <linux/spinlock.h> | ||
61 | #include <linux/crc32.h> | ||
62 | #include <linux/mii.h> | ||
63 | #include <linux/dm9000.h> | ||
64 | #include <linux/delay.h> | ||
65 | |||
66 | #include <asm/delay.h> | ||
67 | #include <asm/irq.h> | ||
68 | #include <asm/io.h> | ||
69 | |||
70 | #include "dm9000.h" | ||
71 | |||
72 | /* Board/System/Debug information/definition ---------------- */ | ||
73 | |||
74 | #define DM9000_PHY 0x40 /* PHY address 0x01 */ | ||
75 | |||
76 | #define TRUE 1 | ||
77 | #define FALSE 0 | ||
78 | |||
79 | #define CARDNAME "dm9000" | ||
80 | #define PFX CARDNAME ": " | ||
81 | |||
82 | #define DM9000_TIMER_WUT jiffies+(HZ*2) /* timer wakeup time : 2 second */ | ||
83 | |||
84 | #define DM9000_DEBUG 0 | ||
85 | |||
86 | #if DM9000_DEBUG > 2 | ||
87 | #define PRINTK3(args...) printk(CARDNAME ": " args) | ||
88 | #else | ||
89 | #define PRINTK3(args...) do { } while(0) | ||
90 | #endif | ||
91 | |||
92 | #if DM9000_DEBUG > 1 | ||
93 | #define PRINTK2(args...) printk(CARDNAME ": " args) | ||
94 | #else | ||
95 | #define PRINTK2(args...) do { } while(0) | ||
96 | #endif | ||
97 | |||
98 | #if DM9000_DEBUG > 0 | ||
99 | #define PRINTK1(args...) printk(CARDNAME ": " args) | ||
100 | #define PRINTK(args...) printk(CARDNAME ": " args) | ||
101 | #else | ||
102 | #define PRINTK1(args...) do { } while(0) | ||
103 | #define PRINTK(args...) printk(KERN_DEBUG args) | ||
104 | #endif | ||
105 | |||
106 | /* | ||
107 | * Transmit timeout, default 5 seconds. | ||
108 | */ | ||
109 | static int watchdog = 5000; | ||
110 | module_param(watchdog, int, 0400); | ||
111 | MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds"); | ||
112 | |||
113 | /* Structure/enum declaration ------------------------------- */ | ||
114 | typedef struct board_info { | ||
115 | |||
116 | void __iomem *io_addr; /* Register I/O base address */ | ||
117 | void __iomem *io_data; /* Data I/O address */ | ||
118 | u16 irq; /* IRQ */ | ||
119 | |||
120 | u16 tx_pkt_cnt; | ||
121 | u16 queue_pkt_len; | ||
122 | u16 queue_start_addr; | ||
123 | u16 dbug_cnt; | ||
124 | u8 io_mode; /* 0:word, 2:byte */ | ||
125 | u8 phy_addr; | ||
126 | |||
127 | void (*inblk)(void __iomem *port, void *data, int length); | ||
128 | void (*outblk)(void __iomem *port, void *data, int length); | ||
129 | void (*dumpblk)(void __iomem *port, int length); | ||
130 | |||
131 | struct resource *addr_res; /* resources found */ | ||
132 | struct resource *data_res; | ||
133 | struct resource *addr_req; /* resources requested */ | ||
134 | struct resource *data_req; | ||
135 | struct resource *irq_res; | ||
136 | |||
137 | struct timer_list timer; | ||
138 | struct net_device_stats stats; | ||
139 | unsigned char srom[128]; | ||
140 | spinlock_t lock; | ||
141 | |||
142 | struct mii_if_info mii; | ||
143 | u32 msg_enable; | ||
144 | } board_info_t; | ||
145 | |||
146 | /* function declaration ------------------------------------- */ | ||
147 | static int dm9000_probe(struct device *); | ||
148 | static int dm9000_open(struct net_device *); | ||
149 | static int dm9000_start_xmit(struct sk_buff *, struct net_device *); | ||
150 | static int dm9000_stop(struct net_device *); | ||
151 | static int dm9000_do_ioctl(struct net_device *, struct ifreq *, int); | ||
152 | |||
153 | |||
154 | static void dm9000_timer(unsigned long); | ||
155 | static void dm9000_init_dm9000(struct net_device *); | ||
156 | |||
157 | static struct net_device_stats *dm9000_get_stats(struct net_device *); | ||
158 | |||
159 | static irqreturn_t dm9000_interrupt(int, void *, struct pt_regs *); | ||
160 | |||
161 | static int dm9000_phy_read(struct net_device *dev, int phyaddr_unsused, int reg); | ||
162 | static void dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, | ||
163 | int value); | ||
164 | static u16 read_srom_word(board_info_t *, int); | ||
165 | static void dm9000_rx(struct net_device *); | ||
166 | static void dm9000_hash_table(struct net_device *); | ||
167 | |||
168 | //#define DM9000_PROGRAM_EEPROM | ||
169 | #ifdef DM9000_PROGRAM_EEPROM | ||
170 | static void program_eeprom(board_info_t * db); | ||
171 | #endif | ||
172 | /* DM9000 network board routine ---------------------------- */ | ||
173 | |||
174 | static void | ||
175 | dm9000_reset(board_info_t * db) | ||
176 | { | ||
177 | PRINTK1("dm9000x: resetting\n"); | ||
178 | /* RESET device */ | ||
179 | writeb(DM9000_NCR, db->io_addr); | ||
180 | udelay(200); | ||
181 | writeb(NCR_RST, db->io_data); | ||
182 | udelay(200); | ||
183 | } | ||
184 | |||
185 | /* | ||
186 | * Read a byte from I/O port | ||
187 | */ | ||
188 | static u8 | ||
189 | ior(board_info_t * db, int reg) | ||
190 | { | ||
191 | writeb(reg, db->io_addr); | ||
192 | return readb(db->io_data); | ||
193 | } | ||
194 | |||
195 | /* | ||
196 | * Write a byte to I/O port | ||
197 | */ | ||
198 | |||
199 | static void | ||
200 | iow(board_info_t * db, int reg, int value) | ||
201 | { | ||
202 | writeb(reg, db->io_addr); | ||
203 | writeb(value, db->io_data); | ||
204 | } | ||
205 | |||
206 | /* routines for sending block to chip */ | ||
207 | |||
208 | static void dm9000_outblk_8bit(void __iomem *reg, void *data, int count) | ||
209 | { | ||
210 | writesb(reg, data, count); | ||
211 | } | ||
212 | |||
213 | static void dm9000_outblk_16bit(void __iomem *reg, void *data, int count) | ||
214 | { | ||
215 | writesw(reg, data, (count+1) >> 1); | ||
216 | } | ||
217 | |||
218 | static void dm9000_outblk_32bit(void __iomem *reg, void *data, int count) | ||
219 | { | ||
220 | writesl(reg, data, (count+3) >> 2); | ||
221 | } | ||
222 | |||
223 | /* input block from chip to memory */ | ||
224 | |||
225 | static void dm9000_inblk_8bit(void __iomem *reg, void *data, int count) | ||
226 | { | ||
227 | readsb(reg, data, count+1); | ||
228 | } | ||
229 | |||
230 | |||
231 | static void dm9000_inblk_16bit(void __iomem *reg, void *data, int count) | ||
232 | { | ||
233 | readsw(reg, data, (count+1) >> 1); | ||
234 | } | ||
235 | |||
236 | static void dm9000_inblk_32bit(void __iomem *reg, void *data, int count) | ||
237 | { | ||
238 | readsl(reg, data, (count+3) >> 2); | ||
239 | } | ||
240 | |||
241 | /* dump block from chip to null */ | ||
242 | |||
243 | static void dm9000_dumpblk_8bit(void __iomem *reg, int count) | ||
244 | { | ||
245 | int i; | ||
246 | int tmp; | ||
247 | |||
248 | for (i = 0; i < count; i++) | ||
249 | tmp = readb(reg); | ||
250 | } | ||
251 | |||
252 | static void dm9000_dumpblk_16bit(void __iomem *reg, int count) | ||
253 | { | ||
254 | int i; | ||
255 | int tmp; | ||
256 | |||
257 | count = (count + 1) >> 1; | ||
258 | |||
259 | for (i = 0; i < count; i++) | ||
260 | tmp = readw(reg); | ||
261 | } | ||
262 | |||
263 | static void dm9000_dumpblk_32bit(void __iomem *reg, int count) | ||
264 | { | ||
265 | int i; | ||
266 | int tmp; | ||
267 | |||
268 | count = (count + 3) >> 2; | ||
269 | |||
270 | for (i = 0; i < count; i++) | ||
271 | tmp = readl(reg); | ||
272 | } | ||
273 | |||
274 | /* dm9000_set_io | ||
275 | * | ||
276 | * select the specified set of io routines to use with the | ||
277 | * device | ||
278 | */ | ||
279 | |||
280 | static void dm9000_set_io(struct board_info *db, int byte_width) | ||
281 | { | ||
282 | /* use the size of the data resource to work out what IO | ||
283 | * routines we want to use | ||
284 | */ | ||
285 | |||
286 | switch (byte_width) { | ||
287 | case 1: | ||
288 | db->dumpblk = dm9000_dumpblk_8bit; | ||
289 | db->outblk = dm9000_outblk_8bit; | ||
290 | db->inblk = dm9000_inblk_8bit; | ||
291 | break; | ||
292 | |||
293 | case 2: | ||
294 | db->dumpblk = dm9000_dumpblk_16bit; | ||
295 | db->outblk = dm9000_outblk_16bit; | ||
296 | db->inblk = dm9000_inblk_16bit; | ||
297 | break; | ||
298 | |||
299 | case 3: | ||
300 | printk(KERN_ERR PFX ": 3 byte IO, falling back to 16bit\n"); | ||
301 | db->dumpblk = dm9000_dumpblk_16bit; | ||
302 | db->outblk = dm9000_outblk_16bit; | ||
303 | db->inblk = dm9000_inblk_16bit; | ||
304 | break; | ||
305 | |||
306 | case 4: | ||
307 | default: | ||
308 | db->dumpblk = dm9000_dumpblk_32bit; | ||
309 | db->outblk = dm9000_outblk_32bit; | ||
310 | db->inblk = dm9000_inblk_32bit; | ||
311 | break; | ||
312 | } | ||
313 | } | ||
314 | |||
315 | |||
316 | /* Our watchdog timed out. Called by the networking layer */ | ||
317 | static void dm9000_timeout(struct net_device *dev) | ||
318 | { | ||
319 | board_info_t *db = (board_info_t *) dev->priv; | ||
320 | u8 reg_save; | ||
321 | unsigned long flags; | ||
322 | |||
323 | /* Save previous register address */ | ||
324 | reg_save = readb(db->io_addr); | ||
325 | spin_lock_irqsave(db->lock,flags); | ||
326 | |||
327 | netif_stop_queue(dev); | ||
328 | dm9000_reset(db); | ||
329 | dm9000_init_dm9000(dev); | ||
330 | /* We can accept TX packets again */ | ||
331 | dev->trans_start = jiffies; | ||
332 | netif_wake_queue(dev); | ||
333 | |||
334 | /* Restore previous register address */ | ||
335 | writeb(reg_save, db->io_addr); | ||
336 | spin_unlock_irqrestore(db->lock,flags); | ||
337 | } | ||
338 | |||
339 | |||
340 | /* dm9000_release_board | ||
341 | * | ||
342 | * release a board, and any mapped resources | ||
343 | */ | ||
344 | |||
345 | static void | ||
346 | dm9000_release_board(struct platform_device *pdev, struct board_info *db) | ||
347 | { | ||
348 | if (db->data_res == NULL) { | ||
349 | if (db->addr_res != NULL) | ||
350 | release_mem_region((unsigned long)db->io_addr, 4); | ||
351 | return; | ||
352 | } | ||
353 | |||
354 | /* unmap our resources */ | ||
355 | |||
356 | iounmap(db->io_addr); | ||
357 | iounmap(db->io_data); | ||
358 | |||
359 | /* release the resources */ | ||
360 | |||
361 | if (db->data_req != NULL) { | ||
362 | release_resource(db->data_req); | ||
363 | kfree(db->data_req); | ||
364 | } | ||
365 | |||
366 | if (db->addr_res != NULL) { | ||
367 | release_resource(db->data_req); | ||
368 | kfree(db->addr_req); | ||
369 | } | ||
370 | } | ||
371 | |||
372 | #define res_size(_r) (((_r)->end - (_r)->start) + 1) | ||
373 | |||
374 | /* | ||
375 | * Search DM9000 board, allocate space and register it | ||
376 | */ | ||
377 | static int | ||
378 | dm9000_probe(struct device *dev) | ||
379 | { | ||
380 | struct platform_device *pdev = to_platform_device(dev); | ||
381 | struct dm9000_plat_data *pdata = pdev->dev.platform_data; | ||
382 | struct board_info *db; /* Point a board information structure */ | ||
383 | struct net_device *ndev; | ||
384 | unsigned long base; | ||
385 | int ret = 0; | ||
386 | int iosize; | ||
387 | int i; | ||
388 | u32 id_val; | ||
389 | |||
390 | printk(KERN_INFO "%s Ethernet Driver\n", CARDNAME); | ||
391 | |||
392 | /* Init network device */ | ||
393 | ndev = alloc_etherdev(sizeof (struct board_info)); | ||
394 | if (!ndev) { | ||
395 | printk("%s: could not allocate device.\n", CARDNAME); | ||
396 | return -ENOMEM; | ||
397 | } | ||
398 | |||
399 | SET_MODULE_OWNER(ndev); | ||
400 | SET_NETDEV_DEV(ndev, dev); | ||
401 | |||
402 | PRINTK2("dm9000_probe()"); | ||
403 | |||
404 | /* setup board info structure */ | ||
405 | db = (struct board_info *) ndev->priv; | ||
406 | memset(db, 0, sizeof (*db)); | ||
407 | |||
408 | if (pdev->num_resources < 2) { | ||
409 | ret = -ENODEV; | ||
410 | goto out; | ||
411 | } | ||
412 | |||
413 | switch (pdev->num_resources) { | ||
414 | case 2: | ||
415 | base = pdev->resource[0].start; | ||
416 | |||
417 | if (!request_mem_region(base, 4, ndev->name)) { | ||
418 | ret = -EBUSY; | ||
419 | goto out; | ||
420 | } | ||
421 | |||
422 | ndev->base_addr = base; | ||
423 | ndev->irq = pdev->resource[1].start; | ||
424 | db->io_addr = (void *)base; | ||
425 | db->io_data = (void *)(base + 4); | ||
426 | |||
427 | break; | ||
428 | |||
429 | case 3: | ||
430 | db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
431 | db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
432 | db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
433 | |||
434 | if (db->addr_res == NULL || db->data_res == NULL) { | ||
435 | printk(KERN_ERR PFX "insufficient resources\n"); | ||
436 | ret = -ENOENT; | ||
437 | goto out; | ||
438 | } | ||
439 | |||
440 | i = res_size(db->addr_res); | ||
441 | db->addr_req = request_mem_region(db->addr_res->start, i, | ||
442 | pdev->name); | ||
443 | |||
444 | if (db->addr_req == NULL) { | ||
445 | printk(KERN_ERR PFX "cannot claim address reg area\n"); | ||
446 | ret = -EIO; | ||
447 | goto out; | ||
448 | } | ||
449 | |||
450 | db->io_addr = ioremap(db->addr_res->start, i); | ||
451 | |||
452 | if (db->io_addr == NULL) { | ||
453 | printk(KERN_ERR "failed to ioremap address reg\n"); | ||
454 | ret = -EINVAL; | ||
455 | goto out; | ||
456 | } | ||
457 | |||
458 | iosize = res_size(db->data_res); | ||
459 | db->data_req = request_mem_region(db->data_res->start, iosize, | ||
460 | pdev->name); | ||
461 | |||
462 | if (db->data_req == NULL) { | ||
463 | printk(KERN_ERR PFX "cannot claim data reg area\n"); | ||
464 | ret = -EIO; | ||
465 | goto out; | ||
466 | } | ||
467 | |||
468 | db->io_data = ioremap(db->data_res->start, iosize); | ||
469 | |||
470 | if (db->io_data == NULL) { | ||
471 | printk(KERN_ERR "failed to ioremap data reg\n"); | ||
472 | ret = -EINVAL; | ||
473 | goto out; | ||
474 | } | ||
475 | |||
476 | /* fill in parameters for net-dev structure */ | ||
477 | |||
478 | ndev->base_addr = (unsigned long)db->io_addr; | ||
479 | ndev->irq = db->irq_res->start; | ||
480 | |||
481 | /* ensure at least we have a default set of IO routines */ | ||
482 | dm9000_set_io(db, iosize); | ||
483 | |||
484 | } | ||
485 | |||
486 | /* check to see if anything is being over-ridden */ | ||
487 | if (pdata != NULL) { | ||
488 | /* check to see if the driver wants to over-ride the | ||
489 | * default IO width */ | ||
490 | |||
491 | if (pdata->flags & DM9000_PLATF_8BITONLY) | ||
492 | dm9000_set_io(db, 1); | ||
493 | |||
494 | if (pdata->flags & DM9000_PLATF_16BITONLY) | ||
495 | dm9000_set_io(db, 2); | ||
496 | |||
497 | if (pdata->flags & DM9000_PLATF_32BITONLY) | ||
498 | dm9000_set_io(db, 4); | ||
499 | |||
500 | /* check to see if there are any IO routine | ||
501 | * over-rides */ | ||
502 | |||
503 | if (pdata->inblk != NULL) | ||
504 | db->inblk = pdata->inblk; | ||
505 | |||
506 | if (pdata->outblk != NULL) | ||
507 | db->outblk = pdata->outblk; | ||
508 | |||
509 | if (pdata->dumpblk != NULL) | ||
510 | db->dumpblk = pdata->dumpblk; | ||
511 | } | ||
512 | |||
513 | dm9000_reset(db); | ||
514 | |||
515 | /* try two times, DM9000 sometimes gets the first read wrong */ | ||
516 | for (i = 0; i < 2; i++) { | ||
517 | id_val = ior(db, DM9000_VIDL); | ||
518 | id_val |= (u32)ior(db, DM9000_VIDH) << 8; | ||
519 | id_val |= (u32)ior(db, DM9000_PIDL) << 16; | ||
520 | id_val |= (u32)ior(db, DM9000_PIDH) << 24; | ||
521 | |||
522 | if (id_val == DM9000_ID) | ||
523 | break; | ||
524 | printk("%s: read wrong id 0x%08x\n", CARDNAME, id_val); | ||
525 | } | ||
526 | |||
527 | if (id_val != DM9000_ID) { | ||
528 | printk("%s: wrong id: 0x%08x\n", CARDNAME, id_val); | ||
529 | goto release; | ||
530 | } | ||
531 | |||
532 | /* from this point we assume that we have found a DM9000 */ | ||
533 | |||
534 | /* driver system function */ | ||
535 | ether_setup(ndev); | ||
536 | |||
537 | ndev->open = &dm9000_open; | ||
538 | ndev->hard_start_xmit = &dm9000_start_xmit; | ||
539 | ndev->tx_timeout = &dm9000_timeout; | ||
540 | ndev->watchdog_timeo = msecs_to_jiffies(watchdog); | ||
541 | ndev->stop = &dm9000_stop; | ||
542 | ndev->get_stats = &dm9000_get_stats; | ||
543 | ndev->set_multicast_list = &dm9000_hash_table; | ||
544 | ndev->do_ioctl = &dm9000_do_ioctl; | ||
545 | |||
546 | #ifdef DM9000_PROGRAM_EEPROM | ||
547 | program_eeprom(db); | ||
548 | #endif | ||
549 | db->msg_enable = NETIF_MSG_LINK; | ||
550 | db->mii.phy_id_mask = 0x1f; | ||
551 | db->mii.reg_num_mask = 0x1f; | ||
552 | db->mii.force_media = 0; | ||
553 | db->mii.full_duplex = 0; | ||
554 | db->mii.dev = ndev; | ||
555 | db->mii.mdio_read = dm9000_phy_read; | ||
556 | db->mii.mdio_write = dm9000_phy_write; | ||
557 | |||
558 | /* Read SROM content */ | ||
559 | for (i = 0; i < 64; i++) | ||
560 | ((u16 *) db->srom)[i] = read_srom_word(db, i); | ||
561 | |||
562 | /* Set Node Address */ | ||
563 | for (i = 0; i < 6; i++) | ||
564 | ndev->dev_addr[i] = db->srom[i]; | ||
565 | |||
566 | if (!is_valid_ether_addr(ndev->dev_addr)) | ||
567 | printk("%s: Invalid ethernet MAC address. Please " | ||
568 | "set using ifconfig\n", ndev->name); | ||
569 | |||
570 | dev_set_drvdata(dev, ndev); | ||
571 | ret = register_netdev(ndev); | ||
572 | |||
573 | if (ret == 0) { | ||
574 | printk("%s: dm9000 at %p,%p IRQ %d MAC: ", | ||
575 | ndev->name, db->io_addr, db->io_data, ndev->irq); | ||
576 | for (i = 0; i < 5; i++) | ||
577 | printk("%02x:", ndev->dev_addr[i]); | ||
578 | printk("%02x\n", ndev->dev_addr[5]); | ||
579 | } | ||
580 | return 0; | ||
581 | |||
582 | release: | ||
583 | out: | ||
584 | printk("%s: not found (%d).\n", CARDNAME, ret); | ||
585 | |||
586 | dm9000_release_board(pdev, db); | ||
587 | kfree(ndev); | ||
588 | |||
589 | return ret; | ||
590 | } | ||
591 | |||
592 | /* | ||
593 | * Open the interface. | ||
594 | * The interface is opened whenever "ifconfig" actives it. | ||
595 | */ | ||
596 | static int | ||
597 | dm9000_open(struct net_device *dev) | ||
598 | { | ||
599 | board_info_t *db = (board_info_t *) dev->priv; | ||
600 | |||
601 | PRINTK2("entering dm9000_open\n"); | ||
602 | |||
603 | if (request_irq(dev->irq, &dm9000_interrupt, SA_SHIRQ, dev->name, dev)) | ||
604 | return -EAGAIN; | ||
605 | |||
606 | /* Initialize DM9000 board */ | ||
607 | dm9000_reset(db); | ||
608 | dm9000_init_dm9000(dev); | ||
609 | |||
610 | /* Init driver variable */ | ||
611 | db->dbug_cnt = 0; | ||
612 | |||
613 | /* set and active a timer process */ | ||
614 | init_timer(&db->timer); | ||
615 | db->timer.expires = DM9000_TIMER_WUT * 2; | ||
616 | db->timer.data = (unsigned long) dev; | ||
617 | db->timer.function = &dm9000_timer; | ||
618 | add_timer(&db->timer); | ||
619 | |||
620 | mii_check_media(&db->mii, netif_msg_link(db), 1); | ||
621 | netif_start_queue(dev); | ||
622 | |||
623 | return 0; | ||
624 | } | ||
625 | |||
626 | /* | ||
627 | * Initilize dm9000 board | ||
628 | */ | ||
629 | static void | ||
630 | dm9000_init_dm9000(struct net_device *dev) | ||
631 | { | ||
632 | board_info_t *db = (board_info_t *) dev->priv; | ||
633 | |||
634 | PRINTK1("entering %s\n",__FUNCTION__); | ||
635 | |||
636 | /* I/O mode */ | ||
637 | db->io_mode = ior(db, DM9000_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */ | ||
638 | |||
639 | /* GPIO0 on pre-activate PHY */ | ||
640 | iow(db, DM9000_GPR, 0); /* REG_1F bit0 activate phyxcer */ | ||
641 | iow(db, DM9000_GPCR, GPCR_GEP_CNTL); /* Let GPIO0 output */ | ||
642 | iow(db, DM9000_GPR, 0); /* Enable PHY */ | ||
643 | |||
644 | /* Program operating register */ | ||
645 | iow(db, DM9000_TCR, 0); /* TX Polling clear */ | ||
646 | iow(db, DM9000_BPTR, 0x3f); /* Less 3Kb, 200us */ | ||
647 | iow(db, DM9000_FCR, 0xff); /* Flow Control */ | ||
648 | iow(db, DM9000_SMCR, 0); /* Special Mode */ | ||
649 | /* clear TX status */ | ||
650 | iow(db, DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END); | ||
651 | iow(db, DM9000_ISR, ISR_CLR_STATUS); /* Clear interrupt status */ | ||
652 | |||
653 | /* Set address filter table */ | ||
654 | dm9000_hash_table(dev); | ||
655 | |||
656 | /* Activate DM9000 */ | ||
657 | iow(db, DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN); | ||
658 | /* Enable TX/RX interrupt mask */ | ||
659 | iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM); | ||
660 | |||
661 | /* Init Driver variable */ | ||
662 | db->tx_pkt_cnt = 0; | ||
663 | db->queue_pkt_len = 0; | ||
664 | dev->trans_start = 0; | ||
665 | spin_lock_init(&db->lock); | ||
666 | } | ||
667 | |||
668 | /* | ||
669 | * Hardware start transmission. | ||
670 | * Send a packet to media from the upper layer. | ||
671 | */ | ||
672 | static int | ||
673 | dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
674 | { | ||
675 | board_info_t *db = (board_info_t *) dev->priv; | ||
676 | |||
677 | PRINTK3("dm9000_start_xmit\n"); | ||
678 | |||
679 | if (db->tx_pkt_cnt > 1) | ||
680 | return 1; | ||
681 | |||
682 | netif_stop_queue(dev); | ||
683 | |||
684 | /* Disable all interrupts */ | ||
685 | iow(db, DM9000_IMR, IMR_PAR); | ||
686 | |||
687 | /* Move data to DM9000 TX RAM */ | ||
688 | writeb(DM9000_MWCMD, db->io_addr); | ||
689 | |||
690 | (db->outblk)(db->io_data, skb->data, skb->len); | ||
691 | db->stats.tx_bytes += skb->len; | ||
692 | |||
693 | /* TX control: First packet immediately send, second packet queue */ | ||
694 | if (db->tx_pkt_cnt == 0) { | ||
695 | |||
696 | /* First Packet */ | ||
697 | db->tx_pkt_cnt++; | ||
698 | |||
699 | /* Set TX length to DM9000 */ | ||
700 | iow(db, DM9000_TXPLL, skb->len & 0xff); | ||
701 | iow(db, DM9000_TXPLH, (skb->len >> 8) & 0xff); | ||
702 | |||
703 | /* Issue TX polling command */ | ||
704 | iow(db, DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */ | ||
705 | |||
706 | dev->trans_start = jiffies; /* save the time stamp */ | ||
707 | |||
708 | } else { | ||
709 | /* Second packet */ | ||
710 | db->tx_pkt_cnt++; | ||
711 | db->queue_pkt_len = skb->len; | ||
712 | } | ||
713 | |||
714 | /* free this SKB */ | ||
715 | dev_kfree_skb(skb); | ||
716 | |||
717 | /* Re-enable resource check */ | ||
718 | if (db->tx_pkt_cnt == 1) | ||
719 | netif_wake_queue(dev); | ||
720 | |||
721 | /* Re-enable interrupt */ | ||
722 | iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM); | ||
723 | |||
724 | return 0; | ||
725 | } | ||
726 | |||
727 | static void | ||
728 | dm9000_shutdown(struct net_device *dev) | ||
729 | { | ||
730 | board_info_t *db = (board_info_t *) dev->priv; | ||
731 | |||
732 | /* RESET device */ | ||
733 | dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */ | ||
734 | iow(db, DM9000_GPR, 0x01); /* Power-Down PHY */ | ||
735 | iow(db, DM9000_IMR, IMR_PAR); /* Disable all interrupt */ | ||
736 | iow(db, DM9000_RCR, 0x00); /* Disable RX */ | ||
737 | } | ||
738 | |||
739 | /* | ||
740 | * Stop the interface. | ||
741 | * The interface is stopped when it is brought. | ||
742 | */ | ||
743 | static int | ||
744 | dm9000_stop(struct net_device *ndev) | ||
745 | { | ||
746 | board_info_t *db = (board_info_t *) ndev->priv; | ||
747 | |||
748 | PRINTK1("entering %s\n",__FUNCTION__); | ||
749 | |||
750 | /* deleted timer */ | ||
751 | del_timer(&db->timer); | ||
752 | |||
753 | netif_stop_queue(ndev); | ||
754 | netif_carrier_off(ndev); | ||
755 | |||
756 | /* free interrupt */ | ||
757 | free_irq(ndev->irq, ndev); | ||
758 | |||
759 | dm9000_shutdown(ndev); | ||
760 | |||
761 | return 0; | ||
762 | } | ||
763 | |||
764 | /* | ||
765 | * DM9000 interrupt handler | ||
766 | * receive the packet to upper layer, free the transmitted packet | ||
767 | */ | ||
768 | |||
769 | void | ||
770 | dm9000_tx_done(struct net_device *dev, board_info_t * db) | ||
771 | { | ||
772 | int tx_status = ior(db, DM9000_NSR); /* Got TX status */ | ||
773 | |||
774 | if (tx_status & (NSR_TX2END | NSR_TX1END)) { | ||
775 | /* One packet sent complete */ | ||
776 | db->tx_pkt_cnt--; | ||
777 | db->stats.tx_packets++; | ||
778 | |||
779 | /* Queue packet check & send */ | ||
780 | if (db->tx_pkt_cnt > 0) { | ||
781 | iow(db, DM9000_TXPLL, db->queue_pkt_len & 0xff); | ||
782 | iow(db, DM9000_TXPLH, (db->queue_pkt_len >> 8) & 0xff); | ||
783 | iow(db, DM9000_TCR, TCR_TXREQ); | ||
784 | dev->trans_start = jiffies; | ||
785 | } | ||
786 | netif_wake_queue(dev); | ||
787 | } | ||
788 | } | ||
789 | |||
790 | static irqreturn_t | ||
791 | dm9000_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
792 | { | ||
793 | struct net_device *dev = dev_id; | ||
794 | board_info_t *db; | ||
795 | int int_status; | ||
796 | u8 reg_save; | ||
797 | |||
798 | PRINTK3("entering %s\n",__FUNCTION__); | ||
799 | |||
800 | if (!dev) { | ||
801 | PRINTK1("dm9000_interrupt() without DEVICE arg\n"); | ||
802 | return IRQ_HANDLED; | ||
803 | } | ||
804 | |||
805 | /* A real interrupt coming */ | ||
806 | db = (board_info_t *) dev->priv; | ||
807 | spin_lock(&db->lock); | ||
808 | |||
809 | /* Save previous register address */ | ||
810 | reg_save = readb(db->io_addr); | ||
811 | |||
812 | /* Disable all interrupts */ | ||
813 | iow(db, DM9000_IMR, IMR_PAR); | ||
814 | |||
815 | /* Got DM9000 interrupt status */ | ||
816 | int_status = ior(db, DM9000_ISR); /* Got ISR */ | ||
817 | iow(db, DM9000_ISR, int_status); /* Clear ISR status */ | ||
818 | |||
819 | /* Received the coming packet */ | ||
820 | if (int_status & ISR_PRS) | ||
821 | dm9000_rx(dev); | ||
822 | |||
823 | /* Trnasmit Interrupt check */ | ||
824 | if (int_status & ISR_PTS) | ||
825 | dm9000_tx_done(dev, db); | ||
826 | |||
827 | /* Re-enable interrupt mask */ | ||
828 | iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM); | ||
829 | |||
830 | /* Restore previous register address */ | ||
831 | writeb(reg_save, db->io_addr); | ||
832 | |||
833 | spin_unlock(&db->lock); | ||
834 | |||
835 | return IRQ_HANDLED; | ||
836 | } | ||
837 | |||
838 | /* | ||
839 | * Get statistics from driver. | ||
840 | */ | ||
841 | static struct net_device_stats * | ||
842 | dm9000_get_stats(struct net_device *dev) | ||
843 | { | ||
844 | board_info_t *db = (board_info_t *) dev->priv; | ||
845 | return &db->stats; | ||
846 | } | ||
847 | |||
848 | /* | ||
849 | * Process the upper socket ioctl command | ||
850 | */ | ||
851 | static int | ||
852 | dm9000_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | ||
853 | { | ||
854 | PRINTK1("entering %s\n",__FUNCTION__); | ||
855 | return 0; | ||
856 | } | ||
857 | |||
858 | /* | ||
859 | * A periodic timer routine | ||
860 | * Dynamic media sense, allocated Rx buffer... | ||
861 | */ | ||
862 | static void | ||
863 | dm9000_timer(unsigned long data) | ||
864 | { | ||
865 | struct net_device *dev = (struct net_device *) data; | ||
866 | board_info_t *db = (board_info_t *) dev->priv; | ||
867 | u8 reg_save; | ||
868 | unsigned long flags; | ||
869 | |||
870 | PRINTK3("dm9000_timer()\n"); | ||
871 | |||
872 | spin_lock_irqsave(db->lock,flags); | ||
873 | /* Save previous register address */ | ||
874 | reg_save = readb(db->io_addr); | ||
875 | |||
876 | mii_check_media(&db->mii, netif_msg_link(db), 0); | ||
877 | |||
878 | /* Restore previous register address */ | ||
879 | writeb(reg_save, db->io_addr); | ||
880 | spin_unlock_irqrestore(db->lock,flags); | ||
881 | |||
882 | /* Set timer again */ | ||
883 | db->timer.expires = DM9000_TIMER_WUT; | ||
884 | add_timer(&db->timer); | ||
885 | } | ||
886 | |||
887 | struct dm9000_rxhdr { | ||
888 | u16 RxStatus; | ||
889 | u16 RxLen; | ||
890 | } __attribute__((__packed__)); | ||
891 | |||
892 | /* | ||
893 | * Received a packet and pass to upper layer | ||
894 | */ | ||
895 | static void | ||
896 | dm9000_rx(struct net_device *dev) | ||
897 | { | ||
898 | board_info_t *db = (board_info_t *) dev->priv; | ||
899 | struct dm9000_rxhdr rxhdr; | ||
900 | struct sk_buff *skb; | ||
901 | u8 rxbyte, *rdptr; | ||
902 | int GoodPacket; | ||
903 | int RxLen; | ||
904 | |||
905 | /* Check packet ready or not */ | ||
906 | do { | ||
907 | ior(db, DM9000_MRCMDX); /* Dummy read */ | ||
908 | |||
909 | /* Get most updated data */ | ||
910 | rxbyte = readb(db->io_data); | ||
911 | |||
912 | /* Status check: this byte must be 0 or 1 */ | ||
913 | if (rxbyte > DM9000_PKT_RDY) { | ||
914 | printk("status check failed: %d\n", rxbyte); | ||
915 | iow(db, DM9000_RCR, 0x00); /* Stop Device */ | ||
916 | iow(db, DM9000_ISR, IMR_PAR); /* Stop INT request */ | ||
917 | return; | ||
918 | } | ||
919 | |||
920 | if (rxbyte != DM9000_PKT_RDY) | ||
921 | return; | ||
922 | |||
923 | /* A packet ready now & Get status/length */ | ||
924 | GoodPacket = TRUE; | ||
925 | writeb(DM9000_MRCMD, db->io_addr); | ||
926 | |||
927 | (db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr)); | ||
928 | |||
929 | RxLen = rxhdr.RxLen; | ||
930 | |||
931 | /* Packet Status check */ | ||
932 | if (RxLen < 0x40) { | ||
933 | GoodPacket = FALSE; | ||
934 | PRINTK1("Bad Packet received (runt)\n"); | ||
935 | } | ||
936 | |||
937 | if (RxLen > DM9000_PKT_MAX) { | ||
938 | PRINTK1("RST: RX Len:%x\n", RxLen); | ||
939 | } | ||
940 | |||
941 | if (rxhdr.RxStatus & 0xbf00) { | ||
942 | GoodPacket = FALSE; | ||
943 | if (rxhdr.RxStatus & 0x100) { | ||
944 | PRINTK1("fifo error\n"); | ||
945 | db->stats.rx_fifo_errors++; | ||
946 | } | ||
947 | if (rxhdr.RxStatus & 0x200) { | ||
948 | PRINTK1("crc error\n"); | ||
949 | db->stats.rx_crc_errors++; | ||
950 | } | ||
951 | if (rxhdr.RxStatus & 0x8000) { | ||
952 | PRINTK1("length error\n"); | ||
953 | db->stats.rx_length_errors++; | ||
954 | } | ||
955 | } | ||
956 | |||
957 | /* Move data from DM9000 */ | ||
958 | if (GoodPacket | ||
959 | && ((skb = dev_alloc_skb(RxLen + 4)) != NULL)) { | ||
960 | skb->dev = dev; | ||
961 | skb_reserve(skb, 2); | ||
962 | rdptr = (u8 *) skb_put(skb, RxLen - 4); | ||
963 | |||
964 | /* Read received packet from RX SRAM */ | ||
965 | |||
966 | (db->inblk)(db->io_data, rdptr, RxLen); | ||
967 | db->stats.rx_bytes += RxLen; | ||
968 | |||
969 | /* Pass to upper layer */ | ||
970 | skb->protocol = eth_type_trans(skb, dev); | ||
971 | netif_rx(skb); | ||
972 | db->stats.rx_packets++; | ||
973 | |||
974 | } else { | ||
975 | /* need to dump the packet's data */ | ||
976 | |||
977 | (db->dumpblk)(db->io_data, RxLen); | ||
978 | } | ||
979 | } while (rxbyte == DM9000_PKT_RDY); | ||
980 | } | ||
981 | |||
982 | /* | ||
983 | * Read a word data from SROM | ||
984 | */ | ||
985 | static u16 | ||
986 | read_srom_word(board_info_t * db, int offset) | ||
987 | { | ||
988 | iow(db, DM9000_EPAR, offset); | ||
989 | iow(db, DM9000_EPCR, EPCR_ERPRR); | ||
990 | mdelay(8); /* according to the datasheet 200us should be enough, | ||
991 | but it doesn't work */ | ||
992 | iow(db, DM9000_EPCR, 0x0); | ||
993 | return (ior(db, DM9000_EPDRL) + (ior(db, DM9000_EPDRH) << 8)); | ||
994 | } | ||
995 | |||
996 | #ifdef DM9000_PROGRAM_EEPROM | ||
997 | /* | ||
998 | * Write a word data to SROM | ||
999 | */ | ||
1000 | static void | ||
1001 | write_srom_word(board_info_t * db, int offset, u16 val) | ||
1002 | { | ||
1003 | iow(db, DM9000_EPAR, offset); | ||
1004 | iow(db, DM9000_EPDRH, ((val >> 8) & 0xff)); | ||
1005 | iow(db, DM9000_EPDRL, (val & 0xff)); | ||
1006 | iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW); | ||
1007 | mdelay(8); /* same shit */ | ||
1008 | iow(db, DM9000_EPCR, 0); | ||
1009 | } | ||
1010 | |||
1011 | /* | ||
1012 | * Only for development: | ||
1013 | * Here we write static data to the eeprom in case | ||
1014 | * we don't have valid content on a new board | ||
1015 | */ | ||
1016 | static void | ||
1017 | program_eeprom(board_info_t * db) | ||
1018 | { | ||
1019 | u16 eeprom[] = { 0x0c00, 0x007f, 0x1300, /* MAC Address */ | ||
1020 | 0x0000, /* Autoload: accept nothing */ | ||
1021 | 0x0a46, 0x9000, /* Vendor / Product ID */ | ||
1022 | 0x0000, /* pin control */ | ||
1023 | 0x0000, | ||
1024 | }; /* Wake-up mode control */ | ||
1025 | int i; | ||
1026 | for (i = 0; i < 8; i++) | ||
1027 | write_srom_word(db, i, eeprom[i]); | ||
1028 | } | ||
1029 | #endif | ||
1030 | |||
1031 | |||
1032 | /* | ||
1033 | * Calculate the CRC valude of the Rx packet | ||
1034 | * flag = 1 : return the reverse CRC (for the received packet CRC) | ||
1035 | * 0 : return the normal CRC (for Hash Table index) | ||
1036 | */ | ||
1037 | |||
1038 | static unsigned long | ||
1039 | cal_CRC(unsigned char *Data, unsigned int Len, u8 flag) | ||
1040 | { | ||
1041 | |||
1042 | u32 crc = ether_crc_le(Len, Data); | ||
1043 | |||
1044 | if (flag) | ||
1045 | return ~crc; | ||
1046 | |||
1047 | return crc; | ||
1048 | } | ||
1049 | |||
1050 | /* | ||
1051 | * Set DM9000 multicast address | ||
1052 | */ | ||
1053 | static void | ||
1054 | dm9000_hash_table(struct net_device *dev) | ||
1055 | { | ||
1056 | board_info_t *db = (board_info_t *) dev->priv; | ||
1057 | struct dev_mc_list *mcptr = dev->mc_list; | ||
1058 | int mc_cnt = dev->mc_count; | ||
1059 | u32 hash_val; | ||
1060 | u16 i, oft, hash_table[4]; | ||
1061 | unsigned long flags; | ||
1062 | |||
1063 | PRINTK2("dm9000_hash_table()\n"); | ||
1064 | |||
1065 | spin_lock_irqsave(&db->lock,flags); | ||
1066 | |||
1067 | for (i = 0, oft = 0x10; i < 6; i++, oft++) | ||
1068 | iow(db, oft, dev->dev_addr[i]); | ||
1069 | |||
1070 | /* Clear Hash Table */ | ||
1071 | for (i = 0; i < 4; i++) | ||
1072 | hash_table[i] = 0x0; | ||
1073 | |||
1074 | /* broadcast address */ | ||
1075 | hash_table[3] = 0x8000; | ||
1076 | |||
1077 | /* the multicast address in Hash Table : 64 bits */ | ||
1078 | for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) { | ||
1079 | hash_val = cal_CRC((char *) mcptr->dmi_addr, 6, 0) & 0x3f; | ||
1080 | hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16); | ||
1081 | } | ||
1082 | |||
1083 | /* Write the hash table to MAC MD table */ | ||
1084 | for (i = 0, oft = 0x16; i < 4; i++) { | ||
1085 | iow(db, oft++, hash_table[i] & 0xff); | ||
1086 | iow(db, oft++, (hash_table[i] >> 8) & 0xff); | ||
1087 | } | ||
1088 | |||
1089 | spin_unlock_irqrestore(&db->lock,flags); | ||
1090 | } | ||
1091 | |||
1092 | |||
1093 | /* | ||
1094 | * Read a word from phyxcer | ||
1095 | */ | ||
1096 | static int | ||
1097 | dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg) | ||
1098 | { | ||
1099 | board_info_t *db = (board_info_t *) dev->priv; | ||
1100 | unsigned long flags; | ||
1101 | int ret; | ||
1102 | |||
1103 | spin_lock_irqsave(&db->lock,flags); | ||
1104 | /* Fill the phyxcer register into REG_0C */ | ||
1105 | iow(db, DM9000_EPAR, DM9000_PHY | reg); | ||
1106 | |||
1107 | iow(db, DM9000_EPCR, 0xc); /* Issue phyxcer read command */ | ||
1108 | udelay(100); /* Wait read complete */ | ||
1109 | iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer read command */ | ||
1110 | |||
1111 | /* The read data keeps on REG_0D & REG_0E */ | ||
1112 | ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL); | ||
1113 | |||
1114 | spin_unlock_irqrestore(&db->lock,flags); | ||
1115 | |||
1116 | return ret; | ||
1117 | } | ||
1118 | |||
1119 | /* | ||
1120 | * Write a word to phyxcer | ||
1121 | */ | ||
1122 | static void | ||
1123 | dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value) | ||
1124 | { | ||
1125 | board_info_t *db = (board_info_t *) dev->priv; | ||
1126 | unsigned long flags; | ||
1127 | |||
1128 | spin_lock_irqsave(&db->lock,flags); | ||
1129 | |||
1130 | /* Fill the phyxcer register into REG_0C */ | ||
1131 | iow(db, DM9000_EPAR, DM9000_PHY | reg); | ||
1132 | |||
1133 | /* Fill the written data into REG_0D & REG_0E */ | ||
1134 | iow(db, DM9000_EPDRL, (value & 0xff)); | ||
1135 | iow(db, DM9000_EPDRH, ((value >> 8) & 0xff)); | ||
1136 | |||
1137 | iow(db, DM9000_EPCR, 0xa); /* Issue phyxcer write command */ | ||
1138 | udelay(500); /* Wait write complete */ | ||
1139 | iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */ | ||
1140 | |||
1141 | spin_unlock_irqrestore(&db->lock,flags); | ||
1142 | } | ||
1143 | |||
1144 | static int | ||
1145 | dm9000_drv_suspend(struct device *dev, u32 state, u32 level) | ||
1146 | { | ||
1147 | struct net_device *ndev = dev_get_drvdata(dev); | ||
1148 | |||
1149 | if (ndev && level == SUSPEND_DISABLE) { | ||
1150 | if (netif_running(ndev)) { | ||
1151 | netif_device_detach(ndev); | ||
1152 | dm9000_shutdown(ndev); | ||
1153 | } | ||
1154 | } | ||
1155 | return 0; | ||
1156 | } | ||
1157 | |||
1158 | static int | ||
1159 | dm9000_drv_resume(struct device *dev, u32 level) | ||
1160 | { | ||
1161 | struct net_device *ndev = dev_get_drvdata(dev); | ||
1162 | board_info_t *db = (board_info_t *) ndev->priv; | ||
1163 | |||
1164 | if (ndev && level == RESUME_ENABLE) { | ||
1165 | |||
1166 | if (netif_running(ndev)) { | ||
1167 | dm9000_reset(db); | ||
1168 | dm9000_init_dm9000(ndev); | ||
1169 | |||
1170 | netif_device_attach(ndev); | ||
1171 | } | ||
1172 | } | ||
1173 | return 0; | ||
1174 | } | ||
1175 | |||
1176 | static int | ||
1177 | dm9000_drv_remove(struct device *dev) | ||
1178 | { | ||
1179 | struct platform_device *pdev = to_platform_device(dev); | ||
1180 | struct net_device *ndev = dev_get_drvdata(dev); | ||
1181 | |||
1182 | dev_set_drvdata(dev, NULL); | ||
1183 | |||
1184 | unregister_netdev(ndev); | ||
1185 | dm9000_release_board(pdev, (board_info_t *) ndev->priv); | ||
1186 | kfree(ndev); /* free device structure */ | ||
1187 | |||
1188 | PRINTK1("clean_module() exit\n"); | ||
1189 | |||
1190 | return 0; | ||
1191 | } | ||
1192 | |||
1193 | static struct device_driver dm9000_driver = { | ||
1194 | .name = "dm9000", | ||
1195 | .bus = &platform_bus_type, | ||
1196 | .probe = dm9000_probe, | ||
1197 | .remove = dm9000_drv_remove, | ||
1198 | .suspend = dm9000_drv_suspend, | ||
1199 | .resume = dm9000_drv_resume, | ||
1200 | }; | ||
1201 | |||
1202 | static int __init | ||
1203 | dm9000_init(void) | ||
1204 | { | ||
1205 | return driver_register(&dm9000_driver); /* search board and register */ | ||
1206 | } | ||
1207 | |||
1208 | static void __exit | ||
1209 | dm9000_cleanup(void) | ||
1210 | { | ||
1211 | driver_unregister(&dm9000_driver); | ||
1212 | } | ||
1213 | |||
1214 | module_init(dm9000_init); | ||
1215 | module_exit(dm9000_cleanup); | ||
1216 | |||
1217 | MODULE_AUTHOR("Sascha Hauer, Ben Dooks"); | ||
1218 | MODULE_DESCRIPTION("Davicom DM9000 network driver"); | ||
1219 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/dm9000.h b/drivers/net/dm9000.h new file mode 100644 index 000000000000..82cad360bafc --- /dev/null +++ b/drivers/net/dm9000.h | |||
@@ -0,0 +1,135 @@ | |||
1 | /* | ||
2 | * dm9000 Ethernet | ||
3 | */ | ||
4 | |||
5 | #ifndef _DM9000X_H_ | ||
6 | #define _DM9000X_H_ | ||
7 | |||
8 | #define DM9000_ID 0x90000A46 | ||
9 | |||
10 | /* although the registers are 16 bit, they are 32-bit aligned. | ||
11 | */ | ||
12 | |||
13 | #define DM9000_NCR 0x00 | ||
14 | #define DM9000_NSR 0x01 | ||
15 | #define DM9000_TCR 0x02 | ||
16 | #define DM9000_TSR1 0x03 | ||
17 | #define DM9000_TSR2 0x04 | ||
18 | #define DM9000_RCR 0x05 | ||
19 | #define DM9000_RSR 0x06 | ||
20 | #define DM9000_ROCR 0x07 | ||
21 | #define DM9000_BPTR 0x08 | ||
22 | #define DM9000_FCTR 0x09 | ||
23 | #define DM9000_FCR 0x0A | ||
24 | #define DM9000_EPCR 0x0B | ||
25 | #define DM9000_EPAR 0x0C | ||
26 | #define DM9000_EPDRL 0x0D | ||
27 | #define DM9000_EPDRH 0x0E | ||
28 | #define DM9000_WCR 0x0F | ||
29 | |||
30 | #define DM9000_PAR 0x10 | ||
31 | #define DM9000_MAR 0x16 | ||
32 | |||
33 | #define DM9000_GPCR 0x1e | ||
34 | #define DM9000_GPR 0x1f | ||
35 | #define DM9000_TRPAL 0x22 | ||
36 | #define DM9000_TRPAH 0x23 | ||
37 | #define DM9000_RWPAL 0x24 | ||
38 | #define DM9000_RWPAH 0x25 | ||
39 | |||
40 | #define DM9000_VIDL 0x28 | ||
41 | #define DM9000_VIDH 0x29 | ||
42 | #define DM9000_PIDL 0x2A | ||
43 | #define DM9000_PIDH 0x2B | ||
44 | |||
45 | #define DM9000_CHIPR 0x2C | ||
46 | #define DM9000_SMCR 0x2F | ||
47 | |||
48 | #define DM9000_MRCMDX 0xF0 | ||
49 | #define DM9000_MRCMD 0xF2 | ||
50 | #define DM9000_MRRL 0xF4 | ||
51 | #define DM9000_MRRH 0xF5 | ||
52 | #define DM9000_MWCMDX 0xF6 | ||
53 | #define DM9000_MWCMD 0xF8 | ||
54 | #define DM9000_MWRL 0xFA | ||
55 | #define DM9000_MWRH 0xFB | ||
56 | #define DM9000_TXPLL 0xFC | ||
57 | #define DM9000_TXPLH 0xFD | ||
58 | #define DM9000_ISR 0xFE | ||
59 | #define DM9000_IMR 0xFF | ||
60 | |||
61 | #define NCR_EXT_PHY (1<<7) | ||
62 | #define NCR_WAKEEN (1<<6) | ||
63 | #define NCR_FCOL (1<<4) | ||
64 | #define NCR_FDX (1<<3) | ||
65 | #define NCR_LBK (3<<1) | ||
66 | #define NCR_RST (1<<0) | ||
67 | |||
68 | #define NSR_SPEED (1<<7) | ||
69 | #define NSR_LINKST (1<<6) | ||
70 | #define NSR_WAKEST (1<<5) | ||
71 | #define NSR_TX2END (1<<3) | ||
72 | #define NSR_TX1END (1<<2) | ||
73 | #define NSR_RXOV (1<<1) | ||
74 | |||
75 | #define TCR_TJDIS (1<<6) | ||
76 | #define TCR_EXCECM (1<<5) | ||
77 | #define TCR_PAD_DIS2 (1<<4) | ||
78 | #define TCR_CRC_DIS2 (1<<3) | ||
79 | #define TCR_PAD_DIS1 (1<<2) | ||
80 | #define TCR_CRC_DIS1 (1<<1) | ||
81 | #define TCR_TXREQ (1<<0) | ||
82 | |||
83 | #define TSR_TJTO (1<<7) | ||
84 | #define TSR_LC (1<<6) | ||
85 | #define TSR_NC (1<<5) | ||
86 | #define TSR_LCOL (1<<4) | ||
87 | #define TSR_COL (1<<3) | ||
88 | #define TSR_EC (1<<2) | ||
89 | |||
90 | #define RCR_WTDIS (1<<6) | ||
91 | #define RCR_DIS_LONG (1<<5) | ||
92 | #define RCR_DIS_CRC (1<<4) | ||
93 | #define RCR_ALL (1<<3) | ||
94 | #define RCR_RUNT (1<<2) | ||
95 | #define RCR_PRMSC (1<<1) | ||
96 | #define RCR_RXEN (1<<0) | ||
97 | |||
98 | #define RSR_RF (1<<7) | ||
99 | #define RSR_MF (1<<6) | ||
100 | #define RSR_LCS (1<<5) | ||
101 | #define RSR_RWTO (1<<4) | ||
102 | #define RSR_PLE (1<<3) | ||
103 | #define RSR_AE (1<<2) | ||
104 | #define RSR_CE (1<<1) | ||
105 | #define RSR_FOE (1<<0) | ||
106 | |||
107 | #define FCTR_HWOT(ot) (( ot & 0xf ) << 4 ) | ||
108 | #define FCTR_LWOT(ot) ( ot & 0xf ) | ||
109 | |||
110 | #define IMR_PAR (1<<7) | ||
111 | #define IMR_ROOM (1<<3) | ||
112 | #define IMR_ROM (1<<2) | ||
113 | #define IMR_PTM (1<<1) | ||
114 | #define IMR_PRM (1<<0) | ||
115 | |||
116 | #define ISR_ROOS (1<<3) | ||
117 | #define ISR_ROS (1<<2) | ||
118 | #define ISR_PTS (1<<1) | ||
119 | #define ISR_PRS (1<<0) | ||
120 | #define ISR_CLR_STATUS (ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS) | ||
121 | |||
122 | #define EPCR_REEP (1<<5) | ||
123 | #define EPCR_WEP (1<<4) | ||
124 | #define EPCR_EPOS (1<<3) | ||
125 | #define EPCR_ERPRR (1<<2) | ||
126 | #define EPCR_ERPRW (1<<1) | ||
127 | #define EPCR_ERRE (1<<0) | ||
128 | |||
129 | #define GPCR_GEP_CNTL (1<<0) | ||
130 | |||
131 | #define DM9000_PKT_RDY 0x01 /* Packet ready to receive */ | ||
132 | #define DM9000_PKT_MAX 1536 /* Received packet max size */ | ||
133 | |||
134 | #endif /* _DM9000X_H_ */ | ||
135 | |||
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index 1c563f905a59..a7f15d9f13e5 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c | |||
@@ -374,29 +374,6 @@ static inline void do_kiss_params(struct baycom_state *bc, | |||
374 | } | 374 | } |
375 | 375 | ||
376 | /* --------------------------------------------------------------------- */ | 376 | /* --------------------------------------------------------------------- */ |
377 | /* | ||
378 | * high performance HDLC encoder | ||
379 | * yes, it's ugly, but generates pretty good code | ||
380 | */ | ||
381 | |||
382 | #define ENCODEITERA(j) \ | ||
383 | ({ \ | ||
384 | if (!(notbitstream & (0x1f0 << j))) \ | ||
385 | goto stuff##j; \ | ||
386 | encodeend##j: ; \ | ||
387 | }) | ||
388 | |||
389 | #define ENCODEITERB(j) \ | ||
390 | ({ \ | ||
391 | stuff##j: \ | ||
392 | bitstream &= ~(0x100 << j); \ | ||
393 | bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) | \ | ||
394 | ((bitbuf & ~(((2 << j) << numbit) - 1)) << 1); \ | ||
395 | numbit++; \ | ||
396 | notbitstream = ~bitstream; \ | ||
397 | goto encodeend##j; \ | ||
398 | }) | ||
399 | |||
400 | 377 | ||
401 | static void encode_hdlc(struct baycom_state *bc) | 378 | static void encode_hdlc(struct baycom_state *bc) |
402 | { | 379 | { |
@@ -405,6 +382,7 @@ static void encode_hdlc(struct baycom_state *bc) | |||
405 | int pkt_len; | 382 | int pkt_len; |
406 | unsigned bitstream, notbitstream, bitbuf, numbit, crc; | 383 | unsigned bitstream, notbitstream, bitbuf, numbit, crc; |
407 | unsigned char crcarr[2]; | 384 | unsigned char crcarr[2]; |
385 | int j; | ||
408 | 386 | ||
409 | if (bc->hdlctx.bufcnt > 0) | 387 | if (bc->hdlctx.bufcnt > 0) |
410 | return; | 388 | return; |
@@ -429,24 +407,14 @@ static void encode_hdlc(struct baycom_state *bc) | |||
429 | pkt_len--; | 407 | pkt_len--; |
430 | if (!pkt_len) | 408 | if (!pkt_len) |
431 | bp = crcarr; | 409 | bp = crcarr; |
432 | ENCODEITERA(0); | 410 | for (j = 0; j < 8; j++) |
433 | ENCODEITERA(1); | 411 | if (unlikely(!(notbitstream & (0x1f0 << j)))) { |
434 | ENCODEITERA(2); | 412 | bitstream &= ~(0x100 << j); |
435 | ENCODEITERA(3); | 413 | bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) | |
436 | ENCODEITERA(4); | 414 | ((bitbuf & ~(((2 << j) << numbit) - 1)) << 1); |
437 | ENCODEITERA(5); | 415 | numbit++; |
438 | ENCODEITERA(6); | 416 | notbitstream = ~bitstream; |
439 | ENCODEITERA(7); | 417 | } |
440 | goto enditer; | ||
441 | ENCODEITERB(0); | ||
442 | ENCODEITERB(1); | ||
443 | ENCODEITERB(2); | ||
444 | ENCODEITERB(3); | ||
445 | ENCODEITERB(4); | ||
446 | ENCODEITERB(5); | ||
447 | ENCODEITERB(6); | ||
448 | ENCODEITERB(7); | ||
449 | enditer: | ||
450 | numbit += 8; | 418 | numbit += 8; |
451 | while (numbit >= 8) { | 419 | while (numbit >= 8) { |
452 | *wp++ = bitbuf; | 420 | *wp++ = bitbuf; |
@@ -610,37 +578,6 @@ static void do_rxpacket(struct net_device *dev) | |||
610 | bc->stats.rx_packets++; | 578 | bc->stats.rx_packets++; |
611 | } | 579 | } |
612 | 580 | ||
613 | #define DECODEITERA(j) \ | ||
614 | ({ \ | ||
615 | if (!(notbitstream & (0x0fc << j))) /* flag or abort */ \ | ||
616 | goto flgabrt##j; \ | ||
617 | if ((bitstream & (0x1f8 << j)) == (0xf8 << j)) /* stuffed bit */ \ | ||
618 | goto stuff##j; \ | ||
619 | enditer##j: ; \ | ||
620 | }) | ||
621 | |||
622 | #define DECODEITERB(j) \ | ||
623 | ({ \ | ||
624 | flgabrt##j: \ | ||
625 | if (!(notbitstream & (0x1fc << j))) { /* abort received */ \ | ||
626 | state = 0; \ | ||
627 | goto enditer##j; \ | ||
628 | } \ | ||
629 | if ((bitstream & (0x1fe << j)) != (0x0fc << j)) /* flag received */ \ | ||
630 | goto enditer##j; \ | ||
631 | if (state) \ | ||
632 | do_rxpacket(dev); \ | ||
633 | bc->hdlcrx.bufcnt = 0; \ | ||
634 | bc->hdlcrx.bufptr = bc->hdlcrx.buf; \ | ||
635 | state = 1; \ | ||
636 | numbits = 7-j; \ | ||
637 | goto enditer##j; \ | ||
638 | stuff##j: \ | ||
639 | numbits--; \ | ||
640 | bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1); \ | ||
641 | goto enditer##j; \ | ||
642 | }) | ||
643 | |||
644 | static int receive(struct net_device *dev, int cnt) | 581 | static int receive(struct net_device *dev, int cnt) |
645 | { | 582 | { |
646 | struct baycom_state *bc = netdev_priv(dev); | 583 | struct baycom_state *bc = netdev_priv(dev); |
@@ -649,6 +586,7 @@ static int receive(struct net_device *dev, int cnt) | |||
649 | unsigned char tmp[128]; | 586 | unsigned char tmp[128]; |
650 | unsigned char *cp; | 587 | unsigned char *cp; |
651 | int cnt2, ret = 0; | 588 | int cnt2, ret = 0; |
589 | int j; | ||
652 | 590 | ||
653 | numbits = bc->hdlcrx.numbits; | 591 | numbits = bc->hdlcrx.numbits; |
654 | state = bc->hdlcrx.state; | 592 | state = bc->hdlcrx.state; |
@@ -669,24 +607,32 @@ static int receive(struct net_device *dev, int cnt) | |||
669 | bitbuf |= (*cp) << 8; | 607 | bitbuf |= (*cp) << 8; |
670 | numbits += 8; | 608 | numbits += 8; |
671 | notbitstream = ~bitstream; | 609 | notbitstream = ~bitstream; |
672 | DECODEITERA(0); | 610 | for (j = 0; j < 8; j++) { |
673 | DECODEITERA(1); | 611 | |
674 | DECODEITERA(2); | 612 | /* flag or abort */ |
675 | DECODEITERA(3); | 613 | if (unlikely(!(notbitstream & (0x0fc << j)))) { |
676 | DECODEITERA(4); | 614 | |
677 | DECODEITERA(5); | 615 | /* abort received */ |
678 | DECODEITERA(6); | 616 | if (!(notbitstream & (0x1fc << j))) |
679 | DECODEITERA(7); | 617 | state = 0; |
680 | goto enddec; | 618 | |
681 | DECODEITERB(0); | 619 | /* not flag received */ |
682 | DECODEITERB(1); | 620 | else if (!(bitstream & (0x1fe << j)) != (0x0fc << j)) { |
683 | DECODEITERB(2); | 621 | if (state) |
684 | DECODEITERB(3); | 622 | do_rxpacket(dev); |
685 | DECODEITERB(4); | 623 | bc->hdlcrx.bufcnt = 0; |
686 | DECODEITERB(5); | 624 | bc->hdlcrx.bufptr = bc->hdlcrx.buf; |
687 | DECODEITERB(6); | 625 | state = 1; |
688 | DECODEITERB(7); | 626 | numbits = 7-j; |
689 | enddec: | 627 | } |
628 | } | ||
629 | |||
630 | /* stuffed bit */ | ||
631 | else if (unlikely((bitstream & (0x1f8 << j)) == (0xf8 << j))) { | ||
632 | numbits--; | ||
633 | bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1); | ||
634 | } | ||
635 | } | ||
690 | while (state && numbits >= 8) { | 636 | while (state && numbits >= 8) { |
691 | if (bc->hdlcrx.bufcnt >= TXBUFFER_SIZE) { | 637 | if (bc->hdlcrx.bufcnt >= TXBUFFER_SIZE) { |
692 | state = 0; | 638 | state = 0; |
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 3b377f6cd4a0..ad4b58af6b76 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c | |||
@@ -1217,36 +1217,43 @@ ppp_push(struct ppp *ppp) | |||
1217 | */ | 1217 | */ |
1218 | static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) | 1218 | static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) |
1219 | { | 1219 | { |
1220 | int nch, len, fragsize; | 1220 | int len, fragsize; |
1221 | int i, bits, hdrlen, mtu; | 1221 | int i, bits, hdrlen, mtu; |
1222 | int flen, fnb; | 1222 | int flen; |
1223 | int navail, nfree; | ||
1224 | int nbigger; | ||
1223 | unsigned char *p, *q; | 1225 | unsigned char *p, *q; |
1224 | struct list_head *list; | 1226 | struct list_head *list; |
1225 | struct channel *pch; | 1227 | struct channel *pch; |
1226 | struct sk_buff *frag; | 1228 | struct sk_buff *frag; |
1227 | struct ppp_channel *chan; | 1229 | struct ppp_channel *chan; |
1228 | 1230 | ||
1229 | nch = 0; | 1231 | nfree = 0; /* # channels which have no packet already queued */ |
1232 | navail = 0; /* total # of usable channels (not deregistered) */ | ||
1230 | hdrlen = (ppp->flags & SC_MP_XSHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN; | 1233 | hdrlen = (ppp->flags & SC_MP_XSHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN; |
1234 | i = 0; | ||
1231 | list = &ppp->channels; | 1235 | list = &ppp->channels; |
1232 | while ((list = list->next) != &ppp->channels) { | 1236 | while ((list = list->next) != &ppp->channels) { |
1233 | pch = list_entry(list, struct channel, clist); | 1237 | pch = list_entry(list, struct channel, clist); |
1234 | nch += pch->avail = (skb_queue_len(&pch->file.xq) == 0); | 1238 | navail += pch->avail = (pch->chan != NULL); |
1235 | /* | 1239 | if (pch->avail) { |
1236 | * If a channel hasn't had a fragment yet, it has to get | 1240 | if (skb_queue_len(&pch->file.xq) == 0 |
1237 | * one before we send any fragments on later channels. | 1241 | || !pch->had_frag) { |
1238 | * If it can't take a fragment now, don't give any | 1242 | pch->avail = 2; |
1239 | * to subsequent channels. | 1243 | ++nfree; |
1240 | */ | ||
1241 | if (!pch->had_frag && !pch->avail) { | ||
1242 | while ((list = list->next) != &ppp->channels) { | ||
1243 | pch = list_entry(list, struct channel, clist); | ||
1244 | pch->avail = 0; | ||
1245 | } | 1244 | } |
1246 | break; | 1245 | if (!pch->had_frag && i < ppp->nxchan) |
1246 | ppp->nxchan = i; | ||
1247 | } | 1247 | } |
1248 | ++i; | ||
1248 | } | 1249 | } |
1249 | if (nch == 0) | 1250 | |
1251 | /* | ||
1252 | * Don't start sending this packet unless at least half of | ||
1253 | * the channels are free. This gives much better TCP | ||
1254 | * performance if we have a lot of channels. | ||
1255 | */ | ||
1256 | if (nfree == 0 || nfree < navail / 2) | ||
1250 | return 0; /* can't take now, leave it in xmit_pending */ | 1257 | return 0; /* can't take now, leave it in xmit_pending */ |
1251 | 1258 | ||
1252 | /* Do protocol field compression (XXX this should be optional) */ | 1259 | /* Do protocol field compression (XXX this should be optional) */ |
@@ -1257,14 +1264,19 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) | |||
1257 | --len; | 1264 | --len; |
1258 | } | 1265 | } |
1259 | 1266 | ||
1260 | /* decide on fragment size */ | 1267 | /* |
1268 | * Decide on fragment size. | ||
1269 | * We create a fragment for each free channel regardless of | ||
1270 | * how small they are (i.e. even 0 length) in order to minimize | ||
1271 | * the time that it will take to detect when a channel drops | ||
1272 | * a fragment. | ||
1273 | */ | ||
1261 | fragsize = len; | 1274 | fragsize = len; |
1262 | if (nch > 1) { | 1275 | if (nfree > 1) |
1263 | int maxch = ROUNDUP(len, MIN_FRAG_SIZE); | 1276 | fragsize = ROUNDUP(fragsize, nfree); |
1264 | if (nch > maxch) | 1277 | /* nbigger channels get fragsize bytes, the rest get fragsize-1, |
1265 | nch = maxch; | 1278 | except if nbigger==0, then they all get fragsize. */ |
1266 | fragsize = ROUNDUP(fragsize, nch); | 1279 | nbigger = len % nfree; |
1267 | } | ||
1268 | 1280 | ||
1269 | /* skip to the channel after the one we last used | 1281 | /* skip to the channel after the one we last used |
1270 | and start at that one */ | 1282 | and start at that one */ |
@@ -1278,7 +1290,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) | |||
1278 | 1290 | ||
1279 | /* create a fragment for each channel */ | 1291 | /* create a fragment for each channel */ |
1280 | bits = B; | 1292 | bits = B; |
1281 | do { | 1293 | while (nfree > 0 || len > 0) { |
1282 | list = list->next; | 1294 | list = list->next; |
1283 | if (list == &ppp->channels) { | 1295 | if (list == &ppp->channels) { |
1284 | i = 0; | 1296 | i = 0; |
@@ -1289,61 +1301,92 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) | |||
1289 | if (!pch->avail) | 1301 | if (!pch->avail) |
1290 | continue; | 1302 | continue; |
1291 | 1303 | ||
1304 | /* | ||
1305 | * Skip this channel if it has a fragment pending already and | ||
1306 | * we haven't given a fragment to all of the free channels. | ||
1307 | */ | ||
1308 | if (pch->avail == 1) { | ||
1309 | if (nfree > 0) | ||
1310 | continue; | ||
1311 | } else { | ||
1312 | --nfree; | ||
1313 | pch->avail = 1; | ||
1314 | } | ||
1315 | |||
1292 | /* check the channel's mtu and whether it is still attached. */ | 1316 | /* check the channel's mtu and whether it is still attached. */ |
1293 | spin_lock_bh(&pch->downl); | 1317 | spin_lock_bh(&pch->downl); |
1294 | if (pch->chan == 0 || (mtu = pch->chan->mtu) < hdrlen) { | 1318 | if (pch->chan == NULL) { |
1295 | /* can't use this channel */ | 1319 | /* can't use this channel, it's being deregistered */ |
1296 | spin_unlock_bh(&pch->downl); | 1320 | spin_unlock_bh(&pch->downl); |
1297 | pch->avail = 0; | 1321 | pch->avail = 0; |
1298 | if (--nch == 0) | 1322 | if (--navail == 0) |
1299 | break; | 1323 | break; |
1300 | continue; | 1324 | continue; |
1301 | } | 1325 | } |
1302 | 1326 | ||
1303 | /* | 1327 | /* |
1304 | * We have to create multiple fragments for this channel | 1328 | * Create a fragment for this channel of |
1305 | * if fragsize is greater than the channel's mtu. | 1329 | * min(max(mtu+2-hdrlen, 4), fragsize, len) bytes. |
1330 | * If mtu+2-hdrlen < 4, that is a ridiculously small | ||
1331 | * MTU, so we use mtu = 2 + hdrlen. | ||
1306 | */ | 1332 | */ |
1307 | if (fragsize > len) | 1333 | if (fragsize > len) |
1308 | fragsize = len; | 1334 | fragsize = len; |
1309 | for (flen = fragsize; flen > 0; flen -= fnb) { | 1335 | flen = fragsize; |
1310 | fnb = flen; | 1336 | mtu = pch->chan->mtu + 2 - hdrlen; |
1311 | if (fnb > mtu + 2 - hdrlen) | 1337 | if (mtu < 4) |
1312 | fnb = mtu + 2 - hdrlen; | 1338 | mtu = 4; |
1313 | if (fnb >= len) | 1339 | if (flen > mtu) |
1314 | bits |= E; | 1340 | flen = mtu; |
1315 | frag = alloc_skb(fnb + hdrlen, GFP_ATOMIC); | 1341 | if (flen == len && nfree == 0) |
1316 | if (frag == 0) | 1342 | bits |= E; |
1317 | goto noskb; | 1343 | frag = alloc_skb(flen + hdrlen + (flen == 0), GFP_ATOMIC); |
1318 | q = skb_put(frag, fnb + hdrlen); | 1344 | if (frag == 0) |
1319 | /* make the MP header */ | 1345 | goto noskb; |
1320 | q[0] = PPP_MP >> 8; | 1346 | q = skb_put(frag, flen + hdrlen); |
1321 | q[1] = PPP_MP; | 1347 | |
1322 | if (ppp->flags & SC_MP_XSHORTSEQ) { | 1348 | /* make the MP header */ |
1323 | q[2] = bits + ((ppp->nxseq >> 8) & 0xf); | 1349 | q[0] = PPP_MP >> 8; |
1324 | q[3] = ppp->nxseq; | 1350 | q[1] = PPP_MP; |
1325 | } else { | 1351 | if (ppp->flags & SC_MP_XSHORTSEQ) { |
1326 | q[2] = bits; | 1352 | q[2] = bits + ((ppp->nxseq >> 8) & 0xf); |
1327 | q[3] = ppp->nxseq >> 16; | 1353 | q[3] = ppp->nxseq; |
1328 | q[4] = ppp->nxseq >> 8; | 1354 | } else { |
1329 | q[5] = ppp->nxseq; | 1355 | q[2] = bits; |
1330 | } | 1356 | q[3] = ppp->nxseq >> 16; |
1331 | 1357 | q[4] = ppp->nxseq >> 8; | |
1332 | /* copy the data in */ | 1358 | q[5] = ppp->nxseq; |
1333 | memcpy(q + hdrlen, p, fnb); | ||
1334 | |||
1335 | /* try to send it down the channel */ | ||
1336 | chan = pch->chan; | ||
1337 | if (!chan->ops->start_xmit(chan, frag)) | ||
1338 | skb_queue_tail(&pch->file.xq, frag); | ||
1339 | pch->had_frag = 1; | ||
1340 | p += fnb; | ||
1341 | len -= fnb; | ||
1342 | ++ppp->nxseq; | ||
1343 | bits = 0; | ||
1344 | } | 1359 | } |
1360 | |||
1361 | /* | ||
1362 | * Copy the data in. | ||
1363 | * Unfortunately there is a bug in older versions of | ||
1364 | * the Linux PPP multilink reconstruction code where it | ||
1365 | * drops 0-length fragments. Therefore we make sure the | ||
1366 | * fragment has at least one byte of data. Any bytes | ||
1367 | * we add in this situation will end up as padding on the | ||
1368 | * end of the reconstructed packet. | ||
1369 | */ | ||
1370 | if (flen == 0) | ||
1371 | *skb_put(frag, 1) = 0; | ||
1372 | else | ||
1373 | memcpy(q + hdrlen, p, flen); | ||
1374 | |||
1375 | /* try to send it down the channel */ | ||
1376 | chan = pch->chan; | ||
1377 | if (skb_queue_len(&pch->file.xq) | ||
1378 | || !chan->ops->start_xmit(chan, frag)) | ||
1379 | skb_queue_tail(&pch->file.xq, frag); | ||
1380 | pch->had_frag = 1; | ||
1381 | p += flen; | ||
1382 | len -= flen; | ||
1383 | ++ppp->nxseq; | ||
1384 | bits = 0; | ||
1345 | spin_unlock_bh(&pch->downl); | 1385 | spin_unlock_bh(&pch->downl); |
1346 | } while (len > 0); | 1386 | |
1387 | if (--nbigger == 0 && fragsize > 0) | ||
1388 | --fragsize; | ||
1389 | } | ||
1347 | ppp->nxchan = i; | 1390 | ppp->nxchan = i; |
1348 | 1391 | ||
1349 | return 1; | 1392 | return 1; |
@@ -1422,7 +1465,7 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb) | |||
1422 | kfree_skb(skb); | 1465 | kfree_skb(skb); |
1423 | return; | 1466 | return; |
1424 | } | 1467 | } |
1425 | 1468 | ||
1426 | proto = PPP_PROTO(skb); | 1469 | proto = PPP_PROTO(skb); |
1427 | read_lock_bh(&pch->upl); | 1470 | read_lock_bh(&pch->upl); |
1428 | if (pch->ppp == 0 || proto >= 0xc000 || proto == PPP_CCPFRAG) { | 1471 | if (pch->ppp == 0 || proto >= 0xc000 || proto == PPP_CCPFRAG) { |
@@ -1691,7 +1734,7 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) | |||
1691 | struct list_head *l; | 1734 | struct list_head *l; |
1692 | int mphdrlen = (ppp->flags & SC_MP_SHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN; | 1735 | int mphdrlen = (ppp->flags & SC_MP_SHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN; |
1693 | 1736 | ||
1694 | if (!pskb_may_pull(skb, mphdrlen + 1) || ppp->mrru == 0) | 1737 | if (!pskb_may_pull(skb, mphdrlen) || ppp->mrru == 0) |
1695 | goto err; /* no good, throw it away */ | 1738 | goto err; /* no good, throw it away */ |
1696 | 1739 | ||
1697 | /* Decode sequence number and begin/end bits */ | 1740 | /* Decode sequence number and begin/end bits */ |
diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c index e68cf5fb4920..20edeb345792 100644 --- a/drivers/net/shaper.c +++ b/drivers/net/shaper.c | |||
@@ -100,35 +100,8 @@ static int sh_debug; /* Debug flag */ | |||
100 | 100 | ||
101 | #define SHAPER_BANNER "CymruNet Traffic Shaper BETA 0.04 for Linux 2.1\n" | 101 | #define SHAPER_BANNER "CymruNet Traffic Shaper BETA 0.04 for Linux 2.1\n" |
102 | 102 | ||
103 | /* | ||
104 | * Locking | ||
105 | */ | ||
106 | |||
107 | static int shaper_lock(struct shaper *sh) | ||
108 | { | ||
109 | /* | ||
110 | * Lock in an interrupt must fail | ||
111 | */ | ||
112 | while (test_and_set_bit(0, &sh->locked)) | ||
113 | { | ||
114 | if (!in_interrupt()) | ||
115 | sleep_on(&sh->wait_queue); | ||
116 | else | ||
117 | return 0; | ||
118 | |||
119 | } | ||
120 | return 1; | ||
121 | } | ||
122 | |||
123 | static void shaper_kick(struct shaper *sh); | 103 | static void shaper_kick(struct shaper *sh); |
124 | 104 | ||
125 | static void shaper_unlock(struct shaper *sh) | ||
126 | { | ||
127 | clear_bit(0, &sh->locked); | ||
128 | wake_up(&sh->wait_queue); | ||
129 | shaper_kick(sh); | ||
130 | } | ||
131 | |||
132 | /* | 105 | /* |
133 | * Compute clocks on a buffer | 106 | * Compute clocks on a buffer |
134 | */ | 107 | */ |
@@ -157,17 +130,15 @@ static void shaper_setspeed(struct shaper *shaper, int bitspersec) | |||
157 | * Throw a frame at a shaper. | 130 | * Throw a frame at a shaper. |
158 | */ | 131 | */ |
159 | 132 | ||
160 | static int shaper_qframe(struct shaper *shaper, struct sk_buff *skb) | 133 | |
134 | static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
161 | { | 135 | { |
136 | struct shaper *shaper = dev->priv; | ||
162 | struct sk_buff *ptr; | 137 | struct sk_buff *ptr; |
163 | 138 | ||
164 | /* | 139 | if (down_trylock(&shaper->sem)) |
165 | * Get ready to work on this shaper. Lock may fail if its | 140 | return -1; |
166 | * an interrupt and locked. | 141 | |
167 | */ | ||
168 | |||
169 | if(!shaper_lock(shaper)) | ||
170 | return -1; | ||
171 | ptr=shaper->sendq.prev; | 142 | ptr=shaper->sendq.prev; |
172 | 143 | ||
173 | /* | 144 | /* |
@@ -260,7 +231,8 @@ static int shaper_qframe(struct shaper *shaper, struct sk_buff *skb) | |||
260 | dev_kfree_skb(ptr); | 231 | dev_kfree_skb(ptr); |
261 | shaper->stats.collisions++; | 232 | shaper->stats.collisions++; |
262 | } | 233 | } |
263 | shaper_unlock(shaper); | 234 | shaper_kick(shaper); |
235 | up(&shaper->sem); | ||
264 | return 0; | 236 | return 0; |
265 | } | 237 | } |
266 | 238 | ||
@@ -297,8 +269,13 @@ static void shaper_queue_xmit(struct shaper *shaper, struct sk_buff *skb) | |||
297 | 269 | ||
298 | static void shaper_timer(unsigned long data) | 270 | static void shaper_timer(unsigned long data) |
299 | { | 271 | { |
300 | struct shaper *sh=(struct shaper *)data; | 272 | struct shaper *shaper = (struct shaper *)data; |
301 | shaper_kick(sh); | 273 | |
274 | if (!down_trylock(&shaper->sem)) { | ||
275 | shaper_kick(shaper); | ||
276 | up(&shaper->sem); | ||
277 | } else | ||
278 | mod_timer(&shaper->timer, jiffies); | ||
302 | } | 279 | } |
303 | 280 | ||
304 | /* | 281 | /* |
@@ -311,19 +288,6 @@ static void shaper_kick(struct shaper *shaper) | |||
311 | struct sk_buff *skb; | 288 | struct sk_buff *skb; |
312 | 289 | ||
313 | /* | 290 | /* |
314 | * Shaper unlock will kick | ||
315 | */ | ||
316 | |||
317 | if (test_and_set_bit(0, &shaper->locked)) | ||
318 | { | ||
319 | if(sh_debug) | ||
320 | printk("Shaper locked.\n"); | ||
321 | mod_timer(&shaper->timer, jiffies); | ||
322 | return; | ||
323 | } | ||
324 | |||
325 | |||
326 | /* | ||
327 | * Walk the list (may be empty) | 291 | * Walk the list (may be empty) |
328 | */ | 292 | */ |
329 | 293 | ||
@@ -364,8 +328,6 @@ static void shaper_kick(struct shaper *shaper) | |||
364 | 328 | ||
365 | if(skb!=NULL) | 329 | if(skb!=NULL) |
366 | mod_timer(&shaper->timer, SHAPERCB(skb)->shapeclock); | 330 | mod_timer(&shaper->timer, SHAPERCB(skb)->shapeclock); |
367 | |||
368 | clear_bit(0, &shaper->locked); | ||
369 | } | 331 | } |
370 | 332 | ||
371 | 333 | ||
@@ -376,14 +338,12 @@ static void shaper_kick(struct shaper *shaper) | |||
376 | static void shaper_flush(struct shaper *shaper) | 338 | static void shaper_flush(struct shaper *shaper) |
377 | { | 339 | { |
378 | struct sk_buff *skb; | 340 | struct sk_buff *skb; |
379 | if(!shaper_lock(shaper)) | 341 | |
380 | { | 342 | down(&shaper->sem); |
381 | printk(KERN_ERR "shaper: shaper_flush() called by an irq!\n"); | ||
382 | return; | ||
383 | } | ||
384 | while((skb=skb_dequeue(&shaper->sendq))!=NULL) | 343 | while((skb=skb_dequeue(&shaper->sendq))!=NULL) |
385 | dev_kfree_skb(skb); | 344 | dev_kfree_skb(skb); |
386 | shaper_unlock(shaper); | 345 | shaper_kick(shaper); |
346 | up(&shaper->sem); | ||
387 | } | 347 | } |
388 | 348 | ||
389 | /* | 349 | /* |
@@ -426,13 +386,6 @@ static int shaper_close(struct net_device *dev) | |||
426 | * ARP and other resolutions and not before. | 386 | * ARP and other resolutions and not before. |
427 | */ | 387 | */ |
428 | 388 | ||
429 | |||
430 | static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
431 | { | ||
432 | struct shaper *sh=dev->priv; | ||
433 | return shaper_qframe(sh, skb); | ||
434 | } | ||
435 | |||
436 | static struct net_device_stats *shaper_get_stats(struct net_device *dev) | 389 | static struct net_device_stats *shaper_get_stats(struct net_device *dev) |
437 | { | 390 | { |
438 | struct shaper *sh=dev->priv; | 391 | struct shaper *sh=dev->priv; |
@@ -623,7 +576,6 @@ static void shaper_init_priv(struct net_device *dev) | |||
623 | init_timer(&sh->timer); | 576 | init_timer(&sh->timer); |
624 | sh->timer.function=shaper_timer; | 577 | sh->timer.function=shaper_timer; |
625 | sh->timer.data=(unsigned long)sh; | 578 | sh->timer.data=(unsigned long)sh; |
626 | init_waitqueue_head(&sh->wait_queue); | ||
627 | } | 579 | } |
628 | 580 | ||
629 | /* | 581 | /* |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index f10dd74988c4..fc9b5cd957aa 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -133,6 +133,8 @@ | |||
133 | /* number of ETHTOOL_GSTATS u64's */ | 133 | /* number of ETHTOOL_GSTATS u64's */ |
134 | #define TG3_NUM_STATS (sizeof(struct tg3_ethtool_stats)/sizeof(u64)) | 134 | #define TG3_NUM_STATS (sizeof(struct tg3_ethtool_stats)/sizeof(u64)) |
135 | 135 | ||
136 | #define TG3_NUM_TEST 6 | ||
137 | |||
136 | static char version[] __devinitdata = | 138 | static char version[] __devinitdata = |
137 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; | 139 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; |
138 | 140 | ||
@@ -316,6 +318,17 @@ static struct { | |||
316 | { "nic_tx_threshold_hit" } | 318 | { "nic_tx_threshold_hit" } |
317 | }; | 319 | }; |
318 | 320 | ||
321 | static struct { | ||
322 | const char string[ETH_GSTRING_LEN]; | ||
323 | } ethtool_test_keys[TG3_NUM_TEST] = { | ||
324 | { "nvram test (online) " }, | ||
325 | { "link test (online) " }, | ||
326 | { "register test (offline)" }, | ||
327 | { "memory test (offline)" }, | ||
328 | { "loopback test (offline)" }, | ||
329 | { "interrupt test (offline)" }, | ||
330 | }; | ||
331 | |||
319 | static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) | 332 | static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) |
320 | { | 333 | { |
321 | if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) { | 334 | if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) { |
@@ -3070,7 +3083,7 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id, | |||
3070 | } | 3083 | } |
3071 | 3084 | ||
3072 | static int tg3_init_hw(struct tg3 *); | 3085 | static int tg3_init_hw(struct tg3 *); |
3073 | static int tg3_halt(struct tg3 *, int); | 3086 | static int tg3_halt(struct tg3 *, int, int); |
3074 | 3087 | ||
3075 | #ifdef CONFIG_NET_POLL_CONTROLLER | 3088 | #ifdef CONFIG_NET_POLL_CONTROLLER |
3076 | static void tg3_poll_controller(struct net_device *dev) | 3089 | static void tg3_poll_controller(struct net_device *dev) |
@@ -3094,7 +3107,7 @@ static void tg3_reset_task(void *_data) | |||
3094 | restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER; | 3107 | restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER; |
3095 | tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER; | 3108 | tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER; |
3096 | 3109 | ||
3097 | tg3_halt(tp, 0); | 3110 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 0); |
3098 | tg3_init_hw(tp); | 3111 | tg3_init_hw(tp); |
3099 | 3112 | ||
3100 | tg3_netif_start(tp); | 3113 | tg3_netif_start(tp); |
@@ -3440,7 +3453,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) | |||
3440 | spin_lock_irq(&tp->lock); | 3453 | spin_lock_irq(&tp->lock); |
3441 | spin_lock(&tp->tx_lock); | 3454 | spin_lock(&tp->tx_lock); |
3442 | 3455 | ||
3443 | tg3_halt(tp, 1); | 3456 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
3444 | 3457 | ||
3445 | tg3_set_mtu(dev, tp, new_mtu); | 3458 | tg3_set_mtu(dev, tp, new_mtu); |
3446 | 3459 | ||
@@ -4131,19 +4144,19 @@ static void tg3_stop_fw(struct tg3 *tp) | |||
4131 | } | 4144 | } |
4132 | 4145 | ||
4133 | /* tp->lock is held. */ | 4146 | /* tp->lock is held. */ |
4134 | static int tg3_halt(struct tg3 *tp, int silent) | 4147 | static int tg3_halt(struct tg3 *tp, int kind, int silent) |
4135 | { | 4148 | { |
4136 | int err; | 4149 | int err; |
4137 | 4150 | ||
4138 | tg3_stop_fw(tp); | 4151 | tg3_stop_fw(tp); |
4139 | 4152 | ||
4140 | tg3_write_sig_pre_reset(tp, RESET_KIND_SHUTDOWN); | 4153 | tg3_write_sig_pre_reset(tp, kind); |
4141 | 4154 | ||
4142 | tg3_abort_hw(tp, silent); | 4155 | tg3_abort_hw(tp, silent); |
4143 | err = tg3_chip_reset(tp); | 4156 | err = tg3_chip_reset(tp); |
4144 | 4157 | ||
4145 | tg3_write_sig_legacy(tp, RESET_KIND_SHUTDOWN); | 4158 | tg3_write_sig_legacy(tp, kind); |
4146 | tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); | 4159 | tg3_write_sig_post_reset(tp, kind); |
4147 | 4160 | ||
4148 | if (err) | 4161 | if (err) |
4149 | return err; | 4162 | return err; |
@@ -4357,7 +4370,12 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b | |||
4357 | */ | 4370 | */ |
4358 | tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG; | 4371 | tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG; |
4359 | 4372 | ||
4373 | /* It is possible that bootcode is still loading at this point. | ||
4374 | * Get the nvram lock first before halting the cpu. | ||
4375 | */ | ||
4376 | tg3_nvram_lock(tp); | ||
4360 | err = tg3_halt_cpu(tp, cpu_base); | 4377 | err = tg3_halt_cpu(tp, cpu_base); |
4378 | tg3_nvram_unlock(tp); | ||
4361 | if (err) | 4379 | if (err) |
4362 | goto out; | 4380 | goto out; |
4363 | 4381 | ||
@@ -5881,6 +5899,9 @@ static int tg3_test_interrupt(struct tg3 *tp) | |||
5881 | int err, i; | 5899 | int err, i; |
5882 | u32 int_mbox = 0; | 5900 | u32 int_mbox = 0; |
5883 | 5901 | ||
5902 | if (!netif_running(dev)) | ||
5903 | return -ENODEV; | ||
5904 | |||
5884 | tg3_disable_ints(tp); | 5905 | tg3_disable_ints(tp); |
5885 | 5906 | ||
5886 | free_irq(tp->pdev->irq, dev); | 5907 | free_irq(tp->pdev->irq, dev); |
@@ -5984,7 +6005,7 @@ static int tg3_test_msi(struct tg3 *tp) | |||
5984 | spin_lock_irq(&tp->lock); | 6005 | spin_lock_irq(&tp->lock); |
5985 | spin_lock(&tp->tx_lock); | 6006 | spin_lock(&tp->tx_lock); |
5986 | 6007 | ||
5987 | tg3_halt(tp, 1); | 6008 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
5988 | err = tg3_init_hw(tp); | 6009 | err = tg3_init_hw(tp); |
5989 | 6010 | ||
5990 | spin_unlock(&tp->tx_lock); | 6011 | spin_unlock(&tp->tx_lock); |
@@ -6060,7 +6081,7 @@ static int tg3_open(struct net_device *dev) | |||
6060 | 6081 | ||
6061 | err = tg3_init_hw(tp); | 6082 | err = tg3_init_hw(tp); |
6062 | if (err) { | 6083 | if (err) { |
6063 | tg3_halt(tp, 1); | 6084 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
6064 | tg3_free_rings(tp); | 6085 | tg3_free_rings(tp); |
6065 | } else { | 6086 | } else { |
6066 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) | 6087 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) |
@@ -6104,7 +6125,7 @@ static int tg3_open(struct net_device *dev) | |||
6104 | pci_disable_msi(tp->pdev); | 6125 | pci_disable_msi(tp->pdev); |
6105 | tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; | 6126 | tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; |
6106 | } | 6127 | } |
6107 | tg3_halt(tp, 1); | 6128 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
6108 | tg3_free_rings(tp); | 6129 | tg3_free_rings(tp); |
6109 | tg3_free_consistent(tp); | 6130 | tg3_free_consistent(tp); |
6110 | 6131 | ||
@@ -6377,7 +6398,7 @@ static int tg3_close(struct net_device *dev) | |||
6377 | 6398 | ||
6378 | tg3_disable_ints(tp); | 6399 | tg3_disable_ints(tp); |
6379 | 6400 | ||
6380 | tg3_halt(tp, 1); | 6401 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
6381 | tg3_free_rings(tp); | 6402 | tg3_free_rings(tp); |
6382 | tp->tg3_flags &= | 6403 | tp->tg3_flags &= |
6383 | ~(TG3_FLAG_INIT_COMPLETE | | 6404 | ~(TG3_FLAG_INIT_COMPLETE | |
@@ -7097,7 +7118,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e | |||
7097 | tp->tx_pending = ering->tx_pending; | 7118 | tp->tx_pending = ering->tx_pending; |
7098 | 7119 | ||
7099 | if (netif_running(dev)) { | 7120 | if (netif_running(dev)) { |
7100 | tg3_halt(tp, 1); | 7121 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
7101 | tg3_init_hw(tp); | 7122 | tg3_init_hw(tp); |
7102 | tg3_netif_start(tp); | 7123 | tg3_netif_start(tp); |
7103 | } | 7124 | } |
@@ -7140,7 +7161,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam | |||
7140 | tp->tg3_flags &= ~TG3_FLAG_TX_PAUSE; | 7161 | tp->tg3_flags &= ~TG3_FLAG_TX_PAUSE; |
7141 | 7162 | ||
7142 | if (netif_running(dev)) { | 7163 | if (netif_running(dev)) { |
7143 | tg3_halt(tp, 1); | 7164 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
7144 | tg3_init_hw(tp); | 7165 | tg3_init_hw(tp); |
7145 | tg3_netif_start(tp); | 7166 | tg3_netif_start(tp); |
7146 | } | 7167 | } |
@@ -7199,12 +7220,20 @@ static int tg3_get_stats_count (struct net_device *dev) | |||
7199 | return TG3_NUM_STATS; | 7220 | return TG3_NUM_STATS; |
7200 | } | 7221 | } |
7201 | 7222 | ||
7223 | static int tg3_get_test_count (struct net_device *dev) | ||
7224 | { | ||
7225 | return TG3_NUM_TEST; | ||
7226 | } | ||
7227 | |||
7202 | static void tg3_get_strings (struct net_device *dev, u32 stringset, u8 *buf) | 7228 | static void tg3_get_strings (struct net_device *dev, u32 stringset, u8 *buf) |
7203 | { | 7229 | { |
7204 | switch (stringset) { | 7230 | switch (stringset) { |
7205 | case ETH_SS_STATS: | 7231 | case ETH_SS_STATS: |
7206 | memcpy(buf, ðtool_stats_keys, sizeof(ethtool_stats_keys)); | 7232 | memcpy(buf, ðtool_stats_keys, sizeof(ethtool_stats_keys)); |
7207 | break; | 7233 | break; |
7234 | case ETH_SS_TEST: | ||
7235 | memcpy(buf, ðtool_test_keys, sizeof(ethtool_test_keys)); | ||
7236 | break; | ||
7208 | default: | 7237 | default: |
7209 | WARN_ON(1); /* we need a WARN() */ | 7238 | WARN_ON(1); /* we need a WARN() */ |
7210 | break; | 7239 | break; |
@@ -7218,6 +7247,516 @@ static void tg3_get_ethtool_stats (struct net_device *dev, | |||
7218 | memcpy(tmp_stats, tg3_get_estats(tp), sizeof(tp->estats)); | 7247 | memcpy(tmp_stats, tg3_get_estats(tp), sizeof(tp->estats)); |
7219 | } | 7248 | } |
7220 | 7249 | ||
7250 | #define NVRAM_TEST_SIZE 0x100 | ||
7251 | |||
7252 | static int tg3_test_nvram(struct tg3 *tp) | ||
7253 | { | ||
7254 | u32 *buf, csum; | ||
7255 | int i, j, err = 0; | ||
7256 | |||
7257 | buf = kmalloc(NVRAM_TEST_SIZE, GFP_KERNEL); | ||
7258 | if (buf == NULL) | ||
7259 | return -ENOMEM; | ||
7260 | |||
7261 | for (i = 0, j = 0; i < NVRAM_TEST_SIZE; i += 4, j++) { | ||
7262 | u32 val; | ||
7263 | |||
7264 | if ((err = tg3_nvram_read(tp, i, &val)) != 0) | ||
7265 | break; | ||
7266 | buf[j] = cpu_to_le32(val); | ||
7267 | } | ||
7268 | if (i < NVRAM_TEST_SIZE) | ||
7269 | goto out; | ||
7270 | |||
7271 | err = -EIO; | ||
7272 | if (cpu_to_be32(buf[0]) != TG3_EEPROM_MAGIC) | ||
7273 | goto out; | ||
7274 | |||
7275 | /* Bootstrap checksum at offset 0x10 */ | ||
7276 | csum = calc_crc((unsigned char *) buf, 0x10); | ||
7277 | if(csum != cpu_to_le32(buf[0x10/4])) | ||
7278 | goto out; | ||
7279 | |||
7280 | /* Manufacturing block starts at offset 0x74, checksum at 0xfc */ | ||
7281 | csum = calc_crc((unsigned char *) &buf[0x74/4], 0x88); | ||
7282 | if (csum != cpu_to_le32(buf[0xfc/4])) | ||
7283 | goto out; | ||
7284 | |||
7285 | err = 0; | ||
7286 | |||
7287 | out: | ||
7288 | kfree(buf); | ||
7289 | return err; | ||
7290 | } | ||
7291 | |||
7292 | #define TG3_SERDES_TIMEOUT_SEC 2 | ||
7293 | #define TG3_COPPER_TIMEOUT_SEC 6 | ||
7294 | |||
7295 | static int tg3_test_link(struct tg3 *tp) | ||
7296 | { | ||
7297 | int i, max; | ||
7298 | |||
7299 | if (!netif_running(tp->dev)) | ||
7300 | return -ENODEV; | ||
7301 | |||
7302 | if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) | ||
7303 | max = TG3_SERDES_TIMEOUT_SEC; | ||
7304 | else | ||
7305 | max = TG3_COPPER_TIMEOUT_SEC; | ||
7306 | |||
7307 | for (i = 0; i < max; i++) { | ||
7308 | if (netif_carrier_ok(tp->dev)) | ||
7309 | return 0; | ||
7310 | |||
7311 | if (msleep_interruptible(1000)) | ||
7312 | break; | ||
7313 | } | ||
7314 | |||
7315 | return -EIO; | ||
7316 | } | ||
7317 | |||
7318 | /* Only test the commonly used registers */ | ||
7319 | static int tg3_test_registers(struct tg3 *tp) | ||
7320 | { | ||
7321 | int i, is_5705; | ||
7322 | u32 offset, read_mask, write_mask, val, save_val, read_val; | ||
7323 | static struct { | ||
7324 | u16 offset; | ||
7325 | u16 flags; | ||
7326 | #define TG3_FL_5705 0x1 | ||
7327 | #define TG3_FL_NOT_5705 0x2 | ||
7328 | #define TG3_FL_NOT_5788 0x4 | ||
7329 | u32 read_mask; | ||
7330 | u32 write_mask; | ||
7331 | } reg_tbl[] = { | ||
7332 | /* MAC Control Registers */ | ||
7333 | { MAC_MODE, TG3_FL_NOT_5705, | ||
7334 | 0x00000000, 0x00ef6f8c }, | ||
7335 | { MAC_MODE, TG3_FL_5705, | ||
7336 | 0x00000000, 0x01ef6b8c }, | ||
7337 | { MAC_STATUS, TG3_FL_NOT_5705, | ||
7338 | 0x03800107, 0x00000000 }, | ||
7339 | { MAC_STATUS, TG3_FL_5705, | ||
7340 | 0x03800100, 0x00000000 }, | ||
7341 | { MAC_ADDR_0_HIGH, 0x0000, | ||
7342 | 0x00000000, 0x0000ffff }, | ||
7343 | { MAC_ADDR_0_LOW, 0x0000, | ||
7344 | 0x00000000, 0xffffffff }, | ||
7345 | { MAC_RX_MTU_SIZE, 0x0000, | ||
7346 | 0x00000000, 0x0000ffff }, | ||
7347 | { MAC_TX_MODE, 0x0000, | ||
7348 | 0x00000000, 0x00000070 }, | ||
7349 | { MAC_TX_LENGTHS, 0x0000, | ||
7350 | 0x00000000, 0x00003fff }, | ||
7351 | { MAC_RX_MODE, TG3_FL_NOT_5705, | ||
7352 | 0x00000000, 0x000007fc }, | ||
7353 | { MAC_RX_MODE, TG3_FL_5705, | ||
7354 | 0x00000000, 0x000007dc }, | ||
7355 | { MAC_HASH_REG_0, 0x0000, | ||
7356 | 0x00000000, 0xffffffff }, | ||
7357 | { MAC_HASH_REG_1, 0x0000, | ||
7358 | 0x00000000, 0xffffffff }, | ||
7359 | { MAC_HASH_REG_2, 0x0000, | ||
7360 | 0x00000000, 0xffffffff }, | ||
7361 | { MAC_HASH_REG_3, 0x0000, | ||
7362 | 0x00000000, 0xffffffff }, | ||
7363 | |||
7364 | /* Receive Data and Receive BD Initiator Control Registers. */ | ||
7365 | { RCVDBDI_JUMBO_BD+0, TG3_FL_NOT_5705, | ||
7366 | 0x00000000, 0xffffffff }, | ||
7367 | { RCVDBDI_JUMBO_BD+4, TG3_FL_NOT_5705, | ||
7368 | 0x00000000, 0xffffffff }, | ||
7369 | { RCVDBDI_JUMBO_BD+8, TG3_FL_NOT_5705, | ||
7370 | 0x00000000, 0x00000003 }, | ||
7371 | { RCVDBDI_JUMBO_BD+0xc, TG3_FL_NOT_5705, | ||
7372 | 0x00000000, 0xffffffff }, | ||
7373 | { RCVDBDI_STD_BD+0, 0x0000, | ||
7374 | 0x00000000, 0xffffffff }, | ||
7375 | { RCVDBDI_STD_BD+4, 0x0000, | ||
7376 | 0x00000000, 0xffffffff }, | ||
7377 | { RCVDBDI_STD_BD+8, 0x0000, | ||
7378 | 0x00000000, 0xffff0002 }, | ||
7379 | { RCVDBDI_STD_BD+0xc, 0x0000, | ||
7380 | 0x00000000, 0xffffffff }, | ||
7381 | |||
7382 | /* Receive BD Initiator Control Registers. */ | ||
7383 | { RCVBDI_STD_THRESH, TG3_FL_NOT_5705, | ||
7384 | 0x00000000, 0xffffffff }, | ||
7385 | { RCVBDI_STD_THRESH, TG3_FL_5705, | ||
7386 | 0x00000000, 0x000003ff }, | ||
7387 | { RCVBDI_JUMBO_THRESH, TG3_FL_NOT_5705, | ||
7388 | 0x00000000, 0xffffffff }, | ||
7389 | |||
7390 | /* Host Coalescing Control Registers. */ | ||
7391 | { HOSTCC_MODE, TG3_FL_NOT_5705, | ||
7392 | 0x00000000, 0x00000004 }, | ||
7393 | { HOSTCC_MODE, TG3_FL_5705, | ||
7394 | 0x00000000, 0x000000f6 }, | ||
7395 | { HOSTCC_RXCOL_TICKS, TG3_FL_NOT_5705, | ||
7396 | 0x00000000, 0xffffffff }, | ||
7397 | { HOSTCC_RXCOL_TICKS, TG3_FL_5705, | ||
7398 | 0x00000000, 0x000003ff }, | ||
7399 | { HOSTCC_TXCOL_TICKS, TG3_FL_NOT_5705, | ||
7400 | 0x00000000, 0xffffffff }, | ||
7401 | { HOSTCC_TXCOL_TICKS, TG3_FL_5705, | ||
7402 | 0x00000000, 0x000003ff }, | ||
7403 | { HOSTCC_RXMAX_FRAMES, TG3_FL_NOT_5705, | ||
7404 | 0x00000000, 0xffffffff }, | ||
7405 | { HOSTCC_RXMAX_FRAMES, TG3_FL_5705 | TG3_FL_NOT_5788, | ||
7406 | 0x00000000, 0x000000ff }, | ||
7407 | { HOSTCC_TXMAX_FRAMES, TG3_FL_NOT_5705, | ||
7408 | 0x00000000, 0xffffffff }, | ||
7409 | { HOSTCC_TXMAX_FRAMES, TG3_FL_5705 | TG3_FL_NOT_5788, | ||
7410 | 0x00000000, 0x000000ff }, | ||
7411 | { HOSTCC_RXCOAL_TICK_INT, TG3_FL_NOT_5705, | ||
7412 | 0x00000000, 0xffffffff }, | ||
7413 | { HOSTCC_TXCOAL_TICK_INT, TG3_FL_NOT_5705, | ||
7414 | 0x00000000, 0xffffffff }, | ||
7415 | { HOSTCC_RXCOAL_MAXF_INT, TG3_FL_NOT_5705, | ||
7416 | 0x00000000, 0xffffffff }, | ||
7417 | { HOSTCC_RXCOAL_MAXF_INT, TG3_FL_5705 | TG3_FL_NOT_5788, | ||
7418 | 0x00000000, 0x000000ff }, | ||
7419 | { HOSTCC_TXCOAL_MAXF_INT, TG3_FL_NOT_5705, | ||
7420 | 0x00000000, 0xffffffff }, | ||
7421 | { HOSTCC_TXCOAL_MAXF_INT, TG3_FL_5705 | TG3_FL_NOT_5788, | ||
7422 | 0x00000000, 0x000000ff }, | ||
7423 | { HOSTCC_STAT_COAL_TICKS, TG3_FL_NOT_5705, | ||
7424 | 0x00000000, 0xffffffff }, | ||
7425 | { HOSTCC_STATS_BLK_HOST_ADDR, TG3_FL_NOT_5705, | ||
7426 | 0x00000000, 0xffffffff }, | ||
7427 | { HOSTCC_STATS_BLK_HOST_ADDR+4, TG3_FL_NOT_5705, | ||
7428 | 0x00000000, 0xffffffff }, | ||
7429 | { HOSTCC_STATUS_BLK_HOST_ADDR, 0x0000, | ||
7430 | 0x00000000, 0xffffffff }, | ||
7431 | { HOSTCC_STATUS_BLK_HOST_ADDR+4, 0x0000, | ||
7432 | 0x00000000, 0xffffffff }, | ||
7433 | { HOSTCC_STATS_BLK_NIC_ADDR, 0x0000, | ||
7434 | 0xffffffff, 0x00000000 }, | ||
7435 | { HOSTCC_STATUS_BLK_NIC_ADDR, 0x0000, | ||
7436 | 0xffffffff, 0x00000000 }, | ||
7437 | |||
7438 | /* Buffer Manager Control Registers. */ | ||
7439 | { BUFMGR_MB_POOL_ADDR, 0x0000, | ||
7440 | 0x00000000, 0x007fff80 }, | ||
7441 | { BUFMGR_MB_POOL_SIZE, 0x0000, | ||
7442 | 0x00000000, 0x007fffff }, | ||
7443 | { BUFMGR_MB_RDMA_LOW_WATER, 0x0000, | ||
7444 | 0x00000000, 0x0000003f }, | ||
7445 | { BUFMGR_MB_MACRX_LOW_WATER, 0x0000, | ||
7446 | 0x00000000, 0x000001ff }, | ||
7447 | { BUFMGR_MB_HIGH_WATER, 0x0000, | ||
7448 | 0x00000000, 0x000001ff }, | ||
7449 | { BUFMGR_DMA_DESC_POOL_ADDR, TG3_FL_NOT_5705, | ||
7450 | 0xffffffff, 0x00000000 }, | ||
7451 | { BUFMGR_DMA_DESC_POOL_SIZE, TG3_FL_NOT_5705, | ||
7452 | 0xffffffff, 0x00000000 }, | ||
7453 | |||
7454 | /* Mailbox Registers */ | ||
7455 | { GRCMBOX_RCVSTD_PROD_IDX+4, 0x0000, | ||
7456 | 0x00000000, 0x000001ff }, | ||
7457 | { GRCMBOX_RCVJUMBO_PROD_IDX+4, TG3_FL_NOT_5705, | ||
7458 | 0x00000000, 0x000001ff }, | ||
7459 | { GRCMBOX_RCVRET_CON_IDX_0+4, 0x0000, | ||
7460 | 0x00000000, 0x000007ff }, | ||
7461 | { GRCMBOX_SNDHOST_PROD_IDX_0+4, 0x0000, | ||
7462 | 0x00000000, 0x000001ff }, | ||
7463 | |||
7464 | { 0xffff, 0x0000, 0x00000000, 0x00000000 }, | ||
7465 | }; | ||
7466 | |||
7467 | if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) | ||
7468 | is_5705 = 1; | ||
7469 | else | ||
7470 | is_5705 = 0; | ||
7471 | |||
7472 | for (i = 0; reg_tbl[i].offset != 0xffff; i++) { | ||
7473 | if (is_5705 && (reg_tbl[i].flags & TG3_FL_NOT_5705)) | ||
7474 | continue; | ||
7475 | |||
7476 | if (!is_5705 && (reg_tbl[i].flags & TG3_FL_5705)) | ||
7477 | continue; | ||
7478 | |||
7479 | if ((tp->tg3_flags2 & TG3_FLG2_IS_5788) && | ||
7480 | (reg_tbl[i].flags & TG3_FL_NOT_5788)) | ||
7481 | continue; | ||
7482 | |||
7483 | offset = (u32) reg_tbl[i].offset; | ||
7484 | read_mask = reg_tbl[i].read_mask; | ||
7485 | write_mask = reg_tbl[i].write_mask; | ||
7486 | |||
7487 | /* Save the original register content */ | ||
7488 | save_val = tr32(offset); | ||
7489 | |||
7490 | /* Determine the read-only value. */ | ||
7491 | read_val = save_val & read_mask; | ||
7492 | |||
7493 | /* Write zero to the register, then make sure the read-only bits | ||
7494 | * are not changed and the read/write bits are all zeros. | ||
7495 | */ | ||
7496 | tw32(offset, 0); | ||
7497 | |||
7498 | val = tr32(offset); | ||
7499 | |||
7500 | /* Test the read-only and read/write bits. */ | ||
7501 | if (((val & read_mask) != read_val) || (val & write_mask)) | ||
7502 | goto out; | ||
7503 | |||
7504 | /* Write ones to all the bits defined by RdMask and WrMask, then | ||
7505 | * make sure the read-only bits are not changed and the | ||
7506 | * read/write bits are all ones. | ||
7507 | */ | ||
7508 | tw32(offset, read_mask | write_mask); | ||
7509 | |||
7510 | val = tr32(offset); | ||
7511 | |||
7512 | /* Test the read-only bits. */ | ||
7513 | if ((val & read_mask) != read_val) | ||
7514 | goto out; | ||
7515 | |||
7516 | /* Test the read/write bits. */ | ||
7517 | if ((val & write_mask) != write_mask) | ||
7518 | goto out; | ||
7519 | |||
7520 | tw32(offset, save_val); | ||
7521 | } | ||
7522 | |||
7523 | return 0; | ||
7524 | |||
7525 | out: | ||
7526 | printk(KERN_ERR PFX "Register test failed at offset %x\n", offset); | ||
7527 | tw32(offset, save_val); | ||
7528 | return -EIO; | ||
7529 | } | ||
7530 | |||
7531 | static int tg3_do_mem_test(struct tg3 *tp, u32 offset, u32 len) | ||
7532 | { | ||
7533 | static u32 test_pattern[] = { 0x00000000, 0xffffffff, 0xaa55a55a }; | ||
7534 | int i; | ||
7535 | u32 j; | ||
7536 | |||
7537 | for (i = 0; i < sizeof(test_pattern)/sizeof(u32); i++) { | ||
7538 | for (j = 0; j < len; j += 4) { | ||
7539 | u32 val; | ||
7540 | |||
7541 | tg3_write_mem(tp, offset + j, test_pattern[i]); | ||
7542 | tg3_read_mem(tp, offset + j, &val); | ||
7543 | if (val != test_pattern[i]) | ||
7544 | return -EIO; | ||
7545 | } | ||
7546 | } | ||
7547 | return 0; | ||
7548 | } | ||
7549 | |||
7550 | static int tg3_test_memory(struct tg3 *tp) | ||
7551 | { | ||
7552 | static struct mem_entry { | ||
7553 | u32 offset; | ||
7554 | u32 len; | ||
7555 | } mem_tbl_570x[] = { | ||
7556 | { 0x00000000, 0x01000}, | ||
7557 | { 0x00002000, 0x1c000}, | ||
7558 | { 0xffffffff, 0x00000} | ||
7559 | }, mem_tbl_5705[] = { | ||
7560 | { 0x00000100, 0x0000c}, | ||
7561 | { 0x00000200, 0x00008}, | ||
7562 | { 0x00000b50, 0x00400}, | ||
7563 | { 0x00004000, 0x00800}, | ||
7564 | { 0x00006000, 0x01000}, | ||
7565 | { 0x00008000, 0x02000}, | ||
7566 | { 0x00010000, 0x0e000}, | ||
7567 | { 0xffffffff, 0x00000} | ||
7568 | }; | ||
7569 | struct mem_entry *mem_tbl; | ||
7570 | int err = 0; | ||
7571 | int i; | ||
7572 | |||
7573 | if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) | ||
7574 | mem_tbl = mem_tbl_5705; | ||
7575 | else | ||
7576 | mem_tbl = mem_tbl_570x; | ||
7577 | |||
7578 | for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) { | ||
7579 | if ((err = tg3_do_mem_test(tp, mem_tbl[i].offset, | ||
7580 | mem_tbl[i].len)) != 0) | ||
7581 | break; | ||
7582 | } | ||
7583 | |||
7584 | return err; | ||
7585 | } | ||
7586 | |||
7587 | static int tg3_test_loopback(struct tg3 *tp) | ||
7588 | { | ||
7589 | u32 mac_mode, send_idx, rx_start_idx, rx_idx, tx_idx, opaque_key; | ||
7590 | u32 desc_idx; | ||
7591 | struct sk_buff *skb, *rx_skb; | ||
7592 | u8 *tx_data; | ||
7593 | dma_addr_t map; | ||
7594 | int num_pkts, tx_len, rx_len, i, err; | ||
7595 | struct tg3_rx_buffer_desc *desc; | ||
7596 | |||
7597 | if (!netif_running(tp->dev)) | ||
7598 | return -ENODEV; | ||
7599 | |||
7600 | err = -EIO; | ||
7601 | |||
7602 | tg3_abort_hw(tp, 1); | ||
7603 | |||
7604 | /* Clearing this flag to keep interrupts disabled */ | ||
7605 | tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; | ||
7606 | tg3_reset_hw(tp); | ||
7607 | |||
7608 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | | ||
7609 | MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY | | ||
7610 | MAC_MODE_PORT_MODE_GMII; | ||
7611 | tw32(MAC_MODE, mac_mode); | ||
7612 | |||
7613 | tx_len = 1514; | ||
7614 | skb = dev_alloc_skb(tx_len); | ||
7615 | tx_data = skb_put(skb, tx_len); | ||
7616 | memcpy(tx_data, tp->dev->dev_addr, 6); | ||
7617 | memset(tx_data + 6, 0x0, 8); | ||
7618 | |||
7619 | tw32(MAC_RX_MTU_SIZE, tx_len + 4); | ||
7620 | |||
7621 | for (i = 14; i < tx_len; i++) | ||
7622 | tx_data[i] = (u8) (i & 0xff); | ||
7623 | |||
7624 | map = pci_map_single(tp->pdev, skb->data, tx_len, PCI_DMA_TODEVICE); | ||
7625 | |||
7626 | tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | | ||
7627 | HOSTCC_MODE_NOW); | ||
7628 | |||
7629 | udelay(10); | ||
7630 | |||
7631 | rx_start_idx = tp->hw_status->idx[0].rx_producer; | ||
7632 | |||
7633 | send_idx = 0; | ||
7634 | num_pkts = 0; | ||
7635 | |||
7636 | tg3_set_txd(tp, send_idx, map, tx_len, 0, 1); | ||
7637 | |||
7638 | send_idx++; | ||
7639 | num_pkts++; | ||
7640 | |||
7641 | tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, send_idx); | ||
7642 | tr32(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW); | ||
7643 | |||
7644 | udelay(10); | ||
7645 | |||
7646 | for (i = 0; i < 10; i++) { | ||
7647 | tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | | ||
7648 | HOSTCC_MODE_NOW); | ||
7649 | |||
7650 | udelay(10); | ||
7651 | |||
7652 | tx_idx = tp->hw_status->idx[0].tx_consumer; | ||
7653 | rx_idx = tp->hw_status->idx[0].rx_producer; | ||
7654 | if ((tx_idx == send_idx) && | ||
7655 | (rx_idx == (rx_start_idx + num_pkts))) | ||
7656 | break; | ||
7657 | } | ||
7658 | |||
7659 | pci_unmap_single(tp->pdev, map, tx_len, PCI_DMA_TODEVICE); | ||
7660 | dev_kfree_skb(skb); | ||
7661 | |||
7662 | if (tx_idx != send_idx) | ||
7663 | goto out; | ||
7664 | |||
7665 | if (rx_idx != rx_start_idx + num_pkts) | ||
7666 | goto out; | ||
7667 | |||
7668 | desc = &tp->rx_rcb[rx_start_idx]; | ||
7669 | desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK; | ||
7670 | opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK; | ||
7671 | if (opaque_key != RXD_OPAQUE_RING_STD) | ||
7672 | goto out; | ||
7673 | |||
7674 | if ((desc->err_vlan & RXD_ERR_MASK) != 0 && | ||
7675 | (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII)) | ||
7676 | goto out; | ||
7677 | |||
7678 | rx_len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - 4; | ||
7679 | if (rx_len != tx_len) | ||
7680 | goto out; | ||
7681 | |||
7682 | rx_skb = tp->rx_std_buffers[desc_idx].skb; | ||
7683 | |||
7684 | map = pci_unmap_addr(&tp->rx_std_buffers[desc_idx], mapping); | ||
7685 | pci_dma_sync_single_for_cpu(tp->pdev, map, rx_len, PCI_DMA_FROMDEVICE); | ||
7686 | |||
7687 | for (i = 14; i < tx_len; i++) { | ||
7688 | if (*(rx_skb->data + i) != (u8) (i & 0xff)) | ||
7689 | goto out; | ||
7690 | } | ||
7691 | err = 0; | ||
7692 | |||
7693 | /* tg3_free_rings will unmap and free the rx_skb */ | ||
7694 | out: | ||
7695 | return err; | ||
7696 | } | ||
7697 | |||
7698 | static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, | ||
7699 | u64 *data) | ||
7700 | { | ||
7701 | struct tg3 *tp = netdev_priv(dev); | ||
7702 | |||
7703 | memset(data, 0, sizeof(u64) * TG3_NUM_TEST); | ||
7704 | |||
7705 | if (tg3_test_nvram(tp) != 0) { | ||
7706 | etest->flags |= ETH_TEST_FL_FAILED; | ||
7707 | data[0] = 1; | ||
7708 | } | ||
7709 | if (tg3_test_link(tp) != 0) { | ||
7710 | etest->flags |= ETH_TEST_FL_FAILED; | ||
7711 | data[1] = 1; | ||
7712 | } | ||
7713 | if (etest->flags & ETH_TEST_FL_OFFLINE) { | ||
7714 | if (netif_running(dev)) | ||
7715 | tg3_netif_stop(tp); | ||
7716 | |||
7717 | spin_lock_irq(&tp->lock); | ||
7718 | spin_lock(&tp->tx_lock); | ||
7719 | |||
7720 | tg3_halt(tp, RESET_KIND_SUSPEND, 1); | ||
7721 | tg3_nvram_lock(tp); | ||
7722 | tg3_halt_cpu(tp, RX_CPU_BASE); | ||
7723 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) | ||
7724 | tg3_halt_cpu(tp, TX_CPU_BASE); | ||
7725 | tg3_nvram_unlock(tp); | ||
7726 | |||
7727 | if (tg3_test_registers(tp) != 0) { | ||
7728 | etest->flags |= ETH_TEST_FL_FAILED; | ||
7729 | data[2] = 1; | ||
7730 | } | ||
7731 | if (tg3_test_memory(tp) != 0) { | ||
7732 | etest->flags |= ETH_TEST_FL_FAILED; | ||
7733 | data[3] = 1; | ||
7734 | } | ||
7735 | if (tg3_test_loopback(tp) != 0) { | ||
7736 | etest->flags |= ETH_TEST_FL_FAILED; | ||
7737 | data[4] = 1; | ||
7738 | } | ||
7739 | |||
7740 | spin_unlock(&tp->tx_lock); | ||
7741 | spin_unlock_irq(&tp->lock); | ||
7742 | if (tg3_test_interrupt(tp) != 0) { | ||
7743 | etest->flags |= ETH_TEST_FL_FAILED; | ||
7744 | data[5] = 1; | ||
7745 | } | ||
7746 | spin_lock_irq(&tp->lock); | ||
7747 | spin_lock(&tp->tx_lock); | ||
7748 | |||
7749 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | ||
7750 | if (netif_running(dev)) { | ||
7751 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; | ||
7752 | tg3_init_hw(tp); | ||
7753 | tg3_netif_start(tp); | ||
7754 | } | ||
7755 | spin_unlock(&tp->tx_lock); | ||
7756 | spin_unlock_irq(&tp->lock); | ||
7757 | } | ||
7758 | } | ||
7759 | |||
7221 | static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 7760 | static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
7222 | { | 7761 | { |
7223 | struct mii_ioctl_data *data = if_mii(ifr); | 7762 | struct mii_ioctl_data *data = if_mii(ifr); |
@@ -7331,6 +7870,8 @@ static struct ethtool_ops tg3_ethtool_ops = { | |||
7331 | .get_tso = ethtool_op_get_tso, | 7870 | .get_tso = ethtool_op_get_tso, |
7332 | .set_tso = tg3_set_tso, | 7871 | .set_tso = tg3_set_tso, |
7333 | #endif | 7872 | #endif |
7873 | .self_test_count = tg3_get_test_count, | ||
7874 | .self_test = tg3_self_test, | ||
7334 | .get_strings = tg3_get_strings, | 7875 | .get_strings = tg3_get_strings, |
7335 | .get_stats_count = tg3_get_stats_count, | 7876 | .get_stats_count = tg3_get_stats_count, |
7336 | .get_ethtool_stats = tg3_get_ethtool_stats, | 7877 | .get_ethtool_stats = tg3_get_ethtool_stats, |
@@ -9478,7 +10019,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
9478 | (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { | 10019 | (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { |
9479 | pci_save_state(tp->pdev); | 10020 | pci_save_state(tp->pdev); |
9480 | tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); | 10021 | tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); |
9481 | tg3_halt(tp, 1); | 10022 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
9482 | } | 10023 | } |
9483 | 10024 | ||
9484 | err = tg3_test_dma(tp); | 10025 | err = tg3_test_dma(tp); |
@@ -9605,7 +10146,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) | |||
9605 | 10146 | ||
9606 | spin_lock_irq(&tp->lock); | 10147 | spin_lock_irq(&tp->lock); |
9607 | spin_lock(&tp->tx_lock); | 10148 | spin_lock(&tp->tx_lock); |
9608 | tg3_halt(tp, 1); | 10149 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
9609 | spin_unlock(&tp->tx_lock); | 10150 | spin_unlock(&tp->tx_lock); |
9610 | spin_unlock_irq(&tp->lock); | 10151 | spin_unlock_irq(&tp->lock); |
9611 | 10152 | ||
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c index 7f450b51a6cb..a5d6891c9d4c 100644 --- a/drivers/net/wan/hdlc_fr.c +++ b/drivers/net/wan/hdlc_fr.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Generic HDLC support routines for Linux | 2 | * Generic HDLC support routines for Linux |
3 | * Frame Relay support | 3 | * Frame Relay support |
4 | * | 4 | * |
5 | * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl> | 5 | * Copyright (C) 1999 - 2005 Krzysztof Halasa <khc@pm.waw.pl> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of version 2 of the GNU General Public License | 8 | * under the terms of version 2 of the GNU General Public License |
@@ -27,6 +27,10 @@ | |||
27 | active = open and "link reliable" | 27 | active = open and "link reliable" |
28 | exist = new = not used | 28 | exist = new = not used |
29 | 29 | ||
30 | CCITT LMI: ITU-T Q.933 Annex A | ||
31 | ANSI LMI: ANSI T1.617 Annex D | ||
32 | CISCO LMI: the original, aka "Gang of Four" LMI | ||
33 | |||
30 | */ | 34 | */ |
31 | 35 | ||
32 | #include <linux/module.h> | 36 | #include <linux/module.h> |
@@ -49,45 +53,41 @@ | |||
49 | #undef DEBUG_ECN | 53 | #undef DEBUG_ECN |
50 | #undef DEBUG_LINK | 54 | #undef DEBUG_LINK |
51 | 55 | ||
52 | #define MAXLEN_LMISTAT 20 /* max size of status enquiry frame */ | 56 | #define FR_UI 0x03 |
53 | 57 | #define FR_PAD 0x00 | |
54 | #define PVC_STATE_NEW 0x01 | 58 | |
55 | #define PVC_STATE_ACTIVE 0x02 | 59 | #define NLPID_IP 0xCC |
56 | #define PVC_STATE_FECN 0x08 /* FECN condition */ | 60 | #define NLPID_IPV6 0x8E |
57 | #define PVC_STATE_BECN 0x10 /* BECN condition */ | 61 | #define NLPID_SNAP 0x80 |
58 | 62 | #define NLPID_PAD 0x00 | |
59 | 63 | #define NLPID_CCITT_ANSI_LMI 0x08 | |
60 | #define FR_UI 0x03 | 64 | #define NLPID_CISCO_LMI 0x09 |
61 | #define FR_PAD 0x00 | 65 | |
62 | 66 | ||
63 | #define NLPID_IP 0xCC | 67 | #define LMI_CCITT_ANSI_DLCI 0 /* LMI DLCI */ |
64 | #define NLPID_IPV6 0x8E | 68 | #define LMI_CISCO_DLCI 1023 |
65 | #define NLPID_SNAP 0x80 | 69 | |
66 | #define NLPID_PAD 0x00 | 70 | #define LMI_CALLREF 0x00 /* Call Reference */ |
67 | #define NLPID_Q933 0x08 | 71 | #define LMI_ANSI_LOCKSHIFT 0x95 /* ANSI locking shift */ |
68 | 72 | #define LMI_ANSI_CISCO_REPTYPE 0x01 /* report type */ | |
69 | 73 | #define LMI_CCITT_REPTYPE 0x51 | |
70 | #define LMI_DLCI 0 /* LMI DLCI */ | 74 | #define LMI_ANSI_CISCO_ALIVE 0x03 /* keep alive */ |
71 | #define LMI_PROTO 0x08 | 75 | #define LMI_CCITT_ALIVE 0x53 |
72 | #define LMI_CALLREF 0x00 /* Call Reference */ | 76 | #define LMI_ANSI_CISCO_PVCSTAT 0x07 /* PVC status */ |
73 | #define LMI_ANSI_LOCKSHIFT 0x95 /* ANSI lockshift */ | 77 | #define LMI_CCITT_PVCSTAT 0x57 |
74 | #define LMI_REPTYPE 1 /* report type */ | 78 | |
75 | #define LMI_CCITT_REPTYPE 0x51 | 79 | #define LMI_FULLREP 0x00 /* full report */ |
76 | #define LMI_ALIVE 3 /* keep alive */ | 80 | #define LMI_INTEGRITY 0x01 /* link integrity report */ |
77 | #define LMI_CCITT_ALIVE 0x53 | 81 | #define LMI_SINGLE 0x02 /* single PVC report */ |
78 | #define LMI_PVCSTAT 7 /* pvc status */ | 82 | |
79 | #define LMI_CCITT_PVCSTAT 0x57 | ||
80 | #define LMI_FULLREP 0 /* full report */ | ||
81 | #define LMI_INTEGRITY 1 /* link integrity report */ | ||
82 | #define LMI_SINGLE 2 /* single pvc report */ | ||
83 | #define LMI_STATUS_ENQUIRY 0x75 | 83 | #define LMI_STATUS_ENQUIRY 0x75 |
84 | #define LMI_STATUS 0x7D /* reply */ | 84 | #define LMI_STATUS 0x7D /* reply */ |
85 | 85 | ||
86 | #define LMI_REPT_LEN 1 /* report type element length */ | 86 | #define LMI_REPT_LEN 1 /* report type element length */ |
87 | #define LMI_INTEG_LEN 2 /* link integrity element length */ | 87 | #define LMI_INTEG_LEN 2 /* link integrity element length */ |
88 | 88 | ||
89 | #define LMI_LENGTH 13 /* standard LMI frame length */ | 89 | #define LMI_CCITT_CISCO_LENGTH 13 /* LMI frame lengths */ |
90 | #define LMI_ANSI_LENGTH 14 | 90 | #define LMI_ANSI_LENGTH 14 |
91 | 91 | ||
92 | 92 | ||
93 | typedef struct { | 93 | typedef struct { |
@@ -223,51 +223,34 @@ static inline struct net_device** get_dev_p(pvc_device *pvc, int type) | |||
223 | } | 223 | } |
224 | 224 | ||
225 | 225 | ||
226 | static inline u16 status_to_dlci(u8 *status, int *active, int *new) | ||
227 | { | ||
228 | *new = (status[2] & 0x08) ? 1 : 0; | ||
229 | *active = (status[2] & 0x02) ? 1 : 0; | ||
230 | |||
231 | return ((status[0] & 0x3F) << 4) | ((status[1] & 0x78) >> 3); | ||
232 | } | ||
233 | |||
234 | |||
235 | static inline void dlci_to_status(u16 dlci, u8 *status, int active, int new) | ||
236 | { | ||
237 | status[0] = (dlci >> 4) & 0x3F; | ||
238 | status[1] = ((dlci << 3) & 0x78) | 0x80; | ||
239 | status[2] = 0x80; | ||
240 | |||
241 | if (new) | ||
242 | status[2] |= 0x08; | ||
243 | else if (active) | ||
244 | status[2] |= 0x02; | ||
245 | } | ||
246 | |||
247 | |||
248 | |||
249 | static int fr_hard_header(struct sk_buff **skb_p, u16 dlci) | 226 | static int fr_hard_header(struct sk_buff **skb_p, u16 dlci) |
250 | { | 227 | { |
251 | u16 head_len; | 228 | u16 head_len; |
252 | struct sk_buff *skb = *skb_p; | 229 | struct sk_buff *skb = *skb_p; |
253 | 230 | ||
254 | switch (skb->protocol) { | 231 | switch (skb->protocol) { |
255 | case __constant_ntohs(ETH_P_IP): | 232 | case __constant_ntohs(NLPID_CCITT_ANSI_LMI): |
256 | head_len = 4; | 233 | head_len = 4; |
257 | skb_push(skb, head_len); | 234 | skb_push(skb, head_len); |
258 | skb->data[3] = NLPID_IP; | 235 | skb->data[3] = NLPID_CCITT_ANSI_LMI; |
259 | break; | 236 | break; |
260 | 237 | ||
261 | case __constant_ntohs(ETH_P_IPV6): | 238 | case __constant_ntohs(NLPID_CISCO_LMI): |
262 | head_len = 4; | 239 | head_len = 4; |
263 | skb_push(skb, head_len); | 240 | skb_push(skb, head_len); |
264 | skb->data[3] = NLPID_IPV6; | 241 | skb->data[3] = NLPID_CISCO_LMI; |
265 | break; | 242 | break; |
266 | 243 | ||
267 | case __constant_ntohs(LMI_PROTO): | 244 | case __constant_ntohs(ETH_P_IP): |
245 | head_len = 4; | ||
246 | skb_push(skb, head_len); | ||
247 | skb->data[3] = NLPID_IP; | ||
248 | break; | ||
249 | |||
250 | case __constant_ntohs(ETH_P_IPV6): | ||
268 | head_len = 4; | 251 | head_len = 4; |
269 | skb_push(skb, head_len); | 252 | skb_push(skb, head_len); |
270 | skb->data[3] = LMI_PROTO; | 253 | skb->data[3] = NLPID_IPV6; |
271 | break; | 254 | break; |
272 | 255 | ||
273 | case __constant_ntohs(ETH_P_802_3): | 256 | case __constant_ntohs(ETH_P_802_3): |
@@ -461,13 +444,14 @@ static void fr_lmi_send(struct net_device *dev, int fullrep) | |||
461 | hdlc_device *hdlc = dev_to_hdlc(dev); | 444 | hdlc_device *hdlc = dev_to_hdlc(dev); |
462 | struct sk_buff *skb; | 445 | struct sk_buff *skb; |
463 | pvc_device *pvc = hdlc->state.fr.first_pvc; | 446 | pvc_device *pvc = hdlc->state.fr.first_pvc; |
464 | int len = (hdlc->state.fr.settings.lmi == LMI_ANSI) ? LMI_ANSI_LENGTH | 447 | int lmi = hdlc->state.fr.settings.lmi; |
465 | : LMI_LENGTH; | 448 | int dce = hdlc->state.fr.settings.dce; |
466 | int stat_len = 3; | 449 | int len = lmi == LMI_ANSI ? LMI_ANSI_LENGTH : LMI_CCITT_CISCO_LENGTH; |
450 | int stat_len = (lmi == LMI_CISCO) ? 6 : 3; | ||
467 | u8 *data; | 451 | u8 *data; |
468 | int i = 0; | 452 | int i = 0; |
469 | 453 | ||
470 | if (hdlc->state.fr.settings.dce && fullrep) { | 454 | if (dce && fullrep) { |
471 | len += hdlc->state.fr.dce_pvc_count * (2 + stat_len); | 455 | len += hdlc->state.fr.dce_pvc_count * (2 + stat_len); |
472 | if (len > HDLC_MAX_MRU) { | 456 | if (len > HDLC_MAX_MRU) { |
473 | printk(KERN_WARNING "%s: Too many PVCs while sending " | 457 | printk(KERN_WARNING "%s: Too many PVCs while sending " |
@@ -484,29 +468,31 @@ static void fr_lmi_send(struct net_device *dev, int fullrep) | |||
484 | } | 468 | } |
485 | memset(skb->data, 0, len); | 469 | memset(skb->data, 0, len); |
486 | skb_reserve(skb, 4); | 470 | skb_reserve(skb, 4); |
487 | skb->protocol = __constant_htons(LMI_PROTO); | 471 | if (lmi == LMI_CISCO) { |
488 | fr_hard_header(&skb, LMI_DLCI); | 472 | skb->protocol = __constant_htons(NLPID_CISCO_LMI); |
473 | fr_hard_header(&skb, LMI_CISCO_DLCI); | ||
474 | } else { | ||
475 | skb->protocol = __constant_htons(NLPID_CCITT_ANSI_LMI); | ||
476 | fr_hard_header(&skb, LMI_CCITT_ANSI_DLCI); | ||
477 | } | ||
489 | data = skb->tail; | 478 | data = skb->tail; |
490 | data[i++] = LMI_CALLREF; | 479 | data[i++] = LMI_CALLREF; |
491 | data[i++] = hdlc->state.fr.settings.dce | 480 | data[i++] = dce ? LMI_STATUS : LMI_STATUS_ENQUIRY; |
492 | ? LMI_STATUS : LMI_STATUS_ENQUIRY; | 481 | if (lmi == LMI_ANSI) |
493 | if (hdlc->state.fr.settings.lmi == LMI_ANSI) | ||
494 | data[i++] = LMI_ANSI_LOCKSHIFT; | 482 | data[i++] = LMI_ANSI_LOCKSHIFT; |
495 | data[i++] = (hdlc->state.fr.settings.lmi == LMI_CCITT) | 483 | data[i++] = lmi == LMI_CCITT ? LMI_CCITT_REPTYPE : |
496 | ? LMI_CCITT_REPTYPE : LMI_REPTYPE; | 484 | LMI_ANSI_CISCO_REPTYPE; |
497 | data[i++] = LMI_REPT_LEN; | 485 | data[i++] = LMI_REPT_LEN; |
498 | data[i++] = fullrep ? LMI_FULLREP : LMI_INTEGRITY; | 486 | data[i++] = fullrep ? LMI_FULLREP : LMI_INTEGRITY; |
499 | 487 | data[i++] = lmi == LMI_CCITT ? LMI_CCITT_ALIVE : LMI_ANSI_CISCO_ALIVE; | |
500 | data[i++] = (hdlc->state.fr.settings.lmi == LMI_CCITT) | ||
501 | ? LMI_CCITT_ALIVE : LMI_ALIVE; | ||
502 | data[i++] = LMI_INTEG_LEN; | 488 | data[i++] = LMI_INTEG_LEN; |
503 | data[i++] = hdlc->state.fr.txseq =fr_lmi_nextseq(hdlc->state.fr.txseq); | 489 | data[i++] = hdlc->state.fr.txseq =fr_lmi_nextseq(hdlc->state.fr.txseq); |
504 | data[i++] = hdlc->state.fr.rxseq; | 490 | data[i++] = hdlc->state.fr.rxseq; |
505 | 491 | ||
506 | if (hdlc->state.fr.settings.dce && fullrep) { | 492 | if (dce && fullrep) { |
507 | while (pvc) { | 493 | while (pvc) { |
508 | data[i++] = (hdlc->state.fr.settings.lmi == LMI_CCITT) | 494 | data[i++] = lmi == LMI_CCITT ? LMI_CCITT_PVCSTAT : |
509 | ? LMI_CCITT_PVCSTAT : LMI_PVCSTAT; | 495 | LMI_ANSI_CISCO_PVCSTAT; |
510 | data[i++] = stat_len; | 496 | data[i++] = stat_len; |
511 | 497 | ||
512 | /* LMI start/restart */ | 498 | /* LMI start/restart */ |
@@ -523,8 +509,20 @@ static void fr_lmi_send(struct net_device *dev, int fullrep) | |||
523 | fr_log_dlci_active(pvc); | 509 | fr_log_dlci_active(pvc); |
524 | } | 510 | } |
525 | 511 | ||
526 | dlci_to_status(pvc->dlci, data + i, | 512 | if (lmi == LMI_CISCO) { |
527 | pvc->state.active, pvc->state.new); | 513 | data[i] = pvc->dlci >> 8; |
514 | data[i + 1] = pvc->dlci & 0xFF; | ||
515 | } else { | ||
516 | data[i] = (pvc->dlci >> 4) & 0x3F; | ||
517 | data[i + 1] = ((pvc->dlci << 3) & 0x78) | 0x80; | ||
518 | data[i + 2] = 0x80; | ||
519 | } | ||
520 | |||
521 | if (pvc->state.new) | ||
522 | data[i + 2] |= 0x08; | ||
523 | else if (pvc->state.active) | ||
524 | data[i + 2] |= 0x02; | ||
525 | |||
528 | i += stat_len; | 526 | i += stat_len; |
529 | pvc = pvc->next; | 527 | pvc = pvc->next; |
530 | } | 528 | } |
@@ -569,6 +567,8 @@ static void fr_set_link_state(int reliable, struct net_device *dev) | |||
569 | pvc_carrier(0, pvc); | 567 | pvc_carrier(0, pvc); |
570 | pvc->state.exist = pvc->state.active = 0; | 568 | pvc->state.exist = pvc->state.active = 0; |
571 | pvc->state.new = 0; | 569 | pvc->state.new = 0; |
570 | if (!hdlc->state.fr.settings.dce) | ||
571 | pvc->state.bandwidth = 0; | ||
572 | pvc = pvc->next; | 572 | pvc = pvc->next; |
573 | } | 573 | } |
574 | } | 574 | } |
@@ -583,11 +583,12 @@ static void fr_timer(unsigned long arg) | |||
583 | int i, cnt = 0, reliable; | 583 | int i, cnt = 0, reliable; |
584 | u32 list; | 584 | u32 list; |
585 | 585 | ||
586 | if (hdlc->state.fr.settings.dce) | 586 | if (hdlc->state.fr.settings.dce) { |
587 | reliable = hdlc->state.fr.request && | 587 | reliable = hdlc->state.fr.request && |
588 | time_before(jiffies, hdlc->state.fr.last_poll + | 588 | time_before(jiffies, hdlc->state.fr.last_poll + |
589 | hdlc->state.fr.settings.t392 * HZ); | 589 | hdlc->state.fr.settings.t392 * HZ); |
590 | else { | 590 | hdlc->state.fr.request = 0; |
591 | } else { | ||
591 | hdlc->state.fr.last_errors <<= 1; /* Shift the list */ | 592 | hdlc->state.fr.last_errors <<= 1; /* Shift the list */ |
592 | if (hdlc->state.fr.request) { | 593 | if (hdlc->state.fr.request) { |
593 | if (hdlc->state.fr.reliable) | 594 | if (hdlc->state.fr.reliable) |
@@ -634,65 +635,88 @@ static void fr_timer(unsigned long arg) | |||
634 | static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) | 635 | static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) |
635 | { | 636 | { |
636 | hdlc_device *hdlc = dev_to_hdlc(dev); | 637 | hdlc_device *hdlc = dev_to_hdlc(dev); |
637 | int stat_len; | ||
638 | pvc_device *pvc; | 638 | pvc_device *pvc; |
639 | int reptype = -1, error, no_ram; | ||
640 | u8 rxseq, txseq; | 639 | u8 rxseq, txseq; |
641 | int i; | 640 | int lmi = hdlc->state.fr.settings.lmi; |
641 | int dce = hdlc->state.fr.settings.dce; | ||
642 | int stat_len = (lmi == LMI_CISCO) ? 6 : 3, reptype, error, no_ram, i; | ||
642 | 643 | ||
643 | if (skb->len < ((hdlc->state.fr.settings.lmi == LMI_ANSI) | 644 | if (skb->len < (lmi == LMI_ANSI ? LMI_ANSI_LENGTH : |
644 | ? LMI_ANSI_LENGTH : LMI_LENGTH)) { | 645 | LMI_CCITT_CISCO_LENGTH)) { |
645 | printk(KERN_INFO "%s: Short LMI frame\n", dev->name); | 646 | printk(KERN_INFO "%s: Short LMI frame\n", dev->name); |
646 | return 1; | 647 | return 1; |
647 | } | 648 | } |
648 | 649 | ||
649 | if (skb->data[5] != (!hdlc->state.fr.settings.dce ? | 650 | if (skb->data[3] != (lmi == LMI_CISCO ? NLPID_CISCO_LMI : |
650 | LMI_STATUS : LMI_STATUS_ENQUIRY)) { | 651 | NLPID_CCITT_ANSI_LMI)) { |
651 | printk(KERN_INFO "%s: LMI msgtype=%x, Not LMI status %s\n", | 652 | printk(KERN_INFO "%s: Received non-LMI frame with LMI" |
652 | dev->name, skb->data[2], | 653 | " DLCI\n", dev->name); |
653 | hdlc->state.fr.settings.dce ? "enquiry" : "reply"); | 654 | return 1; |
655 | } | ||
656 | |||
657 | if (skb->data[4] != LMI_CALLREF) { | ||
658 | printk(KERN_INFO "%s: Invalid LMI Call reference (0x%02X)\n", | ||
659 | dev->name, skb->data[4]); | ||
660 | return 1; | ||
661 | } | ||
662 | |||
663 | if (skb->data[5] != (dce ? LMI_STATUS_ENQUIRY : LMI_STATUS)) { | ||
664 | printk(KERN_INFO "%s: Invalid LMI Message type (0x%02X)\n", | ||
665 | dev->name, skb->data[5]); | ||
654 | return 1; | 666 | return 1; |
655 | } | 667 | } |
656 | 668 | ||
657 | i = (hdlc->state.fr.settings.lmi == LMI_ANSI) ? 7 : 6; | 669 | if (lmi == LMI_ANSI) { |
670 | if (skb->data[6] != LMI_ANSI_LOCKSHIFT) { | ||
671 | printk(KERN_INFO "%s: Not ANSI locking shift in LMI" | ||
672 | " message (0x%02X)\n", dev->name, skb->data[6]); | ||
673 | return 1; | ||
674 | } | ||
675 | i = 7; | ||
676 | } else | ||
677 | i = 6; | ||
658 | 678 | ||
659 | if (skb->data[i] != | 679 | if (skb->data[i] != (lmi == LMI_CCITT ? LMI_CCITT_REPTYPE : |
660 | ((hdlc->state.fr.settings.lmi == LMI_CCITT) | 680 | LMI_ANSI_CISCO_REPTYPE)) { |
661 | ? LMI_CCITT_REPTYPE : LMI_REPTYPE)) { | 681 | printk(KERN_INFO "%s: Not an LMI Report type IE (0x%02X)\n", |
662 | printk(KERN_INFO "%s: Not a report type=%x\n", | ||
663 | dev->name, skb->data[i]); | 682 | dev->name, skb->data[i]); |
664 | return 1; | 683 | return 1; |
665 | } | 684 | } |
666 | i++; | ||
667 | 685 | ||
668 | i++; /* Skip length field */ | 686 | if (skb->data[++i] != LMI_REPT_LEN) { |
687 | printk(KERN_INFO "%s: Invalid LMI Report type IE length" | ||
688 | " (%u)\n", dev->name, skb->data[i]); | ||
689 | return 1; | ||
690 | } | ||
669 | 691 | ||
670 | reptype = skb->data[i++]; | 692 | reptype = skb->data[++i]; |
693 | if (reptype != LMI_INTEGRITY && reptype != LMI_FULLREP) { | ||
694 | printk(KERN_INFO "%s: Unsupported LMI Report type (0x%02X)\n", | ||
695 | dev->name, reptype); | ||
696 | return 1; | ||
697 | } | ||
671 | 698 | ||
672 | if (skb->data[i]!= | 699 | if (skb->data[++i] != (lmi == LMI_CCITT ? LMI_CCITT_ALIVE : |
673 | ((hdlc->state.fr.settings.lmi == LMI_CCITT) | 700 | LMI_ANSI_CISCO_ALIVE)) { |
674 | ? LMI_CCITT_ALIVE : LMI_ALIVE)) { | 701 | printk(KERN_INFO "%s: Not an LMI Link integrity verification" |
675 | printk(KERN_INFO "%s: Unsupported status element=%x\n", | 702 | " IE (0x%02X)\n", dev->name, skb->data[i]); |
676 | dev->name, skb->data[i]); | ||
677 | return 1; | 703 | return 1; |
678 | } | 704 | } |
679 | i++; | ||
680 | 705 | ||
681 | i++; /* Skip length field */ | 706 | if (skb->data[++i] != LMI_INTEG_LEN) { |
707 | printk(KERN_INFO "%s: Invalid LMI Link integrity verification" | ||
708 | " IE length (%u)\n", dev->name, skb->data[i]); | ||
709 | return 1; | ||
710 | } | ||
711 | i++; | ||
682 | 712 | ||
683 | hdlc->state.fr.rxseq = skb->data[i++]; /* TX sequence from peer */ | 713 | hdlc->state.fr.rxseq = skb->data[i++]; /* TX sequence from peer */ |
684 | rxseq = skb->data[i++]; /* Should confirm our sequence */ | 714 | rxseq = skb->data[i++]; /* Should confirm our sequence */ |
685 | 715 | ||
686 | txseq = hdlc->state.fr.txseq; | 716 | txseq = hdlc->state.fr.txseq; |
687 | 717 | ||
688 | if (hdlc->state.fr.settings.dce) { | 718 | if (dce) |
689 | if (reptype != LMI_FULLREP && reptype != LMI_INTEGRITY) { | ||
690 | printk(KERN_INFO "%s: Unsupported report type=%x\n", | ||
691 | dev->name, reptype); | ||
692 | return 1; | ||
693 | } | ||
694 | hdlc->state.fr.last_poll = jiffies; | 719 | hdlc->state.fr.last_poll = jiffies; |
695 | } | ||
696 | 720 | ||
697 | error = 0; | 721 | error = 0; |
698 | if (!hdlc->state.fr.reliable) | 722 | if (!hdlc->state.fr.reliable) |
@@ -703,7 +727,7 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) | |||
703 | error = 1; | 727 | error = 1; |
704 | } | 728 | } |
705 | 729 | ||
706 | if (hdlc->state.fr.settings.dce) { | 730 | if (dce) { |
707 | if (hdlc->state.fr.fullrep_sent && !error) { | 731 | if (hdlc->state.fr.fullrep_sent && !error) { |
708 | /* Stop sending full report - the last one has been confirmed by DTE */ | 732 | /* Stop sending full report - the last one has been confirmed by DTE */ |
709 | hdlc->state.fr.fullrep_sent = 0; | 733 | hdlc->state.fr.fullrep_sent = 0; |
@@ -725,6 +749,7 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) | |||
725 | hdlc->state.fr.dce_changed = 0; | 749 | hdlc->state.fr.dce_changed = 0; |
726 | } | 750 | } |
727 | 751 | ||
752 | hdlc->state.fr.request = 1; /* got request */ | ||
728 | fr_lmi_send(dev, reptype == LMI_FULLREP ? 1 : 0); | 753 | fr_lmi_send(dev, reptype == LMI_FULLREP ? 1 : 0); |
729 | return 0; | 754 | return 0; |
730 | } | 755 | } |
@@ -739,7 +764,6 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) | |||
739 | if (reptype != LMI_FULLREP) | 764 | if (reptype != LMI_FULLREP) |
740 | return 0; | 765 | return 0; |
741 | 766 | ||
742 | stat_len = 3; | ||
743 | pvc = hdlc->state.fr.first_pvc; | 767 | pvc = hdlc->state.fr.first_pvc; |
744 | 768 | ||
745 | while (pvc) { | 769 | while (pvc) { |
@@ -750,24 +774,35 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) | |||
750 | no_ram = 0; | 774 | no_ram = 0; |
751 | while (skb->len >= i + 2 + stat_len) { | 775 | while (skb->len >= i + 2 + stat_len) { |
752 | u16 dlci; | 776 | u16 dlci; |
777 | u32 bw; | ||
753 | unsigned int active, new; | 778 | unsigned int active, new; |
754 | 779 | ||
755 | if (skb->data[i] != ((hdlc->state.fr.settings.lmi == LMI_CCITT) | 780 | if (skb->data[i] != (lmi == LMI_CCITT ? LMI_CCITT_PVCSTAT : |
756 | ? LMI_CCITT_PVCSTAT : LMI_PVCSTAT)) { | 781 | LMI_ANSI_CISCO_PVCSTAT)) { |
757 | printk(KERN_WARNING "%s: Invalid PVCSTAT ID: %x\n", | 782 | printk(KERN_INFO "%s: Not an LMI PVC status IE" |
758 | dev->name, skb->data[i]); | 783 | " (0x%02X)\n", dev->name, skb->data[i]); |
759 | return 1; | 784 | return 1; |
760 | } | 785 | } |
761 | i++; | ||
762 | 786 | ||
763 | if (skb->data[i] != stat_len) { | 787 | if (skb->data[++i] != stat_len) { |
764 | printk(KERN_WARNING "%s: Invalid PVCSTAT length: %x\n", | 788 | printk(KERN_INFO "%s: Invalid LMI PVC status IE length" |
765 | dev->name, skb->data[i]); | 789 | " (%u)\n", dev->name, skb->data[i]); |
766 | return 1; | 790 | return 1; |
767 | } | 791 | } |
768 | i++; | 792 | i++; |
769 | 793 | ||
770 | dlci = status_to_dlci(skb->data + i, &active, &new); | 794 | new = !! (skb->data[i + 2] & 0x08); |
795 | active = !! (skb->data[i + 2] & 0x02); | ||
796 | if (lmi == LMI_CISCO) { | ||
797 | dlci = (skb->data[i] << 8) | skb->data[i + 1]; | ||
798 | bw = (skb->data[i + 3] << 16) | | ||
799 | (skb->data[i + 4] << 8) | | ||
800 | (skb->data[i + 5]); | ||
801 | } else { | ||
802 | dlci = ((skb->data[i] & 0x3F) << 4) | | ||
803 | ((skb->data[i + 1] & 0x78) >> 3); | ||
804 | bw = 0; | ||
805 | } | ||
771 | 806 | ||
772 | pvc = add_pvc(dev, dlci); | 807 | pvc = add_pvc(dev, dlci); |
773 | 808 | ||
@@ -783,9 +818,11 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) | |||
783 | pvc->state.deleted = 0; | 818 | pvc->state.deleted = 0; |
784 | if (active != pvc->state.active || | 819 | if (active != pvc->state.active || |
785 | new != pvc->state.new || | 820 | new != pvc->state.new || |
821 | bw != pvc->state.bandwidth || | ||
786 | !pvc->state.exist) { | 822 | !pvc->state.exist) { |
787 | pvc->state.new = new; | 823 | pvc->state.new = new; |
788 | pvc->state.active = active; | 824 | pvc->state.active = active; |
825 | pvc->state.bandwidth = bw; | ||
789 | pvc_carrier(active, pvc); | 826 | pvc_carrier(active, pvc); |
790 | fr_log_dlci_active(pvc); | 827 | fr_log_dlci_active(pvc); |
791 | } | 828 | } |
@@ -801,6 +838,7 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) | |||
801 | pvc_carrier(0, pvc); | 838 | pvc_carrier(0, pvc); |
802 | pvc->state.active = pvc->state.new = 0; | 839 | pvc->state.active = pvc->state.new = 0; |
803 | pvc->state.exist = 0; | 840 | pvc->state.exist = 0; |
841 | pvc->state.bandwidth = 0; | ||
804 | fr_log_dlci_active(pvc); | 842 | fr_log_dlci_active(pvc); |
805 | } | 843 | } |
806 | pvc = pvc->next; | 844 | pvc = pvc->next; |
@@ -829,22 +867,15 @@ static int fr_rx(struct sk_buff *skb) | |||
829 | 867 | ||
830 | dlci = q922_to_dlci(skb->data); | 868 | dlci = q922_to_dlci(skb->data); |
831 | 869 | ||
832 | if (dlci == LMI_DLCI) { | 870 | if ((dlci == LMI_CCITT_ANSI_DLCI && |
833 | if (hdlc->state.fr.settings.lmi == LMI_NONE) | 871 | (hdlc->state.fr.settings.lmi == LMI_ANSI || |
834 | goto rx_error; /* LMI packet with no LMI? */ | 872 | hdlc->state.fr.settings.lmi == LMI_CCITT)) || |
835 | 873 | (dlci == LMI_CISCO_DLCI && | |
836 | if (data[3] == LMI_PROTO) { | 874 | hdlc->state.fr.settings.lmi == LMI_CISCO)) { |
837 | if (fr_lmi_recv(ndev, skb)) | 875 | if (fr_lmi_recv(ndev, skb)) |
838 | goto rx_error; | 876 | goto rx_error; |
839 | else { | 877 | dev_kfree_skb_any(skb); |
840 | dev_kfree_skb_any(skb); | 878 | return NET_RX_SUCCESS; |
841 | return NET_RX_SUCCESS; | ||
842 | } | ||
843 | } | ||
844 | |||
845 | printk(KERN_INFO "%s: Received non-LMI frame with LMI DLCI\n", | ||
846 | ndev->name); | ||
847 | goto rx_error; | ||
848 | } | 879 | } |
849 | 880 | ||
850 | pvc = find_pvc(hdlc, dlci); | 881 | pvc = find_pvc(hdlc, dlci); |
@@ -1170,7 +1201,8 @@ int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
1170 | 1201 | ||
1171 | if ((new_settings.lmi != LMI_NONE && | 1202 | if ((new_settings.lmi != LMI_NONE && |
1172 | new_settings.lmi != LMI_ANSI && | 1203 | new_settings.lmi != LMI_ANSI && |
1173 | new_settings.lmi != LMI_CCITT) || | 1204 | new_settings.lmi != LMI_CCITT && |
1205 | new_settings.lmi != LMI_CISCO) || | ||
1174 | new_settings.t391 < 1 || | 1206 | new_settings.t391 < 1 || |
1175 | new_settings.t392 < 2 || | 1207 | new_settings.t392 < 2 || |
1176 | new_settings.n391 < 1 || | 1208 | new_settings.n391 < 1 || |
diff --git a/drivers/net/wan/hdlc_generic.c b/drivers/net/wan/hdlc_generic.c index 6ed064cb4469..a63f6a2cc4f7 100644 --- a/drivers/net/wan/hdlc_generic.c +++ b/drivers/net/wan/hdlc_generic.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Generic HDLC support routines for Linux | 2 | * Generic HDLC support routines for Linux |
3 | * | 3 | * |
4 | * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl> | 4 | * Copyright (C) 1999 - 2005 Krzysztof Halasa <khc@pm.waw.pl> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of version 2 of the GNU General Public License | 7 | * under the terms of version 2 of the GNU General Public License |
@@ -38,7 +38,7 @@ | |||
38 | #include <linux/hdlc.h> | 38 | #include <linux/hdlc.h> |
39 | 39 | ||
40 | 40 | ||
41 | static const char* version = "HDLC support module revision 1.17"; | 41 | static const char* version = "HDLC support module revision 1.18"; |
42 | 42 | ||
43 | #undef DEBUG_LINK | 43 | #undef DEBUG_LINK |
44 | 44 | ||
@@ -126,10 +126,13 @@ void hdlc_set_carrier(int on, struct net_device *dev) | |||
126 | if (!hdlc->open) | 126 | if (!hdlc->open) |
127 | goto carrier_exit; | 127 | goto carrier_exit; |
128 | 128 | ||
129 | if (hdlc->carrier) | 129 | if (hdlc->carrier) { |
130 | printk(KERN_INFO "%s: Carrier detected\n", dev->name); | ||
130 | __hdlc_set_carrier_on(dev); | 131 | __hdlc_set_carrier_on(dev); |
131 | else | 132 | } else { |
133 | printk(KERN_INFO "%s: Carrier lost\n", dev->name); | ||
132 | __hdlc_set_carrier_off(dev); | 134 | __hdlc_set_carrier_off(dev); |
135 | } | ||
133 | 136 | ||
134 | carrier_exit: | 137 | carrier_exit: |
135 | spin_unlock_irqrestore(&hdlc->state_lock, flags); | 138 | spin_unlock_irqrestore(&hdlc->state_lock, flags); |
@@ -157,8 +160,11 @@ int hdlc_open(struct net_device *dev) | |||
157 | 160 | ||
158 | spin_lock_irq(&hdlc->state_lock); | 161 | spin_lock_irq(&hdlc->state_lock); |
159 | 162 | ||
160 | if (hdlc->carrier) | 163 | if (hdlc->carrier) { |
164 | printk(KERN_INFO "%s: Carrier detected\n", dev->name); | ||
161 | __hdlc_set_carrier_on(dev); | 165 | __hdlc_set_carrier_on(dev); |
166 | } else | ||
167 | printk(KERN_INFO "%s: No carrier\n", dev->name); | ||
162 | 168 | ||
163 | hdlc->open = 1; | 169 | hdlc->open = 1; |
164 | 170 | ||
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index a3a32430ae9d..b1078baa1d5e 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c | |||
@@ -492,6 +492,9 @@ EXPORT_SYMBOL(orinoco_debug); | |||
492 | static int suppress_linkstatus; /* = 0 */ | 492 | static int suppress_linkstatus; /* = 0 */ |
493 | module_param(suppress_linkstatus, bool, 0644); | 493 | module_param(suppress_linkstatus, bool, 0644); |
494 | MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes"); | 494 | MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes"); |
495 | static int ignore_disconnect; /* = 0 */ | ||
496 | module_param(ignore_disconnect, int, 0644); | ||
497 | MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer"); | ||
495 | 498 | ||
496 | /********************************************************************/ | 499 | /********************************************************************/ |
497 | /* Compile time configuration and compatibility stuff */ | 500 | /* Compile time configuration and compatibility stuff */ |
@@ -604,7 +607,6 @@ struct hermes_rx_descriptor { | |||
604 | static int orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | 607 | static int orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); |
605 | static int __orinoco_program_rids(struct net_device *dev); | 608 | static int __orinoco_program_rids(struct net_device *dev); |
606 | static void __orinoco_set_multicast_list(struct net_device *dev); | 609 | static void __orinoco_set_multicast_list(struct net_device *dev); |
607 | static int orinoco_debug_dump_recs(struct net_device *dev); | ||
608 | 610 | ||
609 | /********************************************************************/ | 611 | /********************************************************************/ |
610 | /* Internal helper functions */ | 612 | /* Internal helper functions */ |
@@ -655,7 +657,7 @@ static int orinoco_open(struct net_device *dev) | |||
655 | return err; | 657 | return err; |
656 | } | 658 | } |
657 | 659 | ||
658 | int orinoco_stop(struct net_device *dev) | 660 | static int orinoco_stop(struct net_device *dev) |
659 | { | 661 | { |
660 | struct orinoco_private *priv = netdev_priv(dev); | 662 | struct orinoco_private *priv = netdev_priv(dev); |
661 | int err = 0; | 663 | int err = 0; |
@@ -686,7 +688,7 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev) | |||
686 | struct orinoco_private *priv = netdev_priv(dev); | 688 | struct orinoco_private *priv = netdev_priv(dev); |
687 | hermes_t *hw = &priv->hw; | 689 | hermes_t *hw = &priv->hw; |
688 | struct iw_statistics *wstats = &priv->wstats; | 690 | struct iw_statistics *wstats = &priv->wstats; |
689 | int err = 0; | 691 | int err; |
690 | unsigned long flags; | 692 | unsigned long flags; |
691 | 693 | ||
692 | if (! netif_device_present(dev)) { | 694 | if (! netif_device_present(dev)) { |
@@ -695,9 +697,21 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev) | |||
695 | return NULL; /* FIXME: Can we do better than this? */ | 697 | return NULL; /* FIXME: Can we do better than this? */ |
696 | } | 698 | } |
697 | 699 | ||
700 | /* If busy, return the old stats. Returning NULL may cause | ||
701 | * the interface to disappear from /proc/net/wireless */ | ||
698 | if (orinoco_lock(priv, &flags) != 0) | 702 | if (orinoco_lock(priv, &flags) != 0) |
699 | return NULL; /* FIXME: Erg, we've been signalled, how | 703 | return wstats; |
700 | * do we propagate this back up? */ | 704 | |
705 | /* We can't really wait for the tallies inquiry command to | ||
706 | * complete, so we just use the previous results and trigger | ||
707 | * a new tallies inquiry command for next time - Jean II */ | ||
708 | /* FIXME: Really we should wait for the inquiry to come back - | ||
709 | * as it is the stats we give don't make a whole lot of sense. | ||
710 | * Unfortunately, it's not clear how to do that within the | ||
711 | * wireless extensions framework: I think we're in user | ||
712 | * context, but a lock seems to be held by the time we get in | ||
713 | * here so we're not safe to sleep here. */ | ||
714 | hermes_inquire(hw, HERMES_INQ_TALLIES); | ||
701 | 715 | ||
702 | if (priv->iw_mode == IW_MODE_ADHOC) { | 716 | if (priv->iw_mode == IW_MODE_ADHOC) { |
703 | memset(&wstats->qual, 0, sizeof(wstats->qual)); | 717 | memset(&wstats->qual, 0, sizeof(wstats->qual)); |
@@ -716,25 +730,16 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev) | |||
716 | 730 | ||
717 | err = HERMES_READ_RECORD(hw, USER_BAP, | 731 | err = HERMES_READ_RECORD(hw, USER_BAP, |
718 | HERMES_RID_COMMSQUALITY, &cq); | 732 | HERMES_RID_COMMSQUALITY, &cq); |
719 | 733 | ||
720 | wstats->qual.qual = (int)le16_to_cpu(cq.qual); | 734 | if (!err) { |
721 | wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95; | 735 | wstats->qual.qual = (int)le16_to_cpu(cq.qual); |
722 | wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95; | 736 | wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95; |
723 | wstats->qual.updated = 7; | 737 | wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95; |
738 | wstats->qual.updated = 7; | ||
739 | } | ||
724 | } | 740 | } |
725 | 741 | ||
726 | /* We can't really wait for the tallies inquiry command to | ||
727 | * complete, so we just use the previous results and trigger | ||
728 | * a new tallies inquiry command for next time - Jean II */ | ||
729 | /* FIXME: We're in user context (I think?), so we should just | ||
730 | wait for the tallies to come through */ | ||
731 | err = hermes_inquire(hw, HERMES_INQ_TALLIES); | ||
732 | |||
733 | orinoco_unlock(priv, &flags); | 742 | orinoco_unlock(priv, &flags); |
734 | |||
735 | if (err) | ||
736 | return NULL; | ||
737 | |||
738 | return wstats; | 743 | return wstats; |
739 | } | 744 | } |
740 | 745 | ||
@@ -1275,9 +1280,10 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) | |||
1275 | len = sizeof(tallies); | 1280 | len = sizeof(tallies); |
1276 | } | 1281 | } |
1277 | 1282 | ||
1278 | /* Read directly the data (no seek) */ | 1283 | err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len, |
1279 | hermes_read_words(hw, HERMES_DATA1, (void *) &tallies, | 1284 | infofid, sizeof(info)); |
1280 | len / 2); /* FIXME: blech! */ | 1285 | if (err) |
1286 | break; | ||
1281 | 1287 | ||
1282 | /* Increment our various counters */ | 1288 | /* Increment our various counters */ |
1283 | /* wstats->discard.nwid - no wrong BSSID stuff */ | 1289 | /* wstats->discard.nwid - no wrong BSSID stuff */ |
@@ -1307,8 +1313,10 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) | |||
1307 | break; | 1313 | break; |
1308 | } | 1314 | } |
1309 | 1315 | ||
1310 | hermes_read_words(hw, HERMES_DATA1, (void *) &linkstatus, | 1316 | err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len, |
1311 | len / 2); | 1317 | infofid, sizeof(info)); |
1318 | if (err) | ||
1319 | break; | ||
1312 | newstatus = le16_to_cpu(linkstatus.linkstatus); | 1320 | newstatus = le16_to_cpu(linkstatus.linkstatus); |
1313 | 1321 | ||
1314 | connected = (newstatus == HERMES_LINKSTATUS_CONNECTED) | 1322 | connected = (newstatus == HERMES_LINKSTATUS_CONNECTED) |
@@ -1317,7 +1325,7 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) | |||
1317 | 1325 | ||
1318 | if (connected) | 1326 | if (connected) |
1319 | netif_carrier_on(dev); | 1327 | netif_carrier_on(dev); |
1320 | else | 1328 | else if (!ignore_disconnect) |
1321 | netif_carrier_off(dev); | 1329 | netif_carrier_off(dev); |
1322 | 1330 | ||
1323 | if (newstatus != priv->last_linkstatus) | 1331 | if (newstatus != priv->last_linkstatus) |
@@ -1350,6 +1358,8 @@ int __orinoco_up(struct net_device *dev) | |||
1350 | struct hermes *hw = &priv->hw; | 1358 | struct hermes *hw = &priv->hw; |
1351 | int err; | 1359 | int err; |
1352 | 1360 | ||
1361 | netif_carrier_off(dev); /* just to make sure */ | ||
1362 | |||
1353 | err = __orinoco_program_rids(dev); | 1363 | err = __orinoco_program_rids(dev); |
1354 | if (err) { | 1364 | if (err) { |
1355 | printk(KERN_ERR "%s: Error %d configuring card\n", | 1365 | printk(KERN_ERR "%s: Error %d configuring card\n", |
@@ -1413,7 +1423,7 @@ int orinoco_reinit_firmware(struct net_device *dev) | |||
1413 | return err; | 1423 | return err; |
1414 | 1424 | ||
1415 | err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); | 1425 | err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); |
1416 | if (err == -EIO) { | 1426 | if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) { |
1417 | /* Try workaround for old Symbol firmware bug */ | 1427 | /* Try workaround for old Symbol firmware bug */ |
1418 | printk(KERN_WARNING "%s: firmware ALLOC bug detected " | 1428 | printk(KERN_WARNING "%s: firmware ALLOC bug detected " |
1419 | "(old Symbol firmware?). Trying to work around... ", | 1429 | "(old Symbol firmware?). Trying to work around... ", |
@@ -1610,17 +1620,15 @@ static int __orinoco_program_rids(struct net_device *dev) | |||
1610 | return err; | 1620 | return err; |
1611 | } | 1621 | } |
1612 | /* Set the channel/frequency */ | 1622 | /* Set the channel/frequency */ |
1613 | if (priv->channel == 0) { | 1623 | if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) { |
1614 | printk(KERN_DEBUG "%s: Channel is 0 in __orinoco_program_rids()\n", dev->name); | 1624 | err = hermes_write_wordrec(hw, USER_BAP, |
1615 | if (priv->createibss) | 1625 | HERMES_RID_CNFOWNCHANNEL, |
1616 | priv->channel = 10; | 1626 | priv->channel); |
1617 | } | 1627 | if (err) { |
1618 | err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFOWNCHANNEL, | 1628 | printk(KERN_ERR "%s: Error %d setting channel %d\n", |
1619 | priv->channel); | 1629 | dev->name, err, priv->channel); |
1620 | if (err) { | 1630 | return err; |
1621 | printk(KERN_ERR "%s: Error %d setting channel\n", | 1631 | } |
1622 | dev->name, err); | ||
1623 | return err; | ||
1624 | } | 1632 | } |
1625 | 1633 | ||
1626 | if (priv->has_ibss) { | 1634 | if (priv->has_ibss) { |
@@ -1916,7 +1924,7 @@ static void orinoco_reset(struct net_device *dev) | |||
1916 | { | 1924 | { |
1917 | struct orinoco_private *priv = netdev_priv(dev); | 1925 | struct orinoco_private *priv = netdev_priv(dev); |
1918 | struct hermes *hw = &priv->hw; | 1926 | struct hermes *hw = &priv->hw; |
1919 | int err = 0; | 1927 | int err; |
1920 | unsigned long flags; | 1928 | unsigned long flags; |
1921 | 1929 | ||
1922 | if (orinoco_lock(priv, &flags) != 0) | 1930 | if (orinoco_lock(priv, &flags) != 0) |
@@ -1938,20 +1946,20 @@ static void orinoco_reset(struct net_device *dev) | |||
1938 | 1946 | ||
1939 | orinoco_unlock(priv, &flags); | 1947 | orinoco_unlock(priv, &flags); |
1940 | 1948 | ||
1941 | if (priv->hard_reset) | 1949 | if (priv->hard_reset) { |
1942 | err = (*priv->hard_reset)(priv); | 1950 | err = (*priv->hard_reset)(priv); |
1943 | if (err) { | 1951 | if (err) { |
1944 | printk(KERN_ERR "%s: orinoco_reset: Error %d " | 1952 | printk(KERN_ERR "%s: orinoco_reset: Error %d " |
1945 | "performing hard reset\n", dev->name, err); | 1953 | "performing hard reset\n", dev->name, err); |
1946 | /* FIXME: shutdown of some sort */ | 1954 | goto disable; |
1947 | return; | 1955 | } |
1948 | } | 1956 | } |
1949 | 1957 | ||
1950 | err = orinoco_reinit_firmware(dev); | 1958 | err = orinoco_reinit_firmware(dev); |
1951 | if (err) { | 1959 | if (err) { |
1952 | printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n", | 1960 | printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n", |
1953 | dev->name, err); | 1961 | dev->name, err); |
1954 | return; | 1962 | goto disable; |
1955 | } | 1963 | } |
1956 | 1964 | ||
1957 | spin_lock_irq(&priv->lock); /* This has to be called from user context */ | 1965 | spin_lock_irq(&priv->lock); /* This has to be called from user context */ |
@@ -1972,6 +1980,10 @@ static void orinoco_reset(struct net_device *dev) | |||
1972 | spin_unlock_irq(&priv->lock); | 1980 | spin_unlock_irq(&priv->lock); |
1973 | 1981 | ||
1974 | return; | 1982 | return; |
1983 | disable: | ||
1984 | hermes_set_irqmask(hw, 0); | ||
1985 | netif_device_detach(dev); | ||
1986 | printk(KERN_ERR "%s: Device has been disabled!\n", dev->name); | ||
1975 | } | 1987 | } |
1976 | 1988 | ||
1977 | /********************************************************************/ | 1989 | /********************************************************************/ |
@@ -2056,7 +2068,7 @@ irqreturn_t orinoco_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
2056 | if (events & HERMES_EV_ALLOC) | 2068 | if (events & HERMES_EV_ALLOC) |
2057 | __orinoco_ev_alloc(dev, hw); | 2069 | __orinoco_ev_alloc(dev, hw); |
2058 | 2070 | ||
2059 | hermes_write_regn(hw, EVACK, events); | 2071 | hermes_write_regn(hw, EVACK, evstat); |
2060 | 2072 | ||
2061 | evstat = hermes_read_regn(hw, EVSTAT); | 2073 | evstat = hermes_read_regn(hw, EVSTAT); |
2062 | events = evstat & hw->inten; | 2074 | events = evstat & hw->inten; |
@@ -2215,6 +2227,8 @@ static int determine_firmware(struct net_device *dev) | |||
2215 | firmver >= 0x31000; | 2227 | firmver >= 0x31000; |
2216 | priv->has_preamble = (firmver >= 0x20000); | 2228 | priv->has_preamble = (firmver >= 0x20000); |
2217 | priv->ibss_port = 4; | 2229 | priv->ibss_port = 4; |
2230 | priv->broken_disableport = (firmver == 0x25013) || | ||
2231 | (firmver >= 0x30000 && firmver <= 0x31000); | ||
2218 | /* Tested with Intel firmware : 0x20015 => Jean II */ | 2232 | /* Tested with Intel firmware : 0x20015 => Jean II */ |
2219 | /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */ | 2233 | /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */ |
2220 | break; | 2234 | break; |
@@ -2267,7 +2281,7 @@ static int orinoco_init(struct net_device *dev) | |||
2267 | priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN; | 2281 | priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN; |
2268 | 2282 | ||
2269 | /* Initialize the firmware */ | 2283 | /* Initialize the firmware */ |
2270 | err = hermes_init(hw); | 2284 | err = orinoco_reinit_firmware(dev); |
2271 | if (err != 0) { | 2285 | if (err != 0) { |
2272 | printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n", | 2286 | printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n", |
2273 | dev->name, err); | 2287 | dev->name, err); |
@@ -2400,31 +2414,12 @@ static int orinoco_init(struct net_device *dev) | |||
2400 | /* By default use IEEE/IBSS ad-hoc mode if we have it */ | 2414 | /* By default use IEEE/IBSS ad-hoc mode if we have it */ |
2401 | priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss); | 2415 | priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss); |
2402 | set_port_type(priv); | 2416 | set_port_type(priv); |
2403 | priv->channel = 10; /* default channel, more-or-less arbitrary */ | 2417 | priv->channel = 0; /* use firmware default */ |
2404 | 2418 | ||
2405 | priv->promiscuous = 0; | 2419 | priv->promiscuous = 0; |
2406 | priv->wep_on = 0; | 2420 | priv->wep_on = 0; |
2407 | priv->tx_key = 0; | 2421 | priv->tx_key = 0; |
2408 | 2422 | ||
2409 | err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); | ||
2410 | if (err == -EIO) { | ||
2411 | /* Try workaround for old Symbol firmware bug */ | ||
2412 | printk(KERN_WARNING "%s: firmware ALLOC bug detected " | ||
2413 | "(old Symbol firmware?). Trying to work around... ", | ||
2414 | dev->name); | ||
2415 | |||
2416 | priv->nicbuf_size = TX_NICBUF_SIZE_BUG; | ||
2417 | err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); | ||
2418 | if (err) | ||
2419 | printk("failed!\n"); | ||
2420 | else | ||
2421 | printk("ok.\n"); | ||
2422 | } | ||
2423 | if (err) { | ||
2424 | printk("%s: Error %d allocating Tx buffer\n", dev->name, err); | ||
2425 | goto out; | ||
2426 | } | ||
2427 | |||
2428 | /* Make the hardware available, as long as it hasn't been | 2423 | /* Make the hardware available, as long as it hasn't been |
2429 | * removed elsewhere (e.g. by PCMCIA hot unplug) */ | 2424 | * removed elsewhere (e.g. by PCMCIA hot unplug) */ |
2430 | spin_lock_irq(&priv->lock); | 2425 | spin_lock_irq(&priv->lock); |
@@ -2450,7 +2445,7 @@ struct net_device *alloc_orinocodev(int sizeof_card, | |||
2450 | priv = netdev_priv(dev); | 2445 | priv = netdev_priv(dev); |
2451 | priv->ndev = dev; | 2446 | priv->ndev = dev; |
2452 | if (sizeof_card) | 2447 | if (sizeof_card) |
2453 | priv->card = (void *)((unsigned long)netdev_priv(dev) | 2448 | priv->card = (void *)((unsigned long)priv |
2454 | + sizeof(struct orinoco_private)); | 2449 | + sizeof(struct orinoco_private)); |
2455 | else | 2450 | else |
2456 | priv->card = NULL; | 2451 | priv->card = NULL; |
@@ -2555,6 +2550,7 @@ static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active, | |||
2555 | } | 2550 | } |
2556 | 2551 | ||
2557 | len = le16_to_cpu(essidbuf.len); | 2552 | len = le16_to_cpu(essidbuf.len); |
2553 | BUG_ON(len > IW_ESSID_MAX_SIZE); | ||
2558 | 2554 | ||
2559 | memset(buf, 0, IW_ESSID_MAX_SIZE+1); | 2555 | memset(buf, 0, IW_ESSID_MAX_SIZE+1); |
2560 | memcpy(buf, p, len); | 2556 | memcpy(buf, p, len); |
@@ -2923,13 +2919,14 @@ static int orinoco_ioctl_setessid(struct net_device *dev, struct iw_point *erq) | |||
2923 | memset(&essidbuf, 0, sizeof(essidbuf)); | 2919 | memset(&essidbuf, 0, sizeof(essidbuf)); |
2924 | 2920 | ||
2925 | if (erq->flags) { | 2921 | if (erq->flags) { |
2926 | if (erq->length > IW_ESSID_MAX_SIZE) | 2922 | /* iwconfig includes the NUL in the specified length */ |
2923 | if (erq->length > IW_ESSID_MAX_SIZE+1) | ||
2927 | return -E2BIG; | 2924 | return -E2BIG; |
2928 | 2925 | ||
2929 | if (copy_from_user(&essidbuf, erq->pointer, erq->length)) | 2926 | if (copy_from_user(&essidbuf, erq->pointer, erq->length)) |
2930 | return -EFAULT; | 2927 | return -EFAULT; |
2931 | 2928 | ||
2932 | essidbuf[erq->length] = '\0'; | 2929 | essidbuf[IW_ESSID_MAX_SIZE] = '\0'; |
2933 | } | 2930 | } |
2934 | 2931 | ||
2935 | if (orinoco_lock(priv, &flags) != 0) | 2932 | if (orinoco_lock(priv, &flags) != 0) |
@@ -3855,7 +3852,6 @@ orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
3855 | { SIOCIWFIRSTPRIV + 0x7, 0, | 3852 | { SIOCIWFIRSTPRIV + 0x7, 0, |
3856 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, | 3853 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, |
3857 | "get_ibssport" }, | 3854 | "get_ibssport" }, |
3858 | { SIOCIWLASTPRIV, 0, 0, "dump_recs" }, | ||
3859 | }; | 3855 | }; |
3860 | 3856 | ||
3861 | wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]); | 3857 | wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]); |
@@ -3943,14 +3939,6 @@ orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
3943 | err = orinoco_ioctl_getibssport(dev, wrq); | 3939 | err = orinoco_ioctl_getibssport(dev, wrq); |
3944 | break; | 3940 | break; |
3945 | 3941 | ||
3946 | case SIOCIWLASTPRIV: | ||
3947 | err = orinoco_debug_dump_recs(dev); | ||
3948 | if (err) | ||
3949 | printk(KERN_ERR "%s: Unable to dump records (%d)\n", | ||
3950 | dev->name, err); | ||
3951 | break; | ||
3952 | |||
3953 | |||
3954 | default: | 3942 | default: |
3955 | err = -EOPNOTSUPP; | 3943 | err = -EOPNOTSUPP; |
3956 | } | 3944 | } |
@@ -3964,187 +3952,6 @@ orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
3964 | return err; | 3952 | return err; |
3965 | } | 3953 | } |
3966 | 3954 | ||
3967 | struct { | ||
3968 | u16 rid; | ||
3969 | char *name; | ||
3970 | int displaytype; | ||
3971 | #define DISPLAY_WORDS 0 | ||
3972 | #define DISPLAY_BYTES 1 | ||
3973 | #define DISPLAY_STRING 2 | ||
3974 | #define DISPLAY_XSTRING 3 | ||
3975 | } record_table[] = { | ||
3976 | #define DEBUG_REC(name,type) { HERMES_RID_##name, #name, DISPLAY_##type } | ||
3977 | DEBUG_REC(CNFPORTTYPE,WORDS), | ||
3978 | DEBUG_REC(CNFOWNMACADDR,BYTES), | ||
3979 | DEBUG_REC(CNFDESIREDSSID,STRING), | ||
3980 | DEBUG_REC(CNFOWNCHANNEL,WORDS), | ||
3981 | DEBUG_REC(CNFOWNSSID,STRING), | ||
3982 | DEBUG_REC(CNFOWNATIMWINDOW,WORDS), | ||
3983 | DEBUG_REC(CNFSYSTEMSCALE,WORDS), | ||
3984 | DEBUG_REC(CNFMAXDATALEN,WORDS), | ||
3985 | DEBUG_REC(CNFPMENABLED,WORDS), | ||
3986 | DEBUG_REC(CNFPMEPS,WORDS), | ||
3987 | DEBUG_REC(CNFMULTICASTRECEIVE,WORDS), | ||
3988 | DEBUG_REC(CNFMAXSLEEPDURATION,WORDS), | ||
3989 | DEBUG_REC(CNFPMHOLDOVERDURATION,WORDS), | ||
3990 | DEBUG_REC(CNFOWNNAME,STRING), | ||
3991 | DEBUG_REC(CNFOWNDTIMPERIOD,WORDS), | ||
3992 | DEBUG_REC(CNFMULTICASTPMBUFFERING,WORDS), | ||
3993 | DEBUG_REC(CNFWEPENABLED_AGERE,WORDS), | ||
3994 | DEBUG_REC(CNFMANDATORYBSSID_SYMBOL,WORDS), | ||
3995 | DEBUG_REC(CNFWEPDEFAULTKEYID,WORDS), | ||
3996 | DEBUG_REC(CNFDEFAULTKEY0,BYTES), | ||
3997 | DEBUG_REC(CNFDEFAULTKEY1,BYTES), | ||
3998 | DEBUG_REC(CNFMWOROBUST_AGERE,WORDS), | ||
3999 | DEBUG_REC(CNFDEFAULTKEY2,BYTES), | ||
4000 | DEBUG_REC(CNFDEFAULTKEY3,BYTES), | ||
4001 | DEBUG_REC(CNFWEPFLAGS_INTERSIL,WORDS), | ||
4002 | DEBUG_REC(CNFWEPKEYMAPPINGTABLE,WORDS), | ||
4003 | DEBUG_REC(CNFAUTHENTICATION,WORDS), | ||
4004 | DEBUG_REC(CNFMAXASSOCSTA,WORDS), | ||
4005 | DEBUG_REC(CNFKEYLENGTH_SYMBOL,WORDS), | ||
4006 | DEBUG_REC(CNFTXCONTROL,WORDS), | ||
4007 | DEBUG_REC(CNFROAMINGMODE,WORDS), | ||
4008 | DEBUG_REC(CNFHOSTAUTHENTICATION,WORDS), | ||
4009 | DEBUG_REC(CNFRCVCRCERROR,WORDS), | ||
4010 | DEBUG_REC(CNFMMLIFE,WORDS), | ||
4011 | DEBUG_REC(CNFALTRETRYCOUNT,WORDS), | ||
4012 | DEBUG_REC(CNFBEACONINT,WORDS), | ||
4013 | DEBUG_REC(CNFAPPCFINFO,WORDS), | ||
4014 | DEBUG_REC(CNFSTAPCFINFO,WORDS), | ||
4015 | DEBUG_REC(CNFPRIORITYQUSAGE,WORDS), | ||
4016 | DEBUG_REC(CNFTIMCTRL,WORDS), | ||
4017 | DEBUG_REC(CNFTHIRTY2TALLY,WORDS), | ||
4018 | DEBUG_REC(CNFENHSECURITY,WORDS), | ||
4019 | DEBUG_REC(CNFGROUPADDRESSES,BYTES), | ||
4020 | DEBUG_REC(CNFCREATEIBSS,WORDS), | ||
4021 | DEBUG_REC(CNFFRAGMENTATIONTHRESHOLD,WORDS), | ||
4022 | DEBUG_REC(CNFRTSTHRESHOLD,WORDS), | ||
4023 | DEBUG_REC(CNFTXRATECONTROL,WORDS), | ||
4024 | DEBUG_REC(CNFPROMISCUOUSMODE,WORDS), | ||
4025 | DEBUG_REC(CNFBASICRATES_SYMBOL,WORDS), | ||
4026 | DEBUG_REC(CNFPREAMBLE_SYMBOL,WORDS), | ||
4027 | DEBUG_REC(CNFSHORTPREAMBLE,WORDS), | ||
4028 | DEBUG_REC(CNFWEPKEYS_AGERE,BYTES), | ||
4029 | DEBUG_REC(CNFEXCLUDELONGPREAMBLE,WORDS), | ||
4030 | DEBUG_REC(CNFTXKEY_AGERE,WORDS), | ||
4031 | DEBUG_REC(CNFAUTHENTICATIONRSPTO,WORDS), | ||
4032 | DEBUG_REC(CNFBASICRATES,WORDS), | ||
4033 | DEBUG_REC(CNFSUPPORTEDRATES,WORDS), | ||
4034 | DEBUG_REC(CNFTICKTIME,WORDS), | ||
4035 | DEBUG_REC(CNFSCANREQUEST,WORDS), | ||
4036 | DEBUG_REC(CNFJOINREQUEST,WORDS), | ||
4037 | DEBUG_REC(CNFAUTHENTICATESTATION,WORDS), | ||
4038 | DEBUG_REC(CNFCHANNELINFOREQUEST,WORDS), | ||
4039 | DEBUG_REC(MAXLOADTIME,WORDS), | ||
4040 | DEBUG_REC(DOWNLOADBUFFER,WORDS), | ||
4041 | DEBUG_REC(PRIID,WORDS), | ||
4042 | DEBUG_REC(PRISUPRANGE,WORDS), | ||
4043 | DEBUG_REC(CFIACTRANGES,WORDS), | ||
4044 | DEBUG_REC(NICSERNUM,XSTRING), | ||
4045 | DEBUG_REC(NICID,WORDS), | ||
4046 | DEBUG_REC(MFISUPRANGE,WORDS), | ||
4047 | DEBUG_REC(CFISUPRANGE,WORDS), | ||
4048 | DEBUG_REC(CHANNELLIST,WORDS), | ||
4049 | DEBUG_REC(REGULATORYDOMAINS,WORDS), | ||
4050 | DEBUG_REC(TEMPTYPE,WORDS), | ||
4051 | /* DEBUG_REC(CIS,BYTES), */ | ||
4052 | DEBUG_REC(STAID,WORDS), | ||
4053 | DEBUG_REC(CURRENTSSID,STRING), | ||
4054 | DEBUG_REC(CURRENTBSSID,BYTES), | ||
4055 | DEBUG_REC(COMMSQUALITY,WORDS), | ||
4056 | DEBUG_REC(CURRENTTXRATE,WORDS), | ||
4057 | DEBUG_REC(CURRENTBEACONINTERVAL,WORDS), | ||
4058 | DEBUG_REC(CURRENTSCALETHRESHOLDS,WORDS), | ||
4059 | DEBUG_REC(PROTOCOLRSPTIME,WORDS), | ||
4060 | DEBUG_REC(SHORTRETRYLIMIT,WORDS), | ||
4061 | DEBUG_REC(LONGRETRYLIMIT,WORDS), | ||
4062 | DEBUG_REC(MAXTRANSMITLIFETIME,WORDS), | ||
4063 | DEBUG_REC(MAXRECEIVELIFETIME,WORDS), | ||
4064 | DEBUG_REC(CFPOLLABLE,WORDS), | ||
4065 | DEBUG_REC(AUTHENTICATIONALGORITHMS,WORDS), | ||
4066 | DEBUG_REC(PRIVACYOPTIONIMPLEMENTED,WORDS), | ||
4067 | DEBUG_REC(OWNMACADDR,BYTES), | ||
4068 | DEBUG_REC(SCANRESULTSTABLE,WORDS), | ||
4069 | DEBUG_REC(PHYTYPE,WORDS), | ||
4070 | DEBUG_REC(CURRENTCHANNEL,WORDS), | ||
4071 | DEBUG_REC(CURRENTPOWERSTATE,WORDS), | ||
4072 | DEBUG_REC(CCAMODE,WORDS), | ||
4073 | DEBUG_REC(SUPPORTEDDATARATES,WORDS), | ||
4074 | DEBUG_REC(BUILDSEQ,BYTES), | ||
4075 | DEBUG_REC(FWID,XSTRING) | ||
4076 | #undef DEBUG_REC | ||
4077 | }; | ||
4078 | |||
4079 | #define DEBUG_LTV_SIZE 128 | ||
4080 | |||
4081 | static int orinoco_debug_dump_recs(struct net_device *dev) | ||
4082 | { | ||
4083 | struct orinoco_private *priv = netdev_priv(dev); | ||
4084 | hermes_t *hw = &priv->hw; | ||
4085 | u8 *val8; | ||
4086 | u16 *val16; | ||
4087 | int i,j; | ||
4088 | u16 length; | ||
4089 | int err; | ||
4090 | |||
4091 | /* I'm not sure: we might have a lock here, so we'd better go | ||
4092 | atomic, just in case. */ | ||
4093 | val8 = kmalloc(DEBUG_LTV_SIZE + 2, GFP_ATOMIC); | ||
4094 | if (! val8) | ||
4095 | return -ENOMEM; | ||
4096 | val16 = (u16 *)val8; | ||
4097 | |||
4098 | for (i = 0; i < ARRAY_SIZE(record_table); i++) { | ||
4099 | u16 rid = record_table[i].rid; | ||
4100 | int len; | ||
4101 | |||
4102 | memset(val8, 0, DEBUG_LTV_SIZE + 2); | ||
4103 | |||
4104 | err = hermes_read_ltv(hw, USER_BAP, rid, DEBUG_LTV_SIZE, | ||
4105 | &length, val8); | ||
4106 | if (err) { | ||
4107 | DEBUG(0, "Error %d reading RID 0x%04x\n", err, rid); | ||
4108 | continue; | ||
4109 | } | ||
4110 | val16 = (u16 *)val8; | ||
4111 | if (length == 0) | ||
4112 | continue; | ||
4113 | |||
4114 | printk(KERN_DEBUG "%-15s (0x%04x): length=%d (%d bytes)\tvalue=", | ||
4115 | record_table[i].name, | ||
4116 | rid, length, (length-1)*2); | ||
4117 | len = min(((int)length-1)*2, DEBUG_LTV_SIZE); | ||
4118 | |||
4119 | switch (record_table[i].displaytype) { | ||
4120 | case DISPLAY_WORDS: | ||
4121 | for (j = 0; j < len / 2; j++) | ||
4122 | printk("%04X-", le16_to_cpu(val16[j])); | ||
4123 | break; | ||
4124 | |||
4125 | case DISPLAY_BYTES: | ||
4126 | default: | ||
4127 | for (j = 0; j < len; j++) | ||
4128 | printk("%02X:", val8[j]); | ||
4129 | break; | ||
4130 | |||
4131 | case DISPLAY_STRING: | ||
4132 | len = min(len, le16_to_cpu(val16[0])+2); | ||
4133 | val8[len] = '\0'; | ||
4134 | printk("\"%s\"", (char *)&val16[1]); | ||
4135 | break; | ||
4136 | |||
4137 | case DISPLAY_XSTRING: | ||
4138 | printk("'%s'", (char *)val8); | ||
4139 | } | ||
4140 | |||
4141 | printk("\n"); | ||
4142 | } | ||
4143 | |||
4144 | kfree(val8); | ||
4145 | |||
4146 | return 0; | ||
4147 | } | ||
4148 | 3955 | ||
4149 | /********************************************************************/ | 3956 | /********************************************************************/ |
4150 | /* Debugging */ | 3957 | /* Debugging */ |
@@ -4218,7 +4025,6 @@ EXPORT_SYMBOL(free_orinocodev); | |||
4218 | 4025 | ||
4219 | EXPORT_SYMBOL(__orinoco_up); | 4026 | EXPORT_SYMBOL(__orinoco_up); |
4220 | EXPORT_SYMBOL(__orinoco_down); | 4027 | EXPORT_SYMBOL(__orinoco_down); |
4221 | EXPORT_SYMBOL(orinoco_stop); | ||
4222 | EXPORT_SYMBOL(orinoco_reinit_firmware); | 4028 | EXPORT_SYMBOL(orinoco_reinit_firmware); |
4223 | 4029 | ||
4224 | EXPORT_SYMBOL(orinoco_interrupt); | 4030 | EXPORT_SYMBOL(orinoco_interrupt); |
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h index 13e42c2afb27..f749b50d1088 100644 --- a/drivers/net/wireless/orinoco.h +++ b/drivers/net/wireless/orinoco.h | |||
@@ -119,7 +119,6 @@ extern struct net_device *alloc_orinocodev(int sizeof_card, | |||
119 | extern void free_orinocodev(struct net_device *dev); | 119 | extern void free_orinocodev(struct net_device *dev); |
120 | extern int __orinoco_up(struct net_device *dev); | 120 | extern int __orinoco_up(struct net_device *dev); |
121 | extern int __orinoco_down(struct net_device *dev); | 121 | extern int __orinoco_down(struct net_device *dev); |
122 | extern int orinoco_stop(struct net_device *dev); | ||
123 | extern int orinoco_reinit_firmware(struct net_device *dev); | 122 | extern int orinoco_reinit_firmware(struct net_device *dev); |
124 | extern irqreturn_t orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs); | 123 | extern irqreturn_t orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs); |
125 | 124 | ||