|
@@ -464,6 +464,7 @@ struct emac_priv {
|
|
|
void __iomem *ctrl_base;
|
|
|
void __iomem *emac_ctrl_ram;
|
|
|
u32 ctrl_ram_size;
|
|
|
+ u32 hw_ram_addr;
|
|
|
struct emac_txch *txch[EMAC_DEF_MAX_TX_CH];
|
|
|
struct emac_rxch *rxch[EMAC_DEF_MAX_RX_CH];
|
|
|
u32 link; /* 1=link on, 0=link off */
|
|
@@ -497,11 +498,9 @@ static struct clk *emac_clk;
|
|
|
static unsigned long emac_bus_frequency;
|
|
|
static unsigned long mdio_max_freq;
|
|
|
|
|
|
-/* EMAC internal utility function */
|
|
|
-static inline u32 emac_virt_to_phys(void __iomem *addr)
|
|
|
-{
|
|
|
- return (u32 __force) io_v2p(addr);
|
|
|
-}
|
|
|
+#define emac_virt_to_phys(addr, priv) \
|
|
|
+ (((u32 __force)(addr) - (u32 __force)(priv->emac_ctrl_ram)) \
|
|
|
+ + priv->hw_ram_addr)
|
|
|
|
|
|
/* Cache macros - Packet buffers would be from skb pool which is cached */
|
|
|
#define EMAC_VIRT_NOCACHE(addr) (addr)
|
|
@@ -1309,7 +1308,7 @@ static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
|
|
|
curr_bd = txch->active_queue_head;
|
|
|
if (NULL == curr_bd) {
|
|
|
emac_write(EMAC_TXCP(ch),
|
|
|
- emac_virt_to_phys(txch->last_hw_bdprocessed));
|
|
|
+ emac_virt_to_phys(txch->last_hw_bdprocessed, priv));
|
|
|
txch->no_active_pkts++;
|
|
|
spin_unlock_irqrestore(&priv->tx_lock, flags);
|
|
|
return 0;
|
|
@@ -1319,7 +1318,7 @@ static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
|
|
|
while ((curr_bd) &&
|
|
|
((frame_status & EMAC_CPPI_OWNERSHIP_BIT) == 0) &&
|
|
|
(pkts_processed < budget)) {
|
|
|
- emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd));
|
|
|
+ emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd, priv));
|
|
|
txch->active_queue_head = curr_bd->next;
|
|
|
if (frame_status & EMAC_CPPI_EOQ_BIT) {
|
|
|
if (curr_bd->next) { /* misqueued packet */
|
|
@@ -1406,7 +1405,7 @@ static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch)
|
|
|
txch->active_queue_tail = curr_bd;
|
|
|
if (1 != txch->queue_active) {
|
|
|
emac_write(EMAC_TXHDP(ch),
|
|
|
- emac_virt_to_phys(curr_bd));
|
|
|
+ emac_virt_to_phys(curr_bd, priv));
|
|
|
txch->queue_active = 1;
|
|
|
}
|
|
|
++txch->queue_reinit;
|
|
@@ -1418,10 +1417,11 @@ static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch)
|
|
|
tail_bd->next = curr_bd;
|
|
|
txch->active_queue_tail = curr_bd;
|
|
|
tail_bd = EMAC_VIRT_NOCACHE(tail_bd);
|
|
|
- tail_bd->h_next = (int)emac_virt_to_phys(curr_bd);
|
|
|
+ tail_bd->h_next = (int)emac_virt_to_phys(curr_bd, priv);
|
|
|
frame_status = tail_bd->mode;
|
|
|
if (frame_status & EMAC_CPPI_EOQ_BIT) {
|
|
|
- emac_write(EMAC_TXHDP(ch), emac_virt_to_phys(curr_bd));
|
|
|
+ emac_write(EMAC_TXHDP(ch),
|
|
|
+ emac_virt_to_phys(curr_bd, priv));
|
|
|
frame_status &= ~(EMAC_CPPI_EOQ_BIT);
|
|
|
tail_bd->mode = frame_status;
|
|
|
++txch->end_of_queue_add;
|
|
@@ -1611,7 +1611,8 @@ static int emac_init_rxch(struct emac_priv *priv, u32 ch, char *param)
|
|
|
}
|
|
|
|
|
|
/* populate the hardware descriptor */
|
|
|
- curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head);
|
|
|
+ curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head,
|
|
|
+ priv);
|
|
|
/* FIXME buff_ptr = dma_map_single(... data_ptr ...) */
|
|
|
curr_bd->buff_ptr = virt_to_phys(curr_bd->data_ptr);
|
|
|
curr_bd->off_b_len = rxch->buf_size;
|
|
@@ -1886,7 +1887,7 @@ static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch,
|
|
|
rxch->active_queue_tail = curr_bd;
|
|
|
if (0 != rxch->queue_active) {
|
|
|
emac_write(EMAC_RXHDP(ch),
|
|
|
- emac_virt_to_phys(rxch->active_queue_head));
|
|
|
+ emac_virt_to_phys(rxch->active_queue_head, priv));
|
|
|
rxch->queue_active = 1;
|
|
|
}
|
|
|
} else {
|
|
@@ -1897,11 +1898,11 @@ static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch,
|
|
|
rxch->active_queue_tail = curr_bd;
|
|
|
tail_bd->next = curr_bd;
|
|
|
tail_bd = EMAC_VIRT_NOCACHE(tail_bd);
|
|
|
- tail_bd->h_next = emac_virt_to_phys(curr_bd);
|
|
|
+ tail_bd->h_next = emac_virt_to_phys(curr_bd, priv);
|
|
|
frame_status = tail_bd->mode;
|
|
|
if (frame_status & EMAC_CPPI_EOQ_BIT) {
|
|
|
emac_write(EMAC_RXHDP(ch),
|
|
|
- emac_virt_to_phys(curr_bd));
|
|
|
+ emac_virt_to_phys(curr_bd, priv));
|
|
|
frame_status &= ~(EMAC_CPPI_EOQ_BIT);
|
|
|
tail_bd->mode = frame_status;
|
|
|
++rxch->end_of_queue_add;
|
|
@@ -1994,7 +1995,7 @@ static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
|
|
|
curr_pkt->num_bufs = 1;
|
|
|
curr_pkt->pkt_length =
|
|
|
(frame_status & EMAC_RX_BD_PKT_LENGTH_MASK);
|
|
|
- emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd));
|
|
|
+ emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd, priv));
|
|
|
++rxch->processed_bd;
|
|
|
last_bd = curr_bd;
|
|
|
curr_bd = last_bd->next;
|
|
@@ -2005,7 +2006,7 @@ static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
|
|
|
if (curr_bd) {
|
|
|
++rxch->mis_queued_packets;
|
|
|
emac_write(EMAC_RXHDP(ch),
|
|
|
- emac_virt_to_phys(curr_bd));
|
|
|
+ emac_virt_to_phys(curr_bd, priv));
|
|
|
} else {
|
|
|
++rxch->end_of_queue;
|
|
|
rxch->queue_active = 0;
|
|
@@ -2106,7 +2107,7 @@ static int emac_hw_enable(struct emac_priv *priv)
|
|
|
emac_write(EMAC_RXINTMASKSET, BIT(ch));
|
|
|
rxch->queue_active = 1;
|
|
|
emac_write(EMAC_RXHDP(ch),
|
|
|
- emac_virt_to_phys(rxch->active_queue_head));
|
|
|
+ emac_virt_to_phys(rxch->active_queue_head, priv));
|
|
|
}
|
|
|
|
|
|
/* Enable MII */
|
|
@@ -2702,6 +2703,12 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
|
|
|
priv->ctrl_ram_size = pdata->ctrl_ram_size;
|
|
|
priv->emac_ctrl_ram = priv->remap_addr + pdata->ctrl_ram_offset;
|
|
|
|
|
|
+ if (pdata->hw_ram_addr)
|
|
|
+ priv->hw_ram_addr = pdata->hw_ram_addr;
|
|
|
+ else
|
|
|
+ priv->hw_ram_addr = (u32 __force)res->start +
|
|
|
+ pdata->ctrl_ram_offset;
|
|
|
+
|
|
|
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
|
|
if (!res) {
|
|
|
dev_err(emac_dev, "DaVinci EMAC: Error getting irq res\n");
|