Commit 5cf4d323 authored by Dhananjay Phadke's avatar Dhananjay Phadke Committed by David S. Miller

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: default avatarDhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 22527864
...@@ -1019,8 +1019,8 @@ typedef struct { ...@@ -1019,8 +1019,8 @@ typedef struct {
#define NETXEN_MAC_DEL 2 #define NETXEN_MAC_DEL 2
typedef struct nx_mac_list_s { typedef struct nx_mac_list_s {
struct nx_mac_list_s *next; struct list_head list;
uint8_t mac_addr[MAX_ADDR_LEN]; uint8_t mac_addr[ETH_ALEN+2];
} nx_mac_list_t; } nx_mac_list_t;
/* /*
...@@ -1213,7 +1213,7 @@ struct netxen_adapter { ...@@ -1213,7 +1213,7 @@ struct netxen_adapter {
struct net_device *netdev; struct net_device *netdev;
struct pci_dev *pdev; struct pci_dev *pdev;
nx_mac_list_t *mac_list; struct list_head mac_list;
u32 curr_window; u32 curr_window;
u32 crb_win; u32 crb_win;
......
...@@ -470,45 +470,6 @@ void netxen_p2_nic_set_multi(struct net_device *netdev) ...@@ -470,45 +470,6 @@ void netxen_p2_nic_set_multi(struct net_device *netdev)
netxen_nic_set_mcast_addr(adapter, index, null_addr); netxen_nic_set_mcast_addr(adapter, index, null_addr);
} }
static int nx_p3_nic_add_mac(struct netxen_adapter *adapter,
u8 *addr, nx_mac_list_t **add_list, nx_mac_list_t **del_list)
{
nx_mac_list_t *cur, *prev;
/* if in del_list, move it to adapter->mac_list */
for (cur = *del_list, prev = NULL; cur;) {
if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) {
if (prev == NULL)
*del_list = cur->next;
else
prev->next = cur->next;
cur->next = adapter->mac_list;
adapter->mac_list = cur;
return 0;
}
prev = cur;
cur = cur->next;
}
/* make sure to add each mac address only once */
for (cur = adapter->mac_list; cur; cur = cur->next) {
if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0)
return 0;
}
/* not in del_list, create new entry and add to add_list */
cur = kmalloc(sizeof(*cur), in_atomic()? GFP_ATOMIC : GFP_KERNEL);
if (cur == NULL) {
printk(KERN_ERR "%s: cannot allocate memory. MAC filtering may"
"not work properly from now.\n", __func__);
return -1;
}
memcpy(cur->mac_addr, addr, ETH_ALEN);
cur->next = *add_list;
*add_list = cur;
return 0;
}
static int static int
netxen_send_cmd_descs(struct netxen_adapter *adapter, netxen_send_cmd_descs(struct netxen_adapter *adapter,
struct cmd_desc_type0 *cmd_desc_arr, int nr_desc) struct cmd_desc_type0 *cmd_desc_arr, int nr_desc)
...@@ -555,14 +516,12 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, ...@@ -555,14 +516,12 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter,
return 0; return 0;
} }
static int nx_p3_sre_macaddr_change(struct net_device *dev, static int
u8 *addr, unsigned op) nx_p3_sre_macaddr_change(struct netxen_adapter *adapter, u8 *addr, unsigned op)
{ {
struct netxen_adapter *adapter = netdev_priv(dev);
nx_nic_req_t req; nx_nic_req_t req;
nx_mac_req_t *mac_req; nx_mac_req_t *mac_req;
u64 word; u64 word;
int rv;
memset(&req, 0, sizeof(nx_nic_req_t)); memset(&req, 0, sizeof(nx_nic_req_t));
req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23); 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,28 +533,51 @@ static int nx_p3_sre_macaddr_change(struct net_device *dev,
mac_req->op = op; mac_req->op = op;
memcpy(mac_req->mac_addr, addr, 6); memcpy(mac_req->mac_addr, addr, 6);
rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); return netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
if (rv != 0) { }
printk(KERN_ERR "ERROR. Could not send mac update\n");
return rv;
}
static int nx_p3_nic_add_mac(struct netxen_adapter *adapter,
u8 *addr, struct list_head *del_list)
{
struct list_head *head;
nx_mac_list_t *cur;
/* look up if already exists */
list_for_each(head, del_list) {
cur = list_entry(head, nx_mac_list_t, list);
if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) {
list_move_tail(head, &adapter->mac_list);
return 0; return 0;
}
}
cur = kzalloc(sizeof(nx_mac_list_t), GFP_ATOMIC);
if (cur == NULL) {
printk(KERN_ERR "%s: failed to add mac address filter\n",
adapter->netdev->name);
return -ENOMEM;
}
memcpy(cur->mac_addr, addr, ETH_ALEN);
list_add_tail(&cur->list, &adapter->mac_list);
return nx_p3_sre_macaddr_change(adapter,
cur->mac_addr, NETXEN_MAC_ADD);
} }
void netxen_p3_nic_set_multi(struct net_device *netdev) void netxen_p3_nic_set_multi(struct net_device *netdev)
{ {
struct netxen_adapter *adapter = netdev_priv(netdev); struct netxen_adapter *adapter = netdev_priv(netdev);
nx_mac_list_t *cur, *next, *del_list, *add_list = NULL;
struct dev_mc_list *mc_ptr; struct dev_mc_list *mc_ptr;
u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
u32 mode = VPORT_MISS_MODE_DROP; u32 mode = VPORT_MISS_MODE_DROP;
LIST_HEAD(del_list);
struct list_head *head;
nx_mac_list_t *cur;
del_list = adapter->mac_list; list_splice_tail_init(&adapter->mac_list, &del_list);
adapter->mac_list = NULL;
nx_p3_nic_add_mac(adapter, netdev->dev_addr, &add_list, &del_list); nx_p3_nic_add_mac(adapter, netdev->dev_addr, &del_list);
nx_p3_nic_add_mac(adapter, bcast_addr, &add_list, &del_list); nx_p3_nic_add_mac(adapter, bcast_addr, &del_list);
if (netdev->flags & IFF_PROMISC) { if (netdev->flags & IFF_PROMISC) {
mode = VPORT_MISS_MODE_ACCEPT_ALL; mode = VPORT_MISS_MODE_ACCEPT_ALL;
...@@ -611,25 +593,20 @@ void netxen_p3_nic_set_multi(struct net_device *netdev) ...@@ -611,25 +593,20 @@ void netxen_p3_nic_set_multi(struct net_device *netdev)
if (netdev->mc_count > 0) { if (netdev->mc_count > 0) {
for (mc_ptr = netdev->mc_list; mc_ptr; for (mc_ptr = netdev->mc_list; mc_ptr;
mc_ptr = mc_ptr->next) { mc_ptr = mc_ptr->next) {
nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr, nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr, &del_list);
&add_list, &del_list);
} }
} }
send_fw_cmd: send_fw_cmd:
adapter->set_promisc(adapter, mode); adapter->set_promisc(adapter, mode);
for (cur = del_list; cur;) { head = &del_list;
nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_DEL); while (!list_empty(head)) {
next = cur->next; cur = list_entry(head->next, nx_mac_list_t, list);
nx_p3_sre_macaddr_change(adapter,
cur->mac_addr, NETXEN_MAC_DEL);
list_del(&cur->list);
kfree(cur); kfree(cur);
cur = next;
}
for (cur = add_list; cur;) {
nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_ADD);
next = cur->next;
cur->next = adapter->mac_list;
adapter->mac_list = cur;
cur = next;
} }
} }
...@@ -654,14 +631,15 @@ int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) ...@@ -654,14 +631,15 @@ int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
void netxen_p3_free_mac_list(struct netxen_adapter *adapter) void netxen_p3_free_mac_list(struct netxen_adapter *adapter)
{ {
nx_mac_list_t *cur, *next; nx_mac_list_t *cur;
struct list_head *head = &adapter->mac_list;
cur = adapter->mac_list;
while (!list_empty(head)) {
while (cur) { cur = list_entry(head->next, nx_mac_list_t, list);
next = cur->next; nx_p3_sre_macaddr_change(adapter,
cur->mac_addr, NETXEN_MAC_DEL);
list_del(&cur->list);
kfree(cur); kfree(cur);
cur = next;
} }
} }
......
...@@ -815,6 +815,9 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) ...@@ -815,6 +815,9 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
if (adapter->stop_port) if (adapter->stop_port)
adapter->stop_port(adapter); adapter->stop_port(adapter);
if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
netxen_p3_free_mac_list(adapter);
netxen_release_tx_buffers(adapter); netxen_release_tx_buffers(adapter);
FLUSH_SCHEDULED_WORK(); FLUSH_SCHEDULED_WORK();
...@@ -961,6 +964,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -961,6 +964,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
rwlock_init(&adapter->adapter_lock); rwlock_init(&adapter->adapter_lock);
spin_lock_init(&adapter->tx_clean_lock); spin_lock_init(&adapter->tx_clean_lock);
INIT_LIST_HEAD(&adapter->mac_list);
err = netxen_setup_pci_map(adapter); err = netxen_setup_pci_map(adapter);
if (err) if (err)
...@@ -1114,9 +1118,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) ...@@ -1114,9 +1118,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
netxen_nic_detach(adapter); netxen_nic_detach(adapter);
if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
netxen_p3_free_mac_list(adapter);
} }
if (adapter->portnum == 0) if (adapter->portnum == 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment