summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethoc.c
diff options
context:
space:
mode:
authorJonas Bonn <jonas@southpole.se>2010-06-11 02:47:35 +0000
committerDavid S. Miller <davem@davemloft.net>2010-06-11 13:28:34 -0700
commitf8555ad0cfb0ba6cbc8729f337341fb11c82db89 (patch)
treec16c743438c26af94d959bc933a79208484a9277 /drivers/net/ethoc.c
parentc527f81475aaa18123eebe3d72a40a25d8e244af (diff)
downloadop-kernel-dev-f8555ad0cfb0ba6cbc8729f337341fb11c82db89.zip
op-kernel-dev-f8555ad0cfb0ba6cbc8729f337341fb11c82db89.tar.gz
ethoc: Write bus addresses to registers
The ethoc driver should be writing bus addresses to the ethoc registers, not virtual addresses. This patch adds an array to store the virtual addresses in and references that array when manipulating the contents of the buffer descriptors. Signed-off-by: Jonas Bonn <jonas@southpole.se> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethoc.c')
-rw-r--r--drivers/net/ethoc.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
index 68093cf..5904ad2 100644
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -180,6 +180,7 @@ MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size");
* @dty_tx: last buffer actually sent
* @num_rx: number of receive buffers
* @cur_rx: current receive buffer
+ * @vma: pointer to array of virtual memory addresses for buffers
* @netdev: pointer to network device structure
* @napi: NAPI structure
* @stats: network device statistics
@@ -203,6 +204,8 @@ struct ethoc {
unsigned int num_rx;
unsigned int cur_rx;
+ void** vma;
+
struct net_device *netdev;
struct napi_struct napi;
struct net_device_stats stats;
@@ -285,18 +288,20 @@ static inline void ethoc_disable_rx_and_tx(struct ethoc *dev)
ethoc_write(dev, MODER, mode);
}
-static int ethoc_init_ring(struct ethoc *dev)
+static int ethoc_init_ring(struct ethoc *dev, void* mem_start)
{
struct ethoc_bd bd;
int i;
+ void* vma;
dev->cur_tx = 0;
dev->dty_tx = 0;
dev->cur_rx = 0;
/* setup transmission buffers */
- bd.addr = virt_to_phys(dev->membase);
+ bd.addr = mem_start;
bd.stat = TX_BD_IRQ | TX_BD_CRC;
+ vma = dev->membase;
for (i = 0; i < dev->num_tx; i++) {
if (i == dev->num_tx - 1)
@@ -304,6 +309,9 @@ static int ethoc_init_ring(struct ethoc *dev)
ethoc_write_bd(dev, i, &bd);
bd.addr += ETHOC_BUFSIZ;
+
+ dev->vma[i] = vma;
+ vma += ETHOC_BUFSIZ;
}
bd.stat = RX_BD_EMPTY | RX_BD_IRQ;
@@ -314,6 +322,9 @@ static int ethoc_init_ring(struct ethoc *dev)
ethoc_write_bd(dev, dev->num_tx + i, &bd);
bd.addr += ETHOC_BUFSIZ;
+
+ dev->vma[dev->num_tx + i] = vma;
+ vma += ETHOC_BUFSIZ;
}
return 0;
@@ -415,7 +426,7 @@ static int ethoc_rx(struct net_device *dev, int limit)
skb = netdev_alloc_skb_ip_align(dev, size);
if (likely(skb)) {
- void *src = phys_to_virt(bd.addr);
+ void *src = priv->vma[entry];
memcpy_fromio(skb_put(skb, size), src, size);
skb->protocol = eth_type_trans(skb, dev);
priv->stats.rx_packets++;
@@ -667,7 +678,7 @@ static int ethoc_open(struct net_device *dev)
ethoc_write(priv, TX_BD_NUM, priv->num_tx);
- ethoc_init_ring(priv);
+ ethoc_init_ring(priv, (void*)dev->mem_start);
ethoc_reset(priv);
if (netif_queue_stopped(dev)) {
@@ -831,7 +842,7 @@ static netdev_tx_t ethoc_start_xmit(struct sk_buff *skb, struct net_device *dev)
else
bd.stat &= ~TX_BD_PAD;
- dest = phys_to_virt(bd.addr);
+ dest = priv->vma[entry];
memcpy_toio(dest, skb->data, skb->len);
bd.stat &= ~(TX_BD_STATS | TX_BD_LEN_MASK);
@@ -978,6 +989,12 @@ static int ethoc_probe(struct platform_device *pdev)
priv->num_tx = max(2, num_bd / 4);
priv->num_rx = num_bd - priv->num_tx;
+ priv->vma = devm_kzalloc(&pdev->dev, num_bd*sizeof(void*), GFP_KERNEL);
+ if (!priv->vma) {
+ ret = -ENOMEM;
+ goto error;
+ }
+
/* Allow the platform setup code to pass in a MAC address. */
if (pdev->dev.platform_data) {
struct ethoc_platform_data *pdata =
OpenPOWER on IntegriCloud