diff options
Diffstat (limited to 'drivers/net/ll_temac_main.c')
-rw-r--r-- | drivers/net/ll_temac_main.c | 30 |
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 | ||
228 | static 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 | |||
227 | static void temac_set_multicast_list(struct net_device *ndev) | 235 | static 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 | ||
939 | static struct of_device_id temac_of_match[] __devinitdata = { | 948 | static 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 | }; |
943 | MODULE_DEVICE_TABLE(of, temac_of_match); | 955 | MODULE_DEVICE_TABLE(of, temac_of_match); |