aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bfin_mac.c
diff options
context:
space:
mode:
authorBryan Wu <bryan.wu@analog.com>2007-09-19 11:37:36 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:51:50 -0400
commit4ae5a3ad5aa35972863f9c656ebd35446fbb5192 (patch)
tree0572d69ffbc64858e86b1a5128380c2138916fa7 /drivers/net/bfin_mac.c
parent496a34c2249fecc87ee689eede2bb8510c1b37a9 (diff)
Blackfin EMAC driver: Add phy abstraction layer supporting in bfin_emac driver
- add MDIO functions and register mdio bus - add phy abstraction layer (PAL) functions and use PAL API - test on STAMP537 board Signed-off-by: Bryan Wu <bryan.wu@analog.com> Acked-by: Jeff Garzik <jeff@garzik.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/bfin_mac.c')
-rw-r--r--drivers/net/bfin_mac.c311
1 files changed, 187 insertions, 124 deletions
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 5cb4433d5612..53fe7ded5d50 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -47,6 +47,7 @@
47#include <linux/spinlock.h> 47#include <linux/spinlock.h>
48#include <linux/ethtool.h> 48#include <linux/ethtool.h>
49#include <linux/mii.h> 49#include <linux/mii.h>
50#include <linux/phy.h>
50#include <linux/netdevice.h> 51#include <linux/netdevice.h>
51#include <linux/etherdevice.h> 52#include <linux/etherdevice.h>
52#include <linux/skbuff.h> 53#include <linux/skbuff.h>
@@ -94,6 +95,9 @@ static struct net_dma_desc_tx *current_tx_ptr;
94static struct net_dma_desc_tx *tx_desc; 95static struct net_dma_desc_tx *tx_desc;
95static struct net_dma_desc_rx *rx_desc; 96static struct net_dma_desc_rx *rx_desc;
96 97
98static void bf537mac_disable(void);
99static void bf537mac_enable(void);
100
97static void desc_list_free(void) 101static void desc_list_free(void)
98{ 102{
99 struct net_dma_desc_rx *r; 103 struct net_dma_desc_rx *r;
@@ -282,8 +286,11 @@ static int setup_pin_mux(int action)
282 return 0; 286 return 0;
283} 287}
284 288
289/*
290 * MII operations
291 */
285/* Wait until the previous MDC/MDIO transaction has completed */ 292/* Wait until the previous MDC/MDIO transaction has completed */
286static void poll_mdc_done(void) 293static void mdio_poll(void)
287{ 294{
288 int timeout_cnt = MAX_TIMEOUT_CNT; 295 int timeout_cnt = MAX_TIMEOUT_CNT;
289 296
@@ -299,154 +306,201 @@ static void poll_mdc_done(void)
299} 306}
300 307
301/* Read an off-chip register in a PHY through the MDC/MDIO port */ 308/* Read an off-chip register in a PHY through the MDC/MDIO port */
302static u16 read_phy_reg(u16 PHYAddr, u16 RegAddr) 309static int mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)
303{ 310{
304 poll_mdc_done(); 311 mdio_poll();
312
305 /* read mode */ 313 /* read mode */
306 bfin_write_EMAC_STAADD(SET_PHYAD(PHYAddr) | 314 bfin_write_EMAC_STAADD(SET_PHYAD((u16) phy_addr) |
307 SET_REGAD(RegAddr) | 315 SET_REGAD((u16) regnum) |
308 STABUSY); 316 STABUSY);
309 poll_mdc_done();
310 317
311 return (u16) bfin_read_EMAC_STADAT(); 318 mdio_poll();
319
320 return (int) bfin_read_EMAC_STADAT();
312} 321}
313 322
314/* Write an off-chip register in a PHY through the MDC/MDIO port */ 323/* Write an off-chip register in a PHY through the MDC/MDIO port */
315static void raw_write_phy_reg(u16 PHYAddr, u16 RegAddr, u32 Data) 324static int mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum,
325 u16 value)
316{ 326{
317 bfin_write_EMAC_STADAT(Data); 327 mdio_poll();
328
329 bfin_write_EMAC_STADAT((u32) value);
318 330
319 /* write mode */ 331 /* write mode */
320 bfin_write_EMAC_STAADD(SET_PHYAD(PHYAddr) | 332 bfin_write_EMAC_STAADD(SET_PHYAD((u16) phy_addr) |
321 SET_REGAD(RegAddr) | 333 SET_REGAD((u16) regnum) |
322 STAOP | 334 STAOP |
323 STABUSY); 335 STABUSY);
324 336
325 poll_mdc_done(); 337 mdio_poll();
338
339 return 0;
326} 340}
327 341
328static void write_phy_reg(u16 PHYAddr, u16 RegAddr, u32 Data) 342static int mdiobus_reset(struct mii_bus *bus)
329{ 343{
330 poll_mdc_done(); 344 return 0;
331 raw_write_phy_reg(PHYAddr, RegAddr, Data);
332} 345}
333 346
334/* set up the phy */ 347static void bf537_adjust_link(struct net_device *dev)
335static void bf537mac_setphy(struct net_device *dev)
336{ 348{
337 u16 phydat;
338 struct bf537mac_local *lp = netdev_priv(dev); 349 struct bf537mac_local *lp = netdev_priv(dev);
350 struct phy_device *phydev = lp->phydev;
351 unsigned long flags;
352 int new_state = 0;
353
354 spin_lock_irqsave(&lp->lock, flags);
355 if (phydev->link) {
356 /* Now we make sure that we can be in full duplex mode.
357 * If not, we operate in half-duplex mode. */
358 if (phydev->duplex != lp->old_duplex) {
359 u32 opmode = bfin_read_EMAC_OPMODE();
360 new_state = 1;
361
362 if (phydev->duplex)
363 opmode |= FDMODE;
364 else
365 opmode &= ~(FDMODE);
366
367 bfin_write_EMAC_OPMODE(opmode);
368 lp->old_duplex = phydev->duplex;
369 }
339 370
340 /* Program PHY registers */ 371 if (phydev->speed != lp->old_speed) {
341 pr_debug("start setting up phy\n"); 372#if defined(CONFIG_BFIN_MAC_RMII)
342 373 u32 opmode = bfin_read_EMAC_OPMODE();
343 /* issue a reset */ 374 bf537mac_disable();
344 raw_write_phy_reg(lp->PhyAddr, PHYREG_MODECTL, 0x8000); 375 switch (phydev->speed) {
345 376 case 10:
346 /* wait half a second */ 377 opmode |= RMII_10;
347 msleep(500); 378 break;
348 379 case 100:
349 phydat = read_phy_reg(lp->PhyAddr, PHYREG_MODECTL); 380 opmode &= ~(RMII_10);
350 381 break;
351 /* advertise flow control supported */ 382 default:
352 phydat = read_phy_reg(lp->PhyAddr, PHYREG_ANAR); 383 printk(KERN_WARNING
353 phydat |= (1 << 10); 384 "%s: Ack! Speed (%d) is not 10/100!\n",
354 write_phy_reg(lp->PhyAddr, PHYREG_ANAR, phydat); 385 DRV_NAME, phydev->speed);
386 break;
387 }
388 bfin_write_EMAC_OPMODE(opmode);
389 bf537mac_enable();
390#endif
355 391
356 phydat = 0; 392 new_state = 1;
357 if (lp->Negotiate) 393 lp->old_speed = phydev->speed;
358 phydat |= 0x1000; /* enable auto negotiation */ 394 }
359 else {
360 if (lp->FullDuplex)
361 phydat |= (1 << 8); /* full duplex */
362 else
363 phydat &= (~(1 << 8)); /* half duplex */
364 395
365 if (!lp->Port10) 396 if (!lp->old_link) {
366 phydat |= (1 << 13); /* 100 Mbps */ 397 new_state = 1;
367 else 398 lp->old_link = 1;
368 phydat &= (~(1 << 13)); /* 10 Mbps */ 399 netif_schedule(dev);
400 }
401 } else if (lp->old_link) {
402 new_state = 1;
403 lp->old_link = 0;
404 lp->old_speed = 0;
405 lp->old_duplex = -1;
369 } 406 }
370 407
371 if (lp->Loopback) 408 if (new_state) {
372 phydat |= (1 << 14); /* enable TX->RX loopback */ 409 u32 opmode = bfin_read_EMAC_OPMODE();
373 410 phy_print_status(phydev);
374 write_phy_reg(lp->PhyAddr, PHYREG_MODECTL, phydat); 411 pr_debug("EMAC_OPMODE = 0x%08x\n", opmode);
375 msleep(500);
376
377 phydat = read_phy_reg(lp->PhyAddr, PHYREG_MODECTL);
378 /* check for SMSC PHY */
379 if ((read_phy_reg(lp->PhyAddr, PHYREG_PHYID1) == 0x7) &&
380 ((read_phy_reg(lp->PhyAddr, PHYREG_PHYID2) & 0xfff0) == 0xC0A0)) {
381 /*
382 * we have SMSC PHY so reqest interrupt
383 * on link down condition
384 */
385
386 /* enable interrupts */
387 write_phy_reg(lp->PhyAddr, 30, 0x0ff);
388 } 412 }
413
414 spin_unlock_irqrestore(&lp->lock, flags);
389} 415}
390 416
391/**************************************************************************/ 417static int mii_probe(struct net_device *dev)
392void setup_system_regs(struct net_device *dev)
393{ 418{
394 int phyaddr;
395 unsigned short sysctl, phydat;
396 u32 opmode;
397 struct bf537mac_local *lp = netdev_priv(dev); 419 struct bf537mac_local *lp = netdev_priv(dev);
398 int count = 0; 420 struct phy_device *phydev = NULL;
399 421 unsigned short sysctl;
400 phyaddr = lp->PhyAddr; 422 int i;
401 423
402 /* Enable PHY output */ 424 /* Enable PHY output early */
403 if (!(bfin_read_VR_CTL() & PHYCLKOE)) 425 if (!(bfin_read_VR_CTL() & PHYCLKOE))
404 bfin_write_VR_CTL(bfin_read_VR_CTL() | PHYCLKOE); 426 bfin_write_VR_CTL(bfin_read_VR_CTL() | PHYCLKOE);
405 427
406 /* MDC = 2.5 MHz */ 428 /* MDC = 2.5 MHz */
407 sysctl = SET_MDCDIV(24); 429 sysctl = bfin_read_EMAC_SYSCTL();
408 /* Odd word alignment for Receive Frame DMA word */ 430 sysctl |= SET_MDCDIV(24);
409 /* Configure checksum support and rcve frame word alignment */
410#if defined(BFIN_MAC_CSUM_OFFLOAD)
411 sysctl |= RXDWA | RXCKS;
412#else
413 sysctl |= RXDWA;
414#endif
415 bfin_write_EMAC_SYSCTL(sysctl); 431 bfin_write_EMAC_SYSCTL(sysctl);
416 /* auto negotiation on */
417 /* full duplex */
418 /* 100 Mbps */
419 phydat = PHY_ANEG_EN | PHY_DUPLEX | PHY_SPD_SET;
420 write_phy_reg(phyaddr, PHYREG_MODECTL, phydat);
421 432
422 /* test if full duplex supported */ 433 /* search for connect PHY device */
423 do { 434 for (i = 0; i < PHY_MAX_ADDR; i++) {
424 msleep(100); 435 struct phy_device *const tmp_phydev = lp->mii_bus.phy_map[i];
425 phydat = read_phy_reg(phyaddr, PHYREG_MODESTAT);
426 if (count > 30) {
427 printk(KERN_NOTICE DRV_NAME ": Link is down\n");
428 printk(KERN_NOTICE DRV_NAME
429 "please check your network connection\n");
430 break;
431 }
432 count++;
433 } while (!(phydat & 0x0004));
434 436
435 phydat = read_phy_reg(phyaddr, PHYREG_ANLPAR); 437 if (!tmp_phydev)
438 continue; /* no PHY here... */
436 439
437 if ((phydat & 0x0100) || (phydat & 0x0040)) { 440 phydev = tmp_phydev;
438 opmode = FDMODE; 441 break; /* found it */
439 } else { 442 }
440 opmode = 0; 443
441 printk(KERN_INFO DRV_NAME 444 /* now we are supposed to have a proper phydev, to attach to... */
442 ": Network is set to half duplex\n"); 445 if (!phydev) {
446 printk(KERN_INFO "%s: Don't found any phy device at all\n",
447 dev->name);
448 return -ENODEV;
443 } 449 }
444 450
445#if defined(CONFIG_BFIN_MAC_RMII) 451#if defined(CONFIG_BFIN_MAC_RMII)
446 opmode |= RMII; /* For Now only 100MBit are supported */ 452 phydev = phy_connect(dev, phydev->dev.bus_id, &bf537_adjust_link, 0,
453 PHY_INTERFACE_MODE_RMII);
454#else
455 phydev = phy_connect(dev, phydev->dev.bus_id, &bf537_adjust_link, 0,
456 PHY_INTERFACE_MODE_MII);
447#endif 457#endif
448 458
449 bfin_write_EMAC_OPMODE(opmode); 459 if (IS_ERR(phydev)) {
460 printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
461 return PTR_ERR(phydev);
462 }
463
464 /* mask with MAC supported features */
465 phydev->supported &= (SUPPORTED_10baseT_Half
466 | SUPPORTED_10baseT_Full
467 | SUPPORTED_100baseT_Half
468 | SUPPORTED_100baseT_Full
469 | SUPPORTED_Autoneg
470 | SUPPORTED_Pause | SUPPORTED_Asym_Pause
471 | SUPPORTED_MII
472 | SUPPORTED_TP);
473
474 phydev->advertising = phydev->supported;
475
476 lp->old_link = 0;
477 lp->old_speed = 0;
478 lp->old_duplex = -1;
479 lp->phydev = phydev;
480
481 printk(KERN_INFO "%s: attached PHY driver [%s] "
482 "(mii_bus:phy_addr=%s, irq=%d)\n",
483 DRV_NAME, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
484
485 return 0;
486}
487
488/**************************************************************************/
489void setup_system_regs(struct net_device *dev)
490{
491 unsigned short sysctl;
492
493 /*
494 * Odd word alignment for Receive Frame DMA word
495 * Configure checksum support and rcve frame word alignment
496 */
497 sysctl = bfin_read_EMAC_SYSCTL();
498#if defined(BFIN_MAC_CSUM_OFFLOAD)
499 sysctl |= RXDWA | RXCKS;
500#else
501 sysctl |= RXDWA;
502#endif
503 bfin_write_EMAC_SYSCTL(sysctl);
450 504
451 bfin_write_EMAC_MMC_CTL(RSTC | CROLL); 505 bfin_write_EMAC_MMC_CTL(RSTC | CROLL);
452 506
@@ -686,18 +740,18 @@ static void bf537mac_disable(void)
686/* 740/*
687 * Enable Interrupts, Receive, and Transmit 741 * Enable Interrupts, Receive, and Transmit
688 */ 742 */
689static int bf537mac_enable(struct net_device *dev) 743static void bf537mac_enable(void)
690{ 744{
691 u32 opmode; 745 u32 opmode;
692 746
693 pr_debug("%s: %s\n", dev->name, __FUNCTION__); 747 pr_debug("%s: %s\n", DRV_NAME, __FUNCTION__);
694 748
695 /* Set RX DMA */ 749 /* Set RX DMA */
696 bfin_write_DMA1_NEXT_DESC_PTR(&(rx_list_head->desc_a)); 750 bfin_write_DMA1_NEXT_DESC_PTR(&(rx_list_head->desc_a));
697 bfin_write_DMA1_CONFIG(rx_list_head->desc_a.config); 751 bfin_write_DMA1_CONFIG(rx_list_head->desc_a.config);
698 752
699 /* Wait MII done */ 753 /* Wait MII done */
700 poll_mdc_done(); 754 mdio_poll();
701 755
702 /* We enable only RX here */ 756 /* We enable only RX here */
703 /* ASTP : Enable Automatic Pad Stripping 757 /* ASTP : Enable Automatic Pad Stripping
@@ -721,8 +775,6 @@ static int bf537mac_enable(struct net_device *dev)
721#endif 775#endif
722 /* Turn on the EMAC rx */ 776 /* Turn on the EMAC rx */
723 bfin_write_EMAC_OPMODE(opmode); 777 bfin_write_EMAC_OPMODE(opmode);
724
725 return 0;
726} 778}
727 779
728/* Our watchdog timed out. Called by the networking layer */ 780/* Our watchdog timed out. Called by the networking layer */
@@ -735,7 +787,7 @@ static void bf537mac_timeout(struct net_device *dev)
735 /* reset tx queue */ 787 /* reset tx queue */
736 tx_list_tail = tx_list_head->next; 788 tx_list_tail = tx_list_head->next;
737 789
738 bf537mac_enable(dev); 790 bf537mac_enable();
739 791
740 /* We can accept TX packets again */ 792 /* We can accept TX packets again */
741 dev->trans_start = jiffies; 793 dev->trans_start = jiffies;
@@ -789,6 +841,7 @@ static void bf537mac_shutdown(struct net_device *dev)
789 */ 841 */
790static int bf537mac_open(struct net_device *dev) 842static int bf537mac_open(struct net_device *dev)
791{ 843{
844 struct bf537mac_local *lp = netdev_priv(dev);
792 int retval; 845 int retval;
793 pr_debug("%s: %s\n", dev->name, __FUNCTION__); 846 pr_debug("%s: %s\n", dev->name, __FUNCTION__);
794 847
@@ -808,10 +861,10 @@ static int bf537mac_open(struct net_device *dev)
808 if (retval) 861 if (retval)
809 return retval; 862 return retval;
810 863
811 bf537mac_setphy(dev); 864 phy_start(lp->phydev);
812 setup_system_regs(dev); 865 setup_system_regs(dev);
813 bf537mac_disable(); 866 bf537mac_disable();
814 bf537mac_enable(dev); 867 bf537mac_enable();
815 868
816 pr_debug("hardware init finished\n"); 869 pr_debug("hardware init finished\n");
817 netif_start_queue(dev); 870 netif_start_queue(dev);
@@ -828,11 +881,14 @@ static int bf537mac_open(struct net_device *dev)
828 */ 881 */
829static int bf537mac_close(struct net_device *dev) 882static int bf537mac_close(struct net_device *dev)
830{ 883{
884 struct bf537mac_local *lp = netdev_priv(dev);
831 pr_debug("%s: %s\n", dev->name, __FUNCTION__); 885 pr_debug("%s: %s\n", dev->name, __FUNCTION__);
832 886
833 netif_stop_queue(dev); 887 netif_stop_queue(dev);
834 netif_carrier_off(dev); 888 netif_carrier_off(dev);
835 889
890 phy_stop(lp->phydev);
891
836 /* clear everything */ 892 /* clear everything */
837 bf537mac_shutdown(dev); 893 bf537mac_shutdown(dev);
838 894
@@ -846,6 +902,7 @@ static int __init bf537mac_probe(struct net_device *dev)
846{ 902{
847 struct bf537mac_local *lp = netdev_priv(dev); 903 struct bf537mac_local *lp = netdev_priv(dev);
848 int retval; 904 int retval;
905 int i;
849 906
850 /* Grab the MAC address in the MAC */ 907 /* Grab the MAC address in the MAC */
851 *(__le32 *) (&(dev->dev_addr[0])) = cpu_to_le32(bfin_read_EMAC_ADDRLO()); 908 *(__le32 *) (&(dev->dev_addr[0])) = cpu_to_le32(bfin_read_EMAC_ADDRLO());
@@ -862,7 +919,6 @@ static int __init bf537mac_probe(struct net_device *dev)
862 919
863 /* set the GPIO pins to Ethernet mode */ 920 /* set the GPIO pins to Ethernet mode */
864 retval = setup_pin_mux(1); 921 retval = setup_pin_mux(1);
865
866 if (retval) 922 if (retval)
867 return retval; 923 return retval;
868 924
@@ -880,6 +936,23 @@ static int __init bf537mac_probe(struct net_device *dev)
880 936
881 setup_mac_addr(dev->dev_addr); 937 setup_mac_addr(dev->dev_addr);
882 938
939 /* MDIO bus initial */
940 lp->mii_bus.priv = dev;
941 lp->mii_bus.read = mdiobus_read;
942 lp->mii_bus.write = mdiobus_write;
943 lp->mii_bus.reset = mdiobus_reset;
944 lp->mii_bus.name = "bfin_mac_mdio";
945 lp->mii_bus.id = 0;
946 lp->mii_bus.irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
947 for (i = 0; i < PHY_MAX_ADDR; ++i)
948 lp->mii_bus.irq[i] = PHY_POLL;
949
950 mdiobus_register(&lp->mii_bus);
951
952 retval = mii_probe(dev);
953 if (retval)
954 return retval;
955
883 /* Fill in the fields of the device structure with ethernet values. */ 956 /* Fill in the fields of the device structure with ethernet values. */
884 ether_setup(dev); 957 ether_setup(dev);
885 958
@@ -893,13 +966,6 @@ static int __init bf537mac_probe(struct net_device *dev)
893 dev->poll_controller = bf537mac_poll; 966 dev->poll_controller = bf537mac_poll;
894#endif 967#endif
895 968
896 /* fill in some of the fields */
897 lp->version = 1;
898 lp->PhyAddr = 0x01;
899 lp->CLKIN = 25;
900 lp->FullDuplex = 0;
901 lp->Negotiate = 1;
902 lp->FlowControl = 0;
903 spin_lock_init(&lp->lock); 969 spin_lock_init(&lp->lock);
904 970
905 /* now, enable interrupts */ 971 /* now, enable interrupts */
@@ -912,9 +978,6 @@ static int __init bf537mac_probe(struct net_device *dev)
912 return -EBUSY; 978 return -EBUSY;
913 } 979 }
914 980
915 /* Enable PHY output early */
916 if (!(bfin_read_VR_CTL() & PHYCLKOE))
917 bfin_write_VR_CTL(bfin_read_VR_CTL() | PHYCLKOE);
918 981
919 retval = register_netdev(dev); 982 retval = register_netdev(dev);
920 if (retval == 0) { 983 if (retval == 0) {