diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 6 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 124 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 7 |
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 | ||
1021 | typedef struct nx_mac_list_s { | 1021 | typedef 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 | ||
473 | static 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 | |||
512 | static int | 473 | static int |
513 | netxen_send_cmd_descs(struct netxen_adapter *adapter, | 474 | netxen_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 | ||
558 | static int nx_p3_sre_macaddr_change(struct net_device *dev, | 519 | static int |
559 | u8 *addr, unsigned op) | 520 | nx_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; | 539 | static 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 | ||
586 | void netxen_p3_nic_set_multi(struct net_device *netdev) | 567 | void 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 | ||
619 | send_fw_cmd: | 600 | send_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 | ||
655 | void netxen_p3_free_mac_list(struct netxen_adapter *adapter) | 632 | void 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) |