diff options
Diffstat (limited to 'drivers/net/bfin_mac.c')
-rw-r--r-- | drivers/net/bfin_mac.c | 107 |
1 files changed, 69 insertions, 38 deletions
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index eb971755a3ff..c993a32b3f50 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c | |||
@@ -1,34 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * File: drivers/net/bfin_mac.c | 2 | * Blackfin On-Chip MAC Driver |
3 | * Based on: | ||
4 | * Maintainer: | ||
5 | * Bryan Wu <bryan.wu@analog.com> | ||
6 | * | 3 | * |
7 | * Original author: | 4 | * Copyright 2004-2007 Analog Devices Inc. |
8 | * Luke Yang <luke.yang@analog.com> | ||
9 | * | 5 | * |
10 | * Created: | 6 | * Enter bugs at http://blackfin.uclinux.org/ |
11 | * Description: | ||
12 | * | 7 | * |
13 | * Modified: | 8 | * Licensed under the GPL-2 or later. |
14 | * Copyright 2004-2006 Analog Devices Inc. | ||
15 | * | ||
16 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | ||
17 | * | ||
18 | * This program is free software ; you can redistribute it and/or modify | ||
19 | * it under the terms of the GNU General Public License as published by | ||
20 | * the Free Software Foundation ; either version 2, or (at your option) | ||
21 | * any later version. | ||
22 | * | ||
23 | * This program is distributed in the hope that it will be useful, | ||
24 | * but WITHOUT ANY WARRANTY ; without even the implied warranty of | ||
25 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
26 | * GNU General Public License for more details. | ||
27 | * | ||
28 | * You should have received a copy of the GNU General Public License | ||
29 | * along with this program ; see the file COPYING. | ||
30 | * If not, write to the Free Software Foundation, | ||
31 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
32 | */ | 9 | */ |
33 | 10 | ||
34 | #include <linux/init.h> | 11 | #include <linux/init.h> |
@@ -65,7 +42,7 @@ | |||
65 | #define DRV_NAME "bfin_mac" | 42 | #define DRV_NAME "bfin_mac" |
66 | #define DRV_VERSION "1.1" | 43 | #define DRV_VERSION "1.1" |
67 | #define DRV_AUTHOR "Bryan Wu, Luke Yang" | 44 | #define DRV_AUTHOR "Bryan Wu, Luke Yang" |
68 | #define DRV_DESC "Blackfin BF53[67] on-chip Ethernet MAC driver" | 45 | #define DRV_DESC "Blackfin BF53[67] BF527 on-chip Ethernet MAC driver" |
69 | 46 | ||
70 | MODULE_AUTHOR(DRV_AUTHOR); | 47 | MODULE_AUTHOR(DRV_AUTHOR); |
71 | MODULE_LICENSE("GPL"); | 48 | MODULE_LICENSE("GPL"); |
@@ -296,7 +273,7 @@ static void mdio_poll(void) | |||
296 | 273 | ||
297 | /* poll the STABUSY bit */ | 274 | /* poll the STABUSY bit */ |
298 | while ((bfin_read_EMAC_STAADD()) & STABUSY) { | 275 | while ((bfin_read_EMAC_STAADD()) & STABUSY) { |
299 | mdelay(10); | 276 | udelay(1); |
300 | if (timeout_cnt-- < 0) { | 277 | if (timeout_cnt-- < 0) { |
301 | printk(KERN_ERR DRV_NAME | 278 | printk(KERN_ERR DRV_NAME |
302 | ": wait MDC/MDIO transaction to complete timeout\n"); | 279 | ": wait MDC/MDIO transaction to complete timeout\n"); |
@@ -412,20 +389,26 @@ static void bf537_adjust_link(struct net_device *dev) | |||
412 | spin_unlock_irqrestore(&lp->lock, flags); | 389 | spin_unlock_irqrestore(&lp->lock, flags); |
413 | } | 390 | } |
414 | 391 | ||
392 | /* MDC = 2.5 MHz */ | ||
393 | #define MDC_CLK 2500000 | ||
394 | |||
415 | static int mii_probe(struct net_device *dev) | 395 | static int mii_probe(struct net_device *dev) |
416 | { | 396 | { |
417 | struct bf537mac_local *lp = netdev_priv(dev); | 397 | struct bf537mac_local *lp = netdev_priv(dev); |
418 | struct phy_device *phydev = NULL; | 398 | struct phy_device *phydev = NULL; |
419 | unsigned short sysctl; | 399 | unsigned short sysctl; |
420 | int i; | 400 | int i; |
401 | u32 sclk, mdc_div; | ||
421 | 402 | ||
422 | /* Enable PHY output early */ | 403 | /* Enable PHY output early */ |
423 | if (!(bfin_read_VR_CTL() & PHYCLKOE)) | 404 | if (!(bfin_read_VR_CTL() & PHYCLKOE)) |
424 | bfin_write_VR_CTL(bfin_read_VR_CTL() | PHYCLKOE); | 405 | bfin_write_VR_CTL(bfin_read_VR_CTL() | PHYCLKOE); |
425 | 406 | ||
426 | /* MDC = 2.5 MHz */ | 407 | sclk = get_sclk(); |
408 | mdc_div = ((sclk / MDC_CLK) / 2) - 1; | ||
409 | |||
427 | sysctl = bfin_read_EMAC_SYSCTL(); | 410 | sysctl = bfin_read_EMAC_SYSCTL(); |
428 | sysctl |= SET_MDCDIV(24); | 411 | sysctl = (sysctl & ~MDCDIV) | SET_MDCDIV(mdc_div); |
429 | bfin_write_EMAC_SYSCTL(sysctl); | 412 | bfin_write_EMAC_SYSCTL(sysctl); |
430 | 413 | ||
431 | /* search for connect PHY device */ | 414 | /* search for connect PHY device */ |
@@ -477,8 +460,10 @@ static int mii_probe(struct net_device *dev) | |||
477 | lp->phydev = phydev; | 460 | lp->phydev = phydev; |
478 | 461 | ||
479 | printk(KERN_INFO "%s: attached PHY driver [%s] " | 462 | printk(KERN_INFO "%s: attached PHY driver [%s] " |
480 | "(mii_bus:phy_addr=%s, irq=%d)\n", | 463 | "(mii_bus:phy_addr=%s, irq=%d, mdc_clk=%dHz(mdc_div=%d)" |
481 | DRV_NAME, phydev->drv->name, phydev->dev.bus_id, phydev->irq); | 464 | "@sclk=%dMHz)\n", |
465 | DRV_NAME, phydev->drv->name, phydev->dev.bus_id, phydev->irq, | ||
466 | MDC_CLK, mdc_div, sclk/1000000); | ||
482 | 467 | ||
483 | return 0; | 468 | return 0; |
484 | } | 469 | } |
@@ -551,7 +536,7 @@ static void adjust_tx_list(void) | |||
551 | */ | 536 | */ |
552 | if (current_tx_ptr->next->next == tx_list_head) { | 537 | if (current_tx_ptr->next->next == tx_list_head) { |
553 | while (tx_list_head->status.status_word == 0) { | 538 | while (tx_list_head->status.status_word == 0) { |
554 | mdelay(10); | 539 | mdelay(1); |
555 | if (tx_list_head->status.status_word != 0 | 540 | if (tx_list_head->status.status_word != 0 |
556 | || !(bfin_read_DMA2_IRQ_STATUS() & 0x08)) { | 541 | || !(bfin_read_DMA2_IRQ_STATUS() & 0x08)) { |
557 | goto adjust_head; | 542 | goto adjust_head; |
@@ -666,6 +651,12 @@ static void bf537mac_rx(struct net_device *dev) | |||
666 | current_rx_ptr->skb = new_skb; | 651 | current_rx_ptr->skb = new_skb; |
667 | current_rx_ptr->desc_a.start_addr = (unsigned long)new_skb->data - 2; | 652 | current_rx_ptr->desc_a.start_addr = (unsigned long)new_skb->data - 2; |
668 | 653 | ||
654 | /* Invidate the data cache of skb->data range when it is write back | ||
655 | * cache. It will prevent overwritting the new data from DMA | ||
656 | */ | ||
657 | blackfin_dcache_invalidate_range((unsigned long)new_skb->head, | ||
658 | (unsigned long)new_skb->end); | ||
659 | |||
669 | len = (unsigned short)((current_rx_ptr->status.status_word) & RX_FRLEN); | 660 | len = (unsigned short)((current_rx_ptr->status.status_word) & RX_FRLEN); |
670 | skb_put(skb, len); | 661 | skb_put(skb, len); |
671 | blackfin_dcache_invalidate_range((unsigned long)skb->head, | 662 | blackfin_dcache_invalidate_range((unsigned long)skb->head, |
@@ -767,7 +758,7 @@ static void bf537mac_enable(void) | |||
767 | 758 | ||
768 | #if defined(CONFIG_BFIN_MAC_RMII) | 759 | #if defined(CONFIG_BFIN_MAC_RMII) |
769 | opmode |= RMII; /* For Now only 100MBit are supported */ | 760 | opmode |= RMII; /* For Now only 100MBit are supported */ |
770 | #ifdef CONFIG_BF_REV_0_2 | 761 | #if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) && CONFIG_BF_REV_0_2 |
771 | opmode |= TE; | 762 | opmode |= TE; |
772 | #endif | 763 | #endif |
773 | #endif | 764 | #endif |
@@ -792,6 +783,39 @@ static void bf537mac_timeout(struct net_device *dev) | |||
792 | netif_wake_queue(dev); | 783 | netif_wake_queue(dev); |
793 | } | 784 | } |
794 | 785 | ||
786 | static void bf537mac_multicast_hash(struct net_device *dev) | ||
787 | { | ||
788 | u32 emac_hashhi, emac_hashlo; | ||
789 | struct dev_mc_list *dmi = dev->mc_list; | ||
790 | char *addrs; | ||
791 | int i; | ||
792 | u32 crc; | ||
793 | |||
794 | emac_hashhi = emac_hashlo = 0; | ||
795 | |||
796 | for (i = 0; i < dev->mc_count; i++) { | ||
797 | addrs = dmi->dmi_addr; | ||
798 | dmi = dmi->next; | ||
799 | |||
800 | /* skip non-multicast addresses */ | ||
801 | if (!(*addrs & 1)) | ||
802 | continue; | ||
803 | |||
804 | crc = ether_crc(ETH_ALEN, addrs); | ||
805 | crc >>= 26; | ||
806 | |||
807 | if (crc & 0x20) | ||
808 | emac_hashhi |= 1 << (crc & 0x1f); | ||
809 | else | ||
810 | emac_hashlo |= 1 << (crc & 0x1f); | ||
811 | } | ||
812 | |||
813 | bfin_write_EMAC_HASHHI(emac_hashhi); | ||
814 | bfin_write_EMAC_HASHLO(emac_hashlo); | ||
815 | |||
816 | return; | ||
817 | } | ||
818 | |||
795 | /* | 819 | /* |
796 | * This routine will, depending on the values passed to it, | 820 | * This routine will, depending on the values passed to it, |
797 | * either make it accept multicast packets, go into | 821 | * either make it accept multicast packets, go into |
@@ -807,11 +831,17 @@ static void bf537mac_set_multicast_list(struct net_device *dev) | |||
807 | sysctl = bfin_read_EMAC_OPMODE(); | 831 | sysctl = bfin_read_EMAC_OPMODE(); |
808 | sysctl |= RAF; | 832 | sysctl |= RAF; |
809 | bfin_write_EMAC_OPMODE(sysctl); | 833 | bfin_write_EMAC_OPMODE(sysctl); |
810 | } else if (dev->flags & IFF_ALLMULTI || dev->mc_count) { | 834 | } else if (dev->flags & IFF_ALLMULTI) { |
811 | /* accept all multicast */ | 835 | /* accept all multicast */ |
812 | sysctl = bfin_read_EMAC_OPMODE(); | 836 | sysctl = bfin_read_EMAC_OPMODE(); |
813 | sysctl |= PAM; | 837 | sysctl |= PAM; |
814 | bfin_write_EMAC_OPMODE(sysctl); | 838 | bfin_write_EMAC_OPMODE(sysctl); |
839 | } else if (dev->mc_count) { | ||
840 | /* set up multicast hash table */ | ||
841 | sysctl = bfin_read_EMAC_OPMODE(); | ||
842 | sysctl |= HM; | ||
843 | bfin_write_EMAC_OPMODE(sysctl); | ||
844 | bf537mac_multicast_hash(dev); | ||
815 | } else { | 845 | } else { |
816 | /* clear promisc or multicast mode */ | 846 | /* clear promisc or multicast mode */ |
817 | sysctl = bfin_read_EMAC_OPMODE(); | 847 | sysctl = bfin_read_EMAC_OPMODE(); |
@@ -860,10 +890,10 @@ static int bf537mac_open(struct net_device *dev) | |||
860 | return retval; | 890 | return retval; |
861 | 891 | ||
862 | phy_start(lp->phydev); | 892 | phy_start(lp->phydev); |
893 | phy_write(lp->phydev, MII_BMCR, BMCR_RESET); | ||
863 | setup_system_regs(dev); | 894 | setup_system_regs(dev); |
864 | bf537mac_disable(); | 895 | bf537mac_disable(); |
865 | bf537mac_enable(); | 896 | bf537mac_enable(); |
866 | |||
867 | pr_debug("hardware init finished\n"); | 897 | pr_debug("hardware init finished\n"); |
868 | netif_start_queue(dev); | 898 | netif_start_queue(dev); |
869 | netif_carrier_on(dev); | 899 | netif_carrier_on(dev); |
@@ -886,6 +916,7 @@ static int bf537mac_close(struct net_device *dev) | |||
886 | netif_carrier_off(dev); | 916 | netif_carrier_off(dev); |
887 | 917 | ||
888 | phy_stop(lp->phydev); | 918 | phy_stop(lp->phydev); |
919 | phy_write(lp->phydev, MII_BMCR, BMCR_PDOWN); | ||
889 | 920 | ||
890 | /* clear everything */ | 921 | /* clear everything */ |
891 | bf537mac_shutdown(dev); | 922 | bf537mac_shutdown(dev); |
@@ -970,7 +1001,7 @@ static int __init bf537mac_probe(struct net_device *dev) | |||
970 | /* register irq handler */ | 1001 | /* register irq handler */ |
971 | if (request_irq | 1002 | if (request_irq |
972 | (IRQ_MAC_RX, bf537mac_interrupt, IRQF_DISABLED | IRQF_SHARED, | 1003 | (IRQ_MAC_RX, bf537mac_interrupt, IRQF_DISABLED | IRQF_SHARED, |
973 | "BFIN537_MAC_RX", dev)) { | 1004 | "EMAC_RX", dev)) { |
974 | printk(KERN_WARNING DRV_NAME | 1005 | printk(KERN_WARNING DRV_NAME |
975 | ": Unable to attach BlackFin MAC RX interrupt\n"); | 1006 | ": Unable to attach BlackFin MAC RX interrupt\n"); |
976 | return -EBUSY; | 1007 | return -EBUSY; |