|
@@ -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,
|
|
|
|
- u8 *addr, unsigned op)
|
|
|
|
|
|
+static int
|
|
|
|
+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);
|
|
|
|
- if (rv != 0) {
|
|
|
|
- printk(KERN_ERR "ERROR. Could not send mac update\n");
|
|
|
|
- return rv;
|
|
|
|
|
|
+ return netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+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;
|
|
|
|
- adapter->mac_list = NULL;
|
|
|
|
|
|
+ list_splice_tail_init(&adapter->mac_list, &del_list);
|
|
|
|
|
|
- nx_p3_nic_add_mac(adapter, netdev->dev_addr, &add_list, &del_list);
|
|
|
|
- nx_p3_nic_add_mac(adapter, bcast_addr, &add_list, &del_list);
|
|
|
|
|
|
+ nx_p3_nic_add_mac(adapter, netdev->dev_addr, &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,
|
|
|
|
- &add_list, &del_list);
|
|
|
|
|
|
+ nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr, &del_list);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
send_fw_cmd:
|
|
send_fw_cmd:
|
|
adapter->set_promisc(adapter, mode);
|
|
adapter->set_promisc(adapter, mode);
|
|
- for (cur = del_list; cur;) {
|
|
|
|
- nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_DEL);
|
|
|
|
- next = cur->next;
|
|
|
|
|
|
+ head = &del_list;
|
|
|
|
+ while (!list_empty(head)) {
|
|
|
|
+ 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;
|
|
|
|
-
|
|
|
|
- cur = adapter->mac_list;
|
|
|
|
-
|
|
|
|
- while (cur) {
|
|
|
|
- next = cur->next;
|
|
|
|
|
|
+ nx_mac_list_t *cur;
|
|
|
|
+ struct list_head *head = &adapter->mac_list;
|
|
|
|
+
|
|
|
|
+ while (!list_empty(head)) {
|
|
|
|
+ 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;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|