Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+3 −3
Original line number Original line Diff line number Diff line
@@ -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 {


	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;
+51 −73
Original line number Original line Diff line number Diff line
@@ -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,
	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,
	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)
	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)


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;
	}
	}
}
}


+4 −3
Original line number Original line Diff line number Diff line
@@ -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)


	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)


	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)