diff options
Diffstat (limited to 'drivers/net/davinci_emac.c')
-rw-r--r-- | drivers/net/davinci_emac.c | 57 |
1 files changed, 37 insertions, 20 deletions
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 3f5db83c7cbb..32960b9b02ae 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c | |||
@@ -62,12 +62,11 @@ | |||
62 | #include <linux/bitops.h> | 62 | #include <linux/bitops.h> |
63 | #include <linux/io.h> | 63 | #include <linux/io.h> |
64 | #include <linux/uaccess.h> | 64 | #include <linux/uaccess.h> |
65 | #include <linux/davinci_emac.h> | ||
65 | 66 | ||
66 | #include <asm/irq.h> | 67 | #include <asm/irq.h> |
67 | #include <asm/page.h> | 68 | #include <asm/page.h> |
68 | 69 | ||
69 | #include <mach/emac.h> | ||
70 | |||
71 | static int debug_level; | 70 | static int debug_level; |
72 | module_param(debug_level, int, 0); | 71 | module_param(debug_level, int, 0); |
73 | MODULE_PARM_DESC(debug_level, "DaVinci EMAC debug level (NETIF_MSG bits)"); | 72 | MODULE_PARM_DESC(debug_level, "DaVinci EMAC debug level (NETIF_MSG bits)"); |
@@ -465,6 +464,7 @@ struct emac_priv { | |||
465 | void __iomem *ctrl_base; | 464 | void __iomem *ctrl_base; |
466 | void __iomem *emac_ctrl_ram; | 465 | void __iomem *emac_ctrl_ram; |
467 | u32 ctrl_ram_size; | 466 | u32 ctrl_ram_size; |
467 | u32 hw_ram_addr; | ||
468 | struct emac_txch *txch[EMAC_DEF_MAX_TX_CH]; | 468 | struct emac_txch *txch[EMAC_DEF_MAX_TX_CH]; |
469 | struct emac_rxch *rxch[EMAC_DEF_MAX_RX_CH]; | 469 | struct emac_rxch *rxch[EMAC_DEF_MAX_RX_CH]; |
470 | u32 link; /* 1=link on, 0=link off */ | 470 | u32 link; /* 1=link on, 0=link off */ |
@@ -488,6 +488,9 @@ struct emac_priv { | |||
488 | struct mii_bus *mii_bus; | 488 | struct mii_bus *mii_bus; |
489 | struct phy_device *phydev; | 489 | struct phy_device *phydev; |
490 | spinlock_t lock; | 490 | spinlock_t lock; |
491 | /*platform specific members*/ | ||
492 | void (*int_enable) (void); | ||
493 | void (*int_disable) (void); | ||
491 | }; | 494 | }; |
492 | 495 | ||
493 | /* clock frequency for EMAC */ | 496 | /* clock frequency for EMAC */ |
@@ -495,11 +498,9 @@ static struct clk *emac_clk; | |||
495 | static unsigned long emac_bus_frequency; | 498 | static unsigned long emac_bus_frequency; |
496 | static unsigned long mdio_max_freq; | 499 | static unsigned long mdio_max_freq; |
497 | 500 | ||
498 | /* EMAC internal utility function */ | 501 | #define emac_virt_to_phys(addr, priv) \ |
499 | static inline u32 emac_virt_to_phys(void __iomem *addr) | 502 | (((u32 __force)(addr) - (u32 __force)(priv->emac_ctrl_ram)) \ |
500 | { | 503 | + priv->hw_ram_addr) |
501 | return (u32 __force) io_v2p(addr); | ||
502 | } | ||
503 | 504 | ||
504 | /* Cache macros - Packet buffers would be from skb pool which is cached */ | 505 | /* Cache macros - Packet buffers would be from skb pool which is cached */ |
505 | #define EMAC_VIRT_NOCACHE(addr) (addr) | 506 | #define EMAC_VIRT_NOCACHE(addr) (addr) |
@@ -1001,6 +1002,8 @@ static void emac_int_disable(struct emac_priv *priv) | |||
1001 | emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0x0); | 1002 | emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0x0); |
1002 | emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0x0); | 1003 | emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0x0); |
1003 | /* NOTE: Rx Threshold and Misc interrupts are not disabled */ | 1004 | /* NOTE: Rx Threshold and Misc interrupts are not disabled */ |
1005 | if (priv->int_disable) | ||
1006 | priv->int_disable(); | ||
1004 | 1007 | ||
1005 | local_irq_restore(flags); | 1008 | local_irq_restore(flags); |
1006 | 1009 | ||
@@ -1020,6 +1023,9 @@ static void emac_int_disable(struct emac_priv *priv) | |||
1020 | static void emac_int_enable(struct emac_priv *priv) | 1023 | static void emac_int_enable(struct emac_priv *priv) |
1021 | { | 1024 | { |
1022 | if (priv->version == EMAC_VERSION_2) { | 1025 | if (priv->version == EMAC_VERSION_2) { |
1026 | if (priv->int_enable) | ||
1027 | priv->int_enable(); | ||
1028 | |||
1023 | emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0xff); | 1029 | emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0xff); |
1024 | emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0xff); | 1030 | emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0xff); |
1025 | 1031 | ||
@@ -1301,7 +1307,7 @@ static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget) | |||
1301 | curr_bd = txch->active_queue_head; | 1307 | curr_bd = txch->active_queue_head; |
1302 | if (NULL == curr_bd) { | 1308 | if (NULL == curr_bd) { |
1303 | emac_write(EMAC_TXCP(ch), | 1309 | emac_write(EMAC_TXCP(ch), |
1304 | emac_virt_to_phys(txch->last_hw_bdprocessed)); | 1310 | emac_virt_to_phys(txch->last_hw_bdprocessed, priv)); |
1305 | txch->no_active_pkts++; | 1311 | txch->no_active_pkts++; |
1306 | spin_unlock_irqrestore(&priv->tx_lock, flags); | 1312 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
1307 | return 0; | 1313 | return 0; |
@@ -1311,7 +1317,7 @@ static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget) | |||
1311 | while ((curr_bd) && | 1317 | while ((curr_bd) && |
1312 | ((frame_status & EMAC_CPPI_OWNERSHIP_BIT) == 0) && | 1318 | ((frame_status & EMAC_CPPI_OWNERSHIP_BIT) == 0) && |
1313 | (pkts_processed < budget)) { | 1319 | (pkts_processed < budget)) { |
1314 | emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd)); | 1320 | emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd, priv)); |
1315 | txch->active_queue_head = curr_bd->next; | 1321 | txch->active_queue_head = curr_bd->next; |
1316 | if (frame_status & EMAC_CPPI_EOQ_BIT) { | 1322 | if (frame_status & EMAC_CPPI_EOQ_BIT) { |
1317 | if (curr_bd->next) { /* misqueued packet */ | 1323 | if (curr_bd->next) { /* misqueued packet */ |
@@ -1398,7 +1404,7 @@ static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch) | |||
1398 | txch->active_queue_tail = curr_bd; | 1404 | txch->active_queue_tail = curr_bd; |
1399 | if (1 != txch->queue_active) { | 1405 | if (1 != txch->queue_active) { |
1400 | emac_write(EMAC_TXHDP(ch), | 1406 | emac_write(EMAC_TXHDP(ch), |
1401 | emac_virt_to_phys(curr_bd)); | 1407 | emac_virt_to_phys(curr_bd, priv)); |
1402 | txch->queue_active = 1; | 1408 | txch->queue_active = 1; |
1403 | } | 1409 | } |
1404 | ++txch->queue_reinit; | 1410 | ++txch->queue_reinit; |
@@ -1410,10 +1416,11 @@ static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch) | |||
1410 | tail_bd->next = curr_bd; | 1416 | tail_bd->next = curr_bd; |
1411 | txch->active_queue_tail = curr_bd; | 1417 | txch->active_queue_tail = curr_bd; |
1412 | tail_bd = EMAC_VIRT_NOCACHE(tail_bd); | 1418 | tail_bd = EMAC_VIRT_NOCACHE(tail_bd); |
1413 | tail_bd->h_next = (int)emac_virt_to_phys(curr_bd); | 1419 | tail_bd->h_next = (int)emac_virt_to_phys(curr_bd, priv); |
1414 | frame_status = tail_bd->mode; | 1420 | frame_status = tail_bd->mode; |
1415 | if (frame_status & EMAC_CPPI_EOQ_BIT) { | 1421 | if (frame_status & EMAC_CPPI_EOQ_BIT) { |
1416 | emac_write(EMAC_TXHDP(ch), emac_virt_to_phys(curr_bd)); | 1422 | emac_write(EMAC_TXHDP(ch), |
1423 | emac_virt_to_phys(curr_bd, priv)); | ||
1417 | frame_status &= ~(EMAC_CPPI_EOQ_BIT); | 1424 | frame_status &= ~(EMAC_CPPI_EOQ_BIT); |
1418 | tail_bd->mode = frame_status; | 1425 | tail_bd->mode = frame_status; |
1419 | ++txch->end_of_queue_add; | 1426 | ++txch->end_of_queue_add; |
@@ -1603,7 +1610,8 @@ static int emac_init_rxch(struct emac_priv *priv, u32 ch, char *param) | |||
1603 | } | 1610 | } |
1604 | 1611 | ||
1605 | /* populate the hardware descriptor */ | 1612 | /* populate the hardware descriptor */ |
1606 | curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head); | 1613 | curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head, |
1614 | priv); | ||
1607 | /* FIXME buff_ptr = dma_map_single(... data_ptr ...) */ | 1615 | /* FIXME buff_ptr = dma_map_single(... data_ptr ...) */ |
1608 | curr_bd->buff_ptr = virt_to_phys(curr_bd->data_ptr); | 1616 | curr_bd->buff_ptr = virt_to_phys(curr_bd->data_ptr); |
1609 | curr_bd->off_b_len = rxch->buf_size; | 1617 | curr_bd->off_b_len = rxch->buf_size; |
@@ -1878,7 +1886,7 @@ static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch, | |||
1878 | rxch->active_queue_tail = curr_bd; | 1886 | rxch->active_queue_tail = curr_bd; |
1879 | if (0 != rxch->queue_active) { | 1887 | if (0 != rxch->queue_active) { |
1880 | emac_write(EMAC_RXHDP(ch), | 1888 | emac_write(EMAC_RXHDP(ch), |
1881 | emac_virt_to_phys(rxch->active_queue_head)); | 1889 | emac_virt_to_phys(rxch->active_queue_head, priv)); |
1882 | rxch->queue_active = 1; | 1890 | rxch->queue_active = 1; |
1883 | } | 1891 | } |
1884 | } else { | 1892 | } else { |
@@ -1889,11 +1897,11 @@ static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch, | |||
1889 | rxch->active_queue_tail = curr_bd; | 1897 | rxch->active_queue_tail = curr_bd; |
1890 | tail_bd->next = curr_bd; | 1898 | tail_bd->next = curr_bd; |
1891 | tail_bd = EMAC_VIRT_NOCACHE(tail_bd); | 1899 | tail_bd = EMAC_VIRT_NOCACHE(tail_bd); |
1892 | tail_bd->h_next = emac_virt_to_phys(curr_bd); | 1900 | tail_bd->h_next = emac_virt_to_phys(curr_bd, priv); |
1893 | frame_status = tail_bd->mode; | 1901 | frame_status = tail_bd->mode; |
1894 | if (frame_status & EMAC_CPPI_EOQ_BIT) { | 1902 | if (frame_status & EMAC_CPPI_EOQ_BIT) { |
1895 | emac_write(EMAC_RXHDP(ch), | 1903 | emac_write(EMAC_RXHDP(ch), |
1896 | emac_virt_to_phys(curr_bd)); | 1904 | emac_virt_to_phys(curr_bd, priv)); |
1897 | frame_status &= ~(EMAC_CPPI_EOQ_BIT); | 1905 | frame_status &= ~(EMAC_CPPI_EOQ_BIT); |
1898 | tail_bd->mode = frame_status; | 1906 | tail_bd->mode = frame_status; |
1899 | ++rxch->end_of_queue_add; | 1907 | ++rxch->end_of_queue_add; |
@@ -1986,7 +1994,7 @@ static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget) | |||
1986 | curr_pkt->num_bufs = 1; | 1994 | curr_pkt->num_bufs = 1; |
1987 | curr_pkt->pkt_length = | 1995 | curr_pkt->pkt_length = |
1988 | (frame_status & EMAC_RX_BD_PKT_LENGTH_MASK); | 1996 | (frame_status & EMAC_RX_BD_PKT_LENGTH_MASK); |
1989 | emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd)); | 1997 | emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd, priv)); |
1990 | ++rxch->processed_bd; | 1998 | ++rxch->processed_bd; |
1991 | last_bd = curr_bd; | 1999 | last_bd = curr_bd; |
1992 | curr_bd = last_bd->next; | 2000 | curr_bd = last_bd->next; |
@@ -1997,7 +2005,7 @@ static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget) | |||
1997 | if (curr_bd) { | 2005 | if (curr_bd) { |
1998 | ++rxch->mis_queued_packets; | 2006 | ++rxch->mis_queued_packets; |
1999 | emac_write(EMAC_RXHDP(ch), | 2007 | emac_write(EMAC_RXHDP(ch), |
2000 | emac_virt_to_phys(curr_bd)); | 2008 | emac_virt_to_phys(curr_bd, priv)); |
2001 | } else { | 2009 | } else { |
2002 | ++rxch->end_of_queue; | 2010 | ++rxch->end_of_queue; |
2003 | rxch->queue_active = 0; | 2011 | rxch->queue_active = 0; |
@@ -2098,7 +2106,7 @@ static int emac_hw_enable(struct emac_priv *priv) | |||
2098 | emac_write(EMAC_RXINTMASKSET, BIT(ch)); | 2106 | emac_write(EMAC_RXINTMASKSET, BIT(ch)); |
2099 | rxch->queue_active = 1; | 2107 | rxch->queue_active = 1; |
2100 | emac_write(EMAC_RXHDP(ch), | 2108 | emac_write(EMAC_RXHDP(ch), |
2101 | emac_virt_to_phys(rxch->active_queue_head)); | 2109 | emac_virt_to_phys(rxch->active_queue_head, priv)); |
2102 | } | 2110 | } |
2103 | 2111 | ||
2104 | /* Enable MII */ | 2112 | /* Enable MII */ |
@@ -2377,7 +2385,7 @@ static int emac_dev_open(struct net_device *ndev) | |||
2377 | struct emac_priv *priv = netdev_priv(ndev); | 2385 | struct emac_priv *priv = netdev_priv(ndev); |
2378 | 2386 | ||
2379 | netif_carrier_off(ndev); | 2387 | netif_carrier_off(ndev); |
2380 | for (cnt = 0; cnt <= ETH_ALEN; cnt++) | 2388 | for (cnt = 0; cnt < ETH_ALEN; cnt++) |
2381 | ndev->dev_addr[cnt] = priv->mac_addr[cnt]; | 2389 | ndev->dev_addr[cnt] = priv->mac_addr[cnt]; |
2382 | 2390 | ||
2383 | /* Configuration items */ | 2391 | /* Configuration items */ |
@@ -2659,6 +2667,9 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) | |||
2659 | priv->phy_mask = pdata->phy_mask; | 2667 | priv->phy_mask = pdata->phy_mask; |
2660 | priv->rmii_en = pdata->rmii_en; | 2668 | priv->rmii_en = pdata->rmii_en; |
2661 | priv->version = pdata->version; | 2669 | priv->version = pdata->version; |
2670 | priv->int_enable = pdata->interrupt_enable; | ||
2671 | priv->int_disable = pdata->interrupt_disable; | ||
2672 | |||
2662 | emac_dev = &ndev->dev; | 2673 | emac_dev = &ndev->dev; |
2663 | /* Get EMAC platform data */ | 2674 | /* Get EMAC platform data */ |
2664 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2675 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -2690,6 +2701,12 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) | |||
2690 | priv->ctrl_ram_size = pdata->ctrl_ram_size; | 2701 | priv->ctrl_ram_size = pdata->ctrl_ram_size; |
2691 | priv->emac_ctrl_ram = priv->remap_addr + pdata->ctrl_ram_offset; | 2702 | priv->emac_ctrl_ram = priv->remap_addr + pdata->ctrl_ram_offset; |
2692 | 2703 | ||
2704 | if (pdata->hw_ram_addr) | ||
2705 | priv->hw_ram_addr = pdata->hw_ram_addr; | ||
2706 | else | ||
2707 | priv->hw_ram_addr = (u32 __force)res->start + | ||
2708 | pdata->ctrl_ram_offset; | ||
2709 | |||
2693 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 2710 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
2694 | if (!res) { | 2711 | if (!res) { |
2695 | dev_err(emac_dev, "DaVinci EMAC: Error getting irq res\n"); | 2712 | dev_err(emac_dev, "DaVinci EMAC: Error getting irq res\n"); |