aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethoc.c64
1 files changed, 44 insertions, 20 deletions
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
index 0c6c7f47ace4..6d82dc646ac0 100644
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -19,6 +19,10 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <net/ethoc.h> 20#include <net/ethoc.h>
21 21
22static int buffer_size = 0x8000; /* 32 KBytes */
23module_param(buffer_size, int, 0);
24MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size");
25
22/* register offsets */ 26/* register offsets */
23#define MODER 0x00 27#define MODER 0x00
24#define INT_SOURCE 0x04 28#define INT_SOURCE 0x04
@@ -167,6 +171,7 @@
167 * struct ethoc - driver-private device structure 171 * struct ethoc - driver-private device structure
168 * @iobase: pointer to I/O memory region 172 * @iobase: pointer to I/O memory region
169 * @membase: pointer to buffer memory region 173 * @membase: pointer to buffer memory region
174 * @dma_alloc: dma allocated buffer size
170 * @num_tx: number of send buffers 175 * @num_tx: number of send buffers
171 * @cur_tx: last send buffer written 176 * @cur_tx: last send buffer written
172 * @dty_tx: last buffer actually sent 177 * @dty_tx: last buffer actually sent
@@ -185,6 +190,7 @@
185struct ethoc { 190struct ethoc {
186 void __iomem *iobase; 191 void __iomem *iobase;
187 void __iomem *membase; 192 void __iomem *membase;
193 int dma_alloc;
188 194
189 unsigned int num_tx; 195 unsigned int num_tx;
190 unsigned int cur_tx; 196 unsigned int cur_tx;
@@ -906,22 +912,19 @@ static int ethoc_probe(struct platform_device *pdev)
906 912
907 /* obtain buffer memory space */ 913 /* obtain buffer memory space */
908 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 914 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
909 if (!res) { 915 if (res) {
910 dev_err(&pdev->dev, "cannot obtain memory space\n"); 916 mem = devm_request_mem_region(&pdev->dev, res->start,
911 ret = -ENXIO;
912 goto free;
913 }
914
915 mem = devm_request_mem_region(&pdev->dev, res->start,
916 res->end - res->start + 1, res->name); 917 res->end - res->start + 1, res->name);
917 if (!mem) { 918 if (!mem) {
918 dev_err(&pdev->dev, "cannot request memory space\n"); 919 dev_err(&pdev->dev, "cannot request memory space\n");
919 ret = -ENXIO; 920 ret = -ENXIO;
920 goto free; 921 goto free;
922 }
923
924 netdev->mem_start = mem->start;
925 netdev->mem_end = mem->end;
921 } 926 }
922 927
923 netdev->mem_start = mem->start;
924 netdev->mem_end = mem->end;
925 928
926 /* obtain device IRQ number */ 929 /* obtain device IRQ number */
927 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 930 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -936,6 +939,7 @@ static int ethoc_probe(struct platform_device *pdev)
936 /* setup driver-private data */ 939 /* setup driver-private data */
937 priv = netdev_priv(netdev); 940 priv = netdev_priv(netdev);
938 priv->netdev = netdev; 941 priv->netdev = netdev;
942 priv->dma_alloc = 0;
939 943
940 priv->iobase = devm_ioremap_nocache(&pdev->dev, netdev->base_addr, 944 priv->iobase = devm_ioremap_nocache(&pdev->dev, netdev->base_addr,
941 mmio->end - mmio->start + 1); 945 mmio->end - mmio->start + 1);
@@ -945,12 +949,27 @@ static int ethoc_probe(struct platform_device *pdev)
945 goto error; 949 goto error;
946 } 950 }
947 951
948 priv->membase = devm_ioremap_nocache(&pdev->dev, netdev->mem_start, 952 if (netdev->mem_end) {
949 mem->end - mem->start + 1); 953 priv->membase = devm_ioremap_nocache(&pdev->dev,
950 if (!priv->membase) { 954 netdev->mem_start, mem->end - mem->start + 1);
951 dev_err(&pdev->dev, "cannot remap memory space\n"); 955 if (!priv->membase) {
952 ret = -ENXIO; 956 dev_err(&pdev->dev, "cannot remap memory space\n");
953 goto error; 957 ret = -ENXIO;
958 goto error;
959 }
960 } else {
961 /* Allocate buffer memory */
962 priv->membase = dma_alloc_coherent(NULL,
963 buffer_size, (void *)&netdev->mem_start,
964 GFP_KERNEL);
965 if (!priv->membase) {
966 dev_err(&pdev->dev, "cannot allocate %dB buffer\n",
967 buffer_size);
968 ret = -ENOMEM;
969 goto error;
970 }
971 netdev->mem_end = netdev->mem_start + buffer_size;
972 priv->dma_alloc = buffer_size;
954 } 973 }
955 974
956 /* Allow the platform setup code to pass in a MAC address. */ 975 /* Allow the platform setup code to pass in a MAC address. */
@@ -1037,6 +1056,9 @@ free_mdio:
1037 kfree(priv->mdio->irq); 1056 kfree(priv->mdio->irq);
1038 mdiobus_free(priv->mdio); 1057 mdiobus_free(priv->mdio);
1039free: 1058free:
1059 if (priv->dma_alloc)
1060 dma_free_coherent(NULL, priv->dma_alloc, priv->membase,
1061 netdev->mem_start);
1040 free_netdev(netdev); 1062 free_netdev(netdev);
1041out: 1063out:
1042 return ret; 1064 return ret;
@@ -1062,7 +1084,9 @@ static int ethoc_remove(struct platform_device *pdev)
1062 kfree(priv->mdio->irq); 1084 kfree(priv->mdio->irq);
1063 mdiobus_free(priv->mdio); 1085 mdiobus_free(priv->mdio);
1064 } 1086 }
1065 1087 if (priv->dma_alloc)
1088 dma_free_coherent(NULL, priv->dma_alloc, priv->membase,
1089 netdev->mem_start);
1066 unregister_netdev(netdev); 1090 unregister_netdev(netdev);
1067 free_netdev(netdev); 1091 free_netdev(netdev);
1068 } 1092 }