aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ll_temac_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ll_temac_main.c')
-rw-r--r--drivers/net/ll_temac_main.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c
index f2a197fd47a5..ba617e3cf1bb 100644
--- a/drivers/net/ll_temac_main.c
+++ b/drivers/net/ll_temac_main.c
@@ -49,6 +49,7 @@
49#include <linux/in.h> 49#include <linux/in.h>
50#include <linux/io.h> 50#include <linux/io.h>
51#include <linux/ip.h> 51#include <linux/ip.h>
52#include <linux/slab.h>
52 53
53#include "ll_temac.h" 54#include "ll_temac.h"
54 55
@@ -134,7 +135,7 @@ static int temac_dma_bd_init(struct net_device *ndev)
134 struct sk_buff *skb; 135 struct sk_buff *skb;
135 int i; 136 int i;
136 137
137 lp->rx_skb = kzalloc(sizeof(struct sk_buff)*RX_BD_NUM, GFP_KERNEL); 138 lp->rx_skb = kzalloc(sizeof(*lp->rx_skb) * RX_BD_NUM, GFP_KERNEL);
138 /* allocate the tx and rx ring buffer descriptors. */ 139 /* allocate the tx and rx ring buffer descriptors. */
139 /* returns a virtual addres and a physical address. */ 140 /* returns a virtual addres and a physical address. */
140 lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent, 141 lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent,
@@ -224,6 +225,13 @@ static int temac_set_mac_address(struct net_device *ndev, void *address)
224 return 0; 225 return 0;
225} 226}
226 227
228static int netdev_set_mac_address(struct net_device *ndev, void *p)
229{
230 struct sockaddr *addr = p;
231
232 return temac_set_mac_address(ndev, addr->sa_data);
233}
234
227static void temac_set_multicast_list(struct net_device *ndev) 235static void temac_set_multicast_list(struct net_device *ndev)
228{ 236{
229 struct temac_local *lp = netdev_priv(ndev); 237 struct temac_local *lp = netdev_priv(ndev);
@@ -231,8 +239,8 @@ static void temac_set_multicast_list(struct net_device *ndev)
231 int i; 239 int i;
232 240
233 mutex_lock(&lp->indirect_mutex); 241 mutex_lock(&lp->indirect_mutex);
234 if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC) 242 if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC) ||
235 || ndev->mc_count > MULTICAST_CAM_TABLE_NUM) { 243 netdev_mc_count(ndev) > MULTICAST_CAM_TABLE_NUM) {
236 /* 244 /*
237 * We must make the kernel realise we had to move 245 * We must make the kernel realise we had to move
238 * into promisc mode or we start all out war on 246 * into promisc mode or we start all out war on
@@ -242,10 +250,11 @@ static void temac_set_multicast_list(struct net_device *ndev)
242 ndev->flags |= IFF_PROMISC; 250 ndev->flags |= IFF_PROMISC;
243 temac_indirect_out32(lp, XTE_AFM_OFFSET, XTE_AFM_EPPRM_MASK); 251 temac_indirect_out32(lp, XTE_AFM_OFFSET, XTE_AFM_EPPRM_MASK);
244 dev_info(&ndev->dev, "Promiscuous mode enabled.\n"); 252 dev_info(&ndev->dev, "Promiscuous mode enabled.\n");
245 } else if (ndev->mc_count) { 253 } else if (!netdev_mc_empty(ndev)) {
246 struct dev_mc_list *mclist = ndev->mc_list; 254 struct dev_mc_list *mclist;
247 for (i = 0; mclist && i < ndev->mc_count; i++) {
248 255
256 i = 0;
257 netdev_for_each_mc_addr(mclist, ndev) {
249 if (i >= MULTICAST_CAM_TABLE_NUM) 258 if (i >= MULTICAST_CAM_TABLE_NUM)
250 break; 259 break;
251 multi_addr_msw = ((mclist->dmi_addr[3] << 24) | 260 multi_addr_msw = ((mclist->dmi_addr[3] << 24) |
@@ -258,7 +267,7 @@ static void temac_set_multicast_list(struct net_device *ndev)
258 (mclist->dmi_addr[4]) | (i << 16)); 267 (mclist->dmi_addr[4]) | (i << 16));
259 temac_indirect_out32(lp, XTE_MAW1_OFFSET, 268 temac_indirect_out32(lp, XTE_MAW1_OFFSET,
260 multi_addr_lsw); 269 multi_addr_lsw);
261 mclist = mclist->next; 270 i++;
262 } 271 }
263 } else { 272 } else {
264 val = temac_indirect_in32(lp, XTE_AFM_OFFSET); 273 val = temac_indirect_in32(lp, XTE_AFM_OFFSET);
@@ -615,7 +624,7 @@ static void ll_temac_recv(struct net_device *ndev)
615 while ((bdstat & STS_CTRL_APP0_CMPLT)) { 624 while ((bdstat & STS_CTRL_APP0_CMPLT)) {
616 625
617 skb = lp->rx_skb[lp->rx_bd_ci]; 626 skb = lp->rx_skb[lp->rx_bd_ci];
618 length = cur_p->app4; 627 length = cur_p->app4 & 0x3FFF;
619 628
620 skb_vaddr = virt_to_bus(skb->data); 629 skb_vaddr = virt_to_bus(skb->data);
621 dma_unmap_single(ndev->dev.parent, skb_vaddr, length, 630 dma_unmap_single(ndev->dev.parent, skb_vaddr, length,
@@ -768,7 +777,7 @@ static const struct net_device_ops temac_netdev_ops = {
768 .ndo_open = temac_open, 777 .ndo_open = temac_open,
769 .ndo_stop = temac_stop, 778 .ndo_stop = temac_stop,
770 .ndo_start_xmit = temac_start_xmit, 779 .ndo_start_xmit = temac_start_xmit,
771 .ndo_set_mac_address = temac_set_mac_address, 780 .ndo_set_mac_address = netdev_set_mac_address,
772 //.ndo_set_multicast_list = temac_set_multicast_list, 781 //.ndo_set_multicast_list = temac_set_multicast_list,
773#ifdef CONFIG_NET_POLL_CONTROLLER 782#ifdef CONFIG_NET_POLL_CONTROLLER
774 .ndo_poll_controller = temac_poll_controller, 783 .ndo_poll_controller = temac_poll_controller,
@@ -938,6 +947,9 @@ static int __devexit temac_of_remove(struct of_device *op)
938 947
939static struct of_device_id temac_of_match[] __devinitdata = { 948static struct of_device_id temac_of_match[] __devinitdata = {
940 { .compatible = "xlnx,xps-ll-temac-1.01.b", }, 949 { .compatible = "xlnx,xps-ll-temac-1.01.b", },
950 { .compatible = "xlnx,xps-ll-temac-2.00.a", },
951 { .compatible = "xlnx,xps-ll-temac-2.02.a", },
952 { .compatible = "xlnx,xps-ll-temac-2.03.a", },
941 {}, 953 {},
942}; 954};
943MODULE_DEVICE_TABLE(of, temac_of_match); 955MODULE_DEVICE_TABLE(of, temac_of_match);