aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDhananjay Phadke <dhananjay@netxen.com>2009-05-05 15:05:07 -0400
committerDavid S. Miller <davem@davemloft.net>2009-05-06 18:33:36 -0400
commit5cf4d323f8864dab818d500ec74f2fcb9ad5bf89 (patch)
tree5f90365023b2b7a78852be460b770c5ae8731723
parent22527864ed7ee6c50f3c4d4b03c83c963caf5c0b (diff)
netxen: fix mac list management
o use standard linked list api for mac addr list management in NX3031. o release mac addresses in firmware in dev close(). Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/netxen/netxen_nic.h6
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c124
-rw-r--r--drivers/net/netxen/netxen_nic_main.c7
3 files changed, 58 insertions, 79 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 8dacfbb003e2..d368e24c0235 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1019,8 +1019,8 @@ typedef struct {
1019#define NETXEN_MAC_DEL 2 1019#define NETXEN_MAC_DEL 2
1020 1020
1021typedef struct nx_mac_list_s { 1021typedef struct nx_mac_list_s {
1022 struct nx_mac_list_s *next; 1022 struct list_head list;
1023 uint8_t mac_addr[MAX_ADDR_LEN]; 1023 uint8_t mac_addr[ETH_ALEN+2];
1024} nx_mac_list_t; 1024} nx_mac_list_t;
1025 1025
1026/* 1026/*
@@ -1213,7 +1213,7 @@ struct netxen_adapter {
1213 1213
1214 struct net_device *netdev; 1214 struct net_device *netdev;
1215 struct pci_dev *pdev; 1215 struct pci_dev *pdev;
1216 nx_mac_list_t *mac_list; 1216 struct list_head mac_list;
1217 1217
1218 u32 curr_window; 1218 u32 curr_window;
1219 u32 crb_win; 1219 u32 crb_win;
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 23c974a7e0e4..be643ea35233 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -470,45 +470,6 @@ void netxen_p2_nic_set_multi(struct net_device *netdev)
470 netxen_nic_set_mcast_addr(adapter, index, null_addr); 470 netxen_nic_set_mcast_addr(adapter, index, null_addr);
471} 471}
472 472
473static int nx_p3_nic_add_mac(struct netxen_adapter *adapter,
474 u8 *addr, nx_mac_list_t **add_list, nx_mac_list_t **del_list)
475{
476 nx_mac_list_t *cur, *prev;
477
478 /* if in del_list, move it to adapter->mac_list */
479 for (cur = *del_list, prev = NULL; cur;) {
480 if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) {
481 if (prev == NULL)
482 *del_list = cur->next;
483 else
484 prev->next = cur->next;
485 cur->next = adapter->mac_list;
486 adapter->mac_list = cur;
487 return 0;
488 }
489 prev = cur;
490 cur = cur->next;
491 }
492
493 /* make sure to add each mac address only once */
494 for (cur = adapter->mac_list; cur; cur = cur->next) {
495 if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0)
496 return 0;
497 }
498 /* not in del_list, create new entry and add to add_list */
499 cur = kmalloc(sizeof(*cur), in_atomic()? GFP_ATOMIC : GFP_KERNEL);
500 if (cur == NULL) {
501 printk(KERN_ERR "%s: cannot allocate memory. MAC filtering may"
502 "not work properly from now.\n", __func__);
503 return -1;
504 }
505
506 memcpy(cur->mac_addr, addr, ETH_ALEN);
507 cur->next = *add_list;
508 *add_list = cur;
509 return 0;
510}
511
512static int 473static int
513netxen_send_cmd_descs(struct netxen_adapter *adapter, 474netxen_send_cmd_descs(struct netxen_adapter *adapter,
514 struct cmd_desc_type0 *cmd_desc_arr, int nr_desc) 475 struct cmd_desc_type0 *cmd_desc_arr, int nr_desc)
@@ -555,14 +516,12 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter,
555 return 0; 516 return 0;
556} 517}
557 518
558static int nx_p3_sre_macaddr_change(struct net_device *dev, 519static int
559 u8 *addr, unsigned op) 520nx_p3_sre_macaddr_change(struct netxen_adapter *adapter, u8 *addr, unsigned op)
560{ 521{
561 struct netxen_adapter *adapter = netdev_priv(dev);
562 nx_nic_req_t req; 522 nx_nic_req_t req;
563 nx_mac_req_t *mac_req; 523 nx_mac_req_t *mac_req;
564 u64 word; 524 u64 word;
565 int rv;
566 525
567 memset(&req, 0, sizeof(nx_nic_req_t)); 526 memset(&req, 0, sizeof(nx_nic_req_t));
568 req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23); 527 req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23);
@@ -574,28 +533,51 @@ static int nx_p3_sre_macaddr_change(struct net_device *dev,
574 mac_req->op = op; 533 mac_req->op = op;
575 memcpy(mac_req->mac_addr, addr, 6); 534 memcpy(mac_req->mac_addr, addr, 6);
576 535
577 rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); 536 return netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
578 if (rv != 0) { 537}
579 printk(KERN_ERR "ERROR. Could not send mac update\n"); 538
580 return rv; 539static int nx_p3_nic_add_mac(struct netxen_adapter *adapter,
540 u8 *addr, struct list_head *del_list)
541{
542 struct list_head *head;
543 nx_mac_list_t *cur;
544
545 /* look up if already exists */
546 list_for_each(head, del_list) {
547 cur = list_entry(head, nx_mac_list_t, list);
548
549 if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) {
550 list_move_tail(head, &adapter->mac_list);
551 return 0;
552 }
581 } 553 }
582 554
583 return 0; 555 cur = kzalloc(sizeof(nx_mac_list_t), GFP_ATOMIC);
556 if (cur == NULL) {
557 printk(KERN_ERR "%s: failed to add mac address filter\n",
558 adapter->netdev->name);
559 return -ENOMEM;
560 }
561 memcpy(cur->mac_addr, addr, ETH_ALEN);
562 list_add_tail(&cur->list, &adapter->mac_list);
563 return nx_p3_sre_macaddr_change(adapter,
564 cur->mac_addr, NETXEN_MAC_ADD);
584} 565}
585 566
586void netxen_p3_nic_set_multi(struct net_device *netdev) 567void netxen_p3_nic_set_multi(struct net_device *netdev)
587{ 568{
588 struct netxen_adapter *adapter = netdev_priv(netdev); 569 struct netxen_adapter *adapter = netdev_priv(netdev);
589 nx_mac_list_t *cur, *next, *del_list, *add_list = NULL;
590 struct dev_mc_list *mc_ptr; 570 struct dev_mc_list *mc_ptr;
591 u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 571 u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
592 u32 mode = VPORT_MISS_MODE_DROP; 572 u32 mode = VPORT_MISS_MODE_DROP;
573 LIST_HEAD(del_list);
574 struct list_head *head;
575 nx_mac_list_t *cur;
593 576
594 del_list = adapter->mac_list; 577 list_splice_tail_init(&adapter->mac_list, &del_list);
595 adapter->mac_list = NULL;
596 578
597 nx_p3_nic_add_mac(adapter, netdev->dev_addr, &add_list, &del_list); 579 nx_p3_nic_add_mac(adapter, netdev->dev_addr, &del_list);
598 nx_p3_nic_add_mac(adapter, bcast_addr, &add_list, &del_list); 580 nx_p3_nic_add_mac(adapter, bcast_addr, &del_list);
599 581
600 if (netdev->flags & IFF_PROMISC) { 582 if (netdev->flags & IFF_PROMISC) {
601 mode = VPORT_MISS_MODE_ACCEPT_ALL; 583 mode = VPORT_MISS_MODE_ACCEPT_ALL;
@@ -611,25 +593,20 @@ void netxen_p3_nic_set_multi(struct net_device *netdev)
611 if (netdev->mc_count > 0) { 593 if (netdev->mc_count > 0) {
612 for (mc_ptr = netdev->mc_list; mc_ptr; 594 for (mc_ptr = netdev->mc_list; mc_ptr;
613 mc_ptr = mc_ptr->next) { 595 mc_ptr = mc_ptr->next) {
614 nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr, 596 nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr, &del_list);
615 &add_list, &del_list);
616 } 597 }
617 } 598 }
618 599
619send_fw_cmd: 600send_fw_cmd:
620 adapter->set_promisc(adapter, mode); 601 adapter->set_promisc(adapter, mode);
621 for (cur = del_list; cur;) { 602 head = &del_list;
622 nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_DEL); 603 while (!list_empty(head)) {
623 next = cur->next; 604 cur = list_entry(head->next, nx_mac_list_t, list);
605
606 nx_p3_sre_macaddr_change(adapter,
607 cur->mac_addr, NETXEN_MAC_DEL);
608 list_del(&cur->list);
624 kfree(cur); 609 kfree(cur);
625 cur = next;
626 }
627 for (cur = add_list; cur;) {
628 nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_ADD);
629 next = cur->next;
630 cur->next = adapter->mac_list;
631 adapter->mac_list = cur;
632 cur = next;
633 } 610 }
634} 611}
635 612
@@ -654,14 +631,15 @@ int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
654 631
655void netxen_p3_free_mac_list(struct netxen_adapter *adapter) 632void netxen_p3_free_mac_list(struct netxen_adapter *adapter)
656{ 633{
657 nx_mac_list_t *cur, *next; 634 nx_mac_list_t *cur;
658 635 struct list_head *head = &adapter->mac_list;
659 cur = adapter->mac_list; 636
660 637 while (!list_empty(head)) {
661 while (cur) { 638 cur = list_entry(head->next, nx_mac_list_t, list);
662 next = cur->next; 639 nx_p3_sre_macaddr_change(adapter,
640 cur->mac_addr, NETXEN_MAC_DEL);
641 list_del(&cur->list);
663 kfree(cur); 642 kfree(cur);
664 cur = next;
665 } 643 }
666} 644}
667 645
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 6a496b1909eb..a5577f8b6c0a 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -815,6 +815,9 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
815 if (adapter->stop_port) 815 if (adapter->stop_port)
816 adapter->stop_port(adapter); 816 adapter->stop_port(adapter);
817 817
818 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
819 netxen_p3_free_mac_list(adapter);
820
818 netxen_release_tx_buffers(adapter); 821 netxen_release_tx_buffers(adapter);
819 822
820 FLUSH_SCHEDULED_WORK(); 823 FLUSH_SCHEDULED_WORK();
@@ -961,6 +964,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
961 964
962 rwlock_init(&adapter->adapter_lock); 965 rwlock_init(&adapter->adapter_lock);
963 spin_lock_init(&adapter->tx_clean_lock); 966 spin_lock_init(&adapter->tx_clean_lock);
967 INIT_LIST_HEAD(&adapter->mac_list);
964 968
965 err = netxen_setup_pci_map(adapter); 969 err = netxen_setup_pci_map(adapter);
966 if (err) 970 if (err)
@@ -1114,9 +1118,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
1114 1118
1115 if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { 1119 if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
1116 netxen_nic_detach(adapter); 1120 netxen_nic_detach(adapter);
1117
1118 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
1119 netxen_p3_free_mac_list(adapter);
1120 } 1121 }
1121 1122
1122 if (adapter->portnum == 0) 1123 if (adapter->portnum == 0)