diff options
| -rw-r--r-- | drivers/net/ethoc.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index 68093cfa153b..5904ad284a01 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c | |||
| @@ -180,6 +180,7 @@ MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size"); | |||
| 180 | * @dty_tx: last buffer actually sent | 180 | * @dty_tx: last buffer actually sent |
| 181 | * @num_rx: number of receive buffers | 181 | * @num_rx: number of receive buffers |
| 182 | * @cur_rx: current receive buffer | 182 | * @cur_rx: current receive buffer |
| 183 | * @vma: pointer to array of virtual memory addresses for buffers | ||
| 183 | * @netdev: pointer to network device structure | 184 | * @netdev: pointer to network device structure |
| 184 | * @napi: NAPI structure | 185 | * @napi: NAPI structure |
| 185 | * @stats: network device statistics | 186 | * @stats: network device statistics |
| @@ -203,6 +204,8 @@ struct ethoc { | |||
| 203 | unsigned int num_rx; | 204 | unsigned int num_rx; |
| 204 | unsigned int cur_rx; | 205 | unsigned int cur_rx; |
| 205 | 206 | ||
| 207 | void** vma; | ||
| 208 | |||
| 206 | struct net_device *netdev; | 209 | struct net_device *netdev; |
| 207 | struct napi_struct napi; | 210 | struct napi_struct napi; |
| 208 | struct net_device_stats stats; | 211 | struct net_device_stats stats; |
| @@ -285,18 +288,20 @@ static inline void ethoc_disable_rx_and_tx(struct ethoc *dev) | |||
| 285 | ethoc_write(dev, MODER, mode); | 288 | ethoc_write(dev, MODER, mode); |
| 286 | } | 289 | } |
| 287 | 290 | ||
| 288 | static int ethoc_init_ring(struct ethoc *dev) | 291 | static int ethoc_init_ring(struct ethoc *dev, void* mem_start) |
| 289 | { | 292 | { |
| 290 | struct ethoc_bd bd; | 293 | struct ethoc_bd bd; |
| 291 | int i; | 294 | int i; |
| 295 | void* vma; | ||
| 292 | 296 | ||
| 293 | dev->cur_tx = 0; | 297 | dev->cur_tx = 0; |
| 294 | dev->dty_tx = 0; | 298 | dev->dty_tx = 0; |
| 295 | dev->cur_rx = 0; | 299 | dev->cur_rx = 0; |
| 296 | 300 | ||
| 297 | /* setup transmission buffers */ | 301 | /* setup transmission buffers */ |
| 298 | bd.addr = virt_to_phys(dev->membase); | 302 | bd.addr = mem_start; |
| 299 | bd.stat = TX_BD_IRQ | TX_BD_CRC; | 303 | bd.stat = TX_BD_IRQ | TX_BD_CRC; |
| 304 | vma = dev->membase; | ||
| 300 | 305 | ||
| 301 | for (i = 0; i < dev->num_tx; i++) { | 306 | for (i = 0; i < dev->num_tx; i++) { |
| 302 | if (i == dev->num_tx - 1) | 307 | if (i == dev->num_tx - 1) |
| @@ -304,6 +309,9 @@ static int ethoc_init_ring(struct ethoc *dev) | |||
| 304 | 309 | ||
| 305 | ethoc_write_bd(dev, i, &bd); | 310 | ethoc_write_bd(dev, i, &bd); |
| 306 | bd.addr += ETHOC_BUFSIZ; | 311 | bd.addr += ETHOC_BUFSIZ; |
| 312 | |||
| 313 | dev->vma[i] = vma; | ||
| 314 | vma += ETHOC_BUFSIZ; | ||
| 307 | } | 315 | } |
| 308 | 316 | ||
| 309 | bd.stat = RX_BD_EMPTY | RX_BD_IRQ; | 317 | bd.stat = RX_BD_EMPTY | RX_BD_IRQ; |
| @@ -314,6 +322,9 @@ static int ethoc_init_ring(struct ethoc *dev) | |||
| 314 | 322 | ||
| 315 | ethoc_write_bd(dev, dev->num_tx + i, &bd); | 323 | ethoc_write_bd(dev, dev->num_tx + i, &bd); |
| 316 | bd.addr += ETHOC_BUFSIZ; | 324 | bd.addr += ETHOC_BUFSIZ; |
| 325 | |||
| 326 | dev->vma[dev->num_tx + i] = vma; | ||
| 327 | vma += ETHOC_BUFSIZ; | ||
| 317 | } | 328 | } |
| 318 | 329 | ||
| 319 | return 0; | 330 | return 0; |
| @@ -415,7 +426,7 @@ static int ethoc_rx(struct net_device *dev, int limit) | |||
| 415 | skb = netdev_alloc_skb_ip_align(dev, size); | 426 | skb = netdev_alloc_skb_ip_align(dev, size); |
| 416 | 427 | ||
| 417 | if (likely(skb)) { | 428 | if (likely(skb)) { |
| 418 | void *src = phys_to_virt(bd.addr); | 429 | void *src = priv->vma[entry]; |
| 419 | memcpy_fromio(skb_put(skb, size), src, size); | 430 | memcpy_fromio(skb_put(skb, size), src, size); |
| 420 | skb->protocol = eth_type_trans(skb, dev); | 431 | skb->protocol = eth_type_trans(skb, dev); |
| 421 | priv->stats.rx_packets++; | 432 | priv->stats.rx_packets++; |
| @@ -667,7 +678,7 @@ static int ethoc_open(struct net_device *dev) | |||
| 667 | 678 | ||
| 668 | ethoc_write(priv, TX_BD_NUM, priv->num_tx); | 679 | ethoc_write(priv, TX_BD_NUM, priv->num_tx); |
| 669 | 680 | ||
| 670 | ethoc_init_ring(priv); | 681 | ethoc_init_ring(priv, (void*)dev->mem_start); |
| 671 | ethoc_reset(priv); | 682 | ethoc_reset(priv); |
| 672 | 683 | ||
| 673 | if (netif_queue_stopped(dev)) { | 684 | if (netif_queue_stopped(dev)) { |
| @@ -831,7 +842,7 @@ static netdev_tx_t ethoc_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 831 | else | 842 | else |
| 832 | bd.stat &= ~TX_BD_PAD; | 843 | bd.stat &= ~TX_BD_PAD; |
| 833 | 844 | ||
| 834 | dest = phys_to_virt(bd.addr); | 845 | dest = priv->vma[entry]; |
| 835 | memcpy_toio(dest, skb->data, skb->len); | 846 | memcpy_toio(dest, skb->data, skb->len); |
| 836 | 847 | ||
| 837 | bd.stat &= ~(TX_BD_STATS | TX_BD_LEN_MASK); | 848 | bd.stat &= ~(TX_BD_STATS | TX_BD_LEN_MASK); |
| @@ -978,6 +989,12 @@ static int ethoc_probe(struct platform_device *pdev) | |||
| 978 | priv->num_tx = max(2, num_bd / 4); | 989 | priv->num_tx = max(2, num_bd / 4); |
| 979 | priv->num_rx = num_bd - priv->num_tx; | 990 | priv->num_rx = num_bd - priv->num_tx; |
| 980 | 991 | ||
| 992 | priv->vma = devm_kzalloc(&pdev->dev, num_bd*sizeof(void*), GFP_KERNEL); | ||
| 993 | if (!priv->vma) { | ||
| 994 | ret = -ENOMEM; | ||
| 995 | goto error; | ||
| 996 | } | ||
| 997 | |||
| 981 | /* Allow the platform setup code to pass in a MAC address. */ | 998 | /* Allow the platform setup code to pass in a MAC address. */ |
| 982 | if (pdev->dev.platform_data) { | 999 | if (pdev->dev.platform_data) { |
| 983 | struct ethoc_platform_data *pdata = | 1000 | struct ethoc_platform_data *pdata = |
