diff options
author | Shahed Shaikh <shahed.shaikh@qlogic.com> | 2013-02-18 08:22:37 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-02-19 00:47:01 -0500 |
commit | 53643a75b147bfb30f3488a4eaf5a59bfeeb39bb (patch) | |
tree | 7235a9db539637feb24c09e34b6ea5b2ff12dc35 | |
parent | 99e8587900a3d32b1eaa3a92da90b49e9d4ff765 (diff) |
qlcnic: fix ping resumption to a VM after a live migration
Delete the MAC address of a VM, from the adapter's embedded switch,
after the VM had been migrated out of this adapter/server.
Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | 18 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 145 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 21 |
4 files changed, 177 insertions, 12 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 61b594c6d9d7..01e9ea149da0 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | |||
@@ -1008,9 +1008,12 @@ struct qlcnic_adapter { | |||
1008 | struct delayed_work idc_aen_work; | 1008 | struct delayed_work idc_aen_work; |
1009 | 1009 | ||
1010 | struct qlcnic_filter_hash fhash; | 1010 | struct qlcnic_filter_hash fhash; |
1011 | struct qlcnic_filter_hash rx_fhash; | ||
1011 | 1012 | ||
1012 | spinlock_t tx_clean_lock; | 1013 | spinlock_t tx_clean_lock; |
1013 | spinlock_t mac_learn_lock; | 1014 | spinlock_t mac_learn_lock; |
1015 | /* spinlock for catching rcv filters for eswitch traffic */ | ||
1016 | spinlock_t rx_mac_learn_lock; | ||
1014 | u32 file_prd_off; /*File fw product offset*/ | 1017 | u32 file_prd_off; /*File fw product offset*/ |
1015 | u32 fw_version; | 1018 | u32 fw_version; |
1016 | const struct firmware *fw; | 1019 | const struct firmware *fw; |
@@ -1506,6 +1509,8 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *); | |||
1506 | int qlcnic_set_default_offload_settings(struct qlcnic_adapter *); | 1509 | int qlcnic_set_default_offload_settings(struct qlcnic_adapter *); |
1507 | int qlcnic_reset_npar_config(struct qlcnic_adapter *); | 1510 | int qlcnic_reset_npar_config(struct qlcnic_adapter *); |
1508 | int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *); | 1511 | int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *); |
1512 | void qlcnic_add_lb_filter(struct qlcnic_adapter *, struct sk_buff *, int, | ||
1513 | __le16); | ||
1509 | /* | 1514 | /* |
1510 | * QLOGIC Board information | 1515 | * QLOGIC Board information |
1511 | */ | 1516 | */ |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index 51716ab8739a..325e11e1ce0f 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | |||
@@ -578,7 +578,8 @@ void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter) | |||
578 | struct qlcnic_filter *tmp_fil; | 578 | struct qlcnic_filter *tmp_fil; |
579 | struct hlist_node *tmp_hnode, *n; | 579 | struct hlist_node *tmp_hnode, *n; |
580 | struct hlist_head *head; | 580 | struct hlist_head *head; |
581 | int i, time; | 581 | int i; |
582 | unsigned long time; | ||
582 | u8 cmd; | 583 | u8 cmd; |
583 | 584 | ||
584 | for (i = 0; i < adapter->fhash.fbucket_size; i++) { | 585 | for (i = 0; i < adapter->fhash.fbucket_size; i++) { |
@@ -600,6 +601,21 @@ void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter) | |||
600 | } | 601 | } |
601 | } | 602 | } |
602 | } | 603 | } |
604 | for (i = 0; i < adapter->rx_fhash.fbucket_size; i++) { | ||
605 | head = &(adapter->rx_fhash.fhead[i]); | ||
606 | |||
607 | hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) | ||
608 | { | ||
609 | time = tmp_fil->ftime; | ||
610 | if (jiffies > (QLCNIC_FILTER_AGE * HZ + time)) { | ||
611 | spin_lock_bh(&adapter->rx_mac_learn_lock); | ||
612 | adapter->rx_fhash.fnum--; | ||
613 | hlist_del(&tmp_fil->fnode); | ||
614 | spin_unlock_bh(&adapter->rx_mac_learn_lock); | ||
615 | kfree(tmp_fil); | ||
616 | } | ||
617 | } | ||
618 | } | ||
603 | } | 619 | } |
604 | 620 | ||
605 | void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter) | 621 | void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter) |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c index 2990f45df787..6387e0cc3ea9 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | |||
@@ -152,6 +152,89 @@ static inline u32 qlcnic_get_ref_handle(struct qlcnic_adapter *adapter, | |||
152 | return handle; | 152 | return handle; |
153 | } | 153 | } |
154 | 154 | ||
155 | static inline int qlcnic_82xx_is_lb_pkt(u64 sts_data) | ||
156 | { | ||
157 | return (qlcnic_get_sts_status(sts_data) == STATUS_CKSUM_LOOP) ? 1 : 0; | ||
158 | } | ||
159 | |||
160 | void qlcnic_add_lb_filter(struct qlcnic_adapter *adapter, struct sk_buff *skb, | ||
161 | int loopback_pkt, __le16 vlan_id) | ||
162 | { | ||
163 | struct ethhdr *phdr = (struct ethhdr *)(skb->data); | ||
164 | struct qlcnic_filter *fil, *tmp_fil; | ||
165 | struct hlist_node *tmp_hnode, *n; | ||
166 | struct hlist_head *head; | ||
167 | unsigned long time; | ||
168 | u64 src_addr = 0; | ||
169 | u8 hindex, found = 0, op; | ||
170 | int ret; | ||
171 | |||
172 | memcpy(&src_addr, phdr->h_source, ETH_ALEN); | ||
173 | |||
174 | if (loopback_pkt) { | ||
175 | if (adapter->rx_fhash.fnum >= adapter->rx_fhash.fmax) | ||
176 | return; | ||
177 | |||
178 | hindex = qlcnic_mac_hash(src_addr) & | ||
179 | (adapter->fhash.fbucket_size - 1); | ||
180 | head = &(adapter->rx_fhash.fhead[hindex]); | ||
181 | |||
182 | hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) { | ||
183 | if (!memcmp(tmp_fil->faddr, &src_addr, ETH_ALEN) && | ||
184 | tmp_fil->vlan_id == vlan_id) { | ||
185 | time = tmp_fil->ftime; | ||
186 | if (jiffies > (QLCNIC_READD_AGE * HZ + time)) | ||
187 | tmp_fil->ftime = jiffies; | ||
188 | return; | ||
189 | } | ||
190 | } | ||
191 | |||
192 | fil = kzalloc(sizeof(struct qlcnic_filter), GFP_ATOMIC); | ||
193 | if (!fil) | ||
194 | return; | ||
195 | |||
196 | fil->ftime = jiffies; | ||
197 | memcpy(fil->faddr, &src_addr, ETH_ALEN); | ||
198 | fil->vlan_id = vlan_id; | ||
199 | spin_lock(&adapter->rx_mac_learn_lock); | ||
200 | hlist_add_head(&(fil->fnode), head); | ||
201 | adapter->rx_fhash.fnum++; | ||
202 | spin_unlock(&adapter->rx_mac_learn_lock); | ||
203 | } else { | ||
204 | hindex = qlcnic_mac_hash(src_addr) & | ||
205 | (adapter->fhash.fbucket_size - 1); | ||
206 | head = &(adapter->rx_fhash.fhead[hindex]); | ||
207 | spin_lock(&adapter->rx_mac_learn_lock); | ||
208 | hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) { | ||
209 | if (!memcmp(tmp_fil->faddr, &src_addr, ETH_ALEN) && | ||
210 | tmp_fil->vlan_id == vlan_id) { | ||
211 | found = 1; | ||
212 | break; | ||
213 | } | ||
214 | } | ||
215 | |||
216 | if (!found) { | ||
217 | spin_unlock(&adapter->rx_mac_learn_lock); | ||
218 | return; | ||
219 | } | ||
220 | |||
221 | op = vlan_id ? QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_ADD; | ||
222 | ret = qlcnic_sre_macaddr_change(adapter, (u8 *)&src_addr, | ||
223 | vlan_id, op); | ||
224 | if (!ret) { | ||
225 | op = vlan_id ? QLCNIC_MAC_VLAN_DEL : QLCNIC_MAC_DEL; | ||
226 | ret = qlcnic_sre_macaddr_change(adapter, | ||
227 | (u8 *)&src_addr, | ||
228 | vlan_id, op); | ||
229 | if (!ret) { | ||
230 | hlist_del(&(tmp_fil->fnode)); | ||
231 | adapter->rx_fhash.fnum--; | ||
232 | } | ||
233 | } | ||
234 | spin_unlock(&adapter->rx_mac_learn_lock); | ||
235 | } | ||
236 | } | ||
237 | |||
155 | void qlcnic_82xx_change_filter(struct qlcnic_adapter *adapter, u64 *uaddr, | 238 | void qlcnic_82xx_change_filter(struct qlcnic_adapter *adapter, u64 *uaddr, |
156 | __le16 vlan_id) | 239 | __le16 vlan_id) |
157 | { | 240 | { |
@@ -207,9 +290,6 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter, | |||
207 | return; | 290 | return; |
208 | } | 291 | } |
209 | 292 | ||
210 | /* Only NPAR capable devices support vlan based learning */ | ||
211 | if (adapter->flags & QLCNIC_ESWITCH_ENABLED) | ||
212 | vlan_id = first_desc->vlan_TCI; | ||
213 | memcpy(&src_addr, phdr->h_source, ETH_ALEN); | 293 | memcpy(&src_addr, phdr->h_source, ETH_ALEN); |
214 | hindex = qlcnic_mac_hash(src_addr) & (adapter->fhash.fbucket_size - 1); | 294 | hindex = qlcnic_mac_hash(src_addr) & (adapter->fhash.fbucket_size - 1); |
215 | head = &(adapter->fhash.fhead[hindex]); | 295 | head = &(adapter->fhash.fhead[hindex]); |
@@ -920,8 +1000,8 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter, | |||
920 | struct qlcnic_rx_buffer *buffer; | 1000 | struct qlcnic_rx_buffer *buffer; |
921 | struct sk_buff *skb; | 1001 | struct sk_buff *skb; |
922 | struct qlcnic_host_rds_ring *rds_ring; | 1002 | struct qlcnic_host_rds_ring *rds_ring; |
923 | int index, length, cksum, pkt_offset; | 1003 | int index, length, cksum, pkt_offset, is_lb_pkt; |
924 | u16 vid = 0xffff; | 1004 | u16 vid = 0xffff, t_vid; |
925 | 1005 | ||
926 | if (unlikely(ring >= adapter->max_rds_rings)) | 1006 | if (unlikely(ring >= adapter->max_rds_rings)) |
927 | return NULL; | 1007 | return NULL; |
@@ -941,6 +1021,14 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter, | |||
941 | if (!skb) | 1021 | if (!skb) |
942 | return buffer; | 1022 | return buffer; |
943 | 1023 | ||
1024 | if (adapter->drv_mac_learn && | ||
1025 | (adapter->flags & QLCNIC_ESWITCH_ENABLED)) { | ||
1026 | t_vid = 0; | ||
1027 | is_lb_pkt = qlcnic_82xx_is_lb_pkt(sts_data0); | ||
1028 | qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, | ||
1029 | cpu_to_le16(t_vid)); | ||
1030 | } | ||
1031 | |||
944 | if (length > rds_ring->skb_size) | 1032 | if (length > rds_ring->skb_size) |
945 | skb_put(skb, rds_ring->skb_size); | 1033 | skb_put(skb, rds_ring->skb_size); |
946 | else | 1034 | else |
@@ -985,8 +1073,8 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, | |||
985 | struct ipv6hdr *ipv6h; | 1073 | struct ipv6hdr *ipv6h; |
986 | struct tcphdr *th; | 1074 | struct tcphdr *th; |
987 | bool push, timestamp; | 1075 | bool push, timestamp; |
988 | int index, l2_hdr_offset, l4_hdr_offset; | 1076 | int index, l2_hdr_offset, l4_hdr_offset, is_lb_pkt; |
989 | u16 lro_length, length, data_offset, vid = 0xffff; | 1077 | u16 lro_length, length, data_offset, t_vid, vid = 0xffff; |
990 | u32 seq_number; | 1078 | u32 seq_number; |
991 | 1079 | ||
992 | if (unlikely(ring > adapter->max_rds_rings)) | 1080 | if (unlikely(ring > adapter->max_rds_rings)) |
@@ -1011,6 +1099,14 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, | |||
1011 | if (!skb) | 1099 | if (!skb) |
1012 | return buffer; | 1100 | return buffer; |
1013 | 1101 | ||
1102 | if (adapter->drv_mac_learn && | ||
1103 | (adapter->flags & QLCNIC_ESWITCH_ENABLED)) { | ||
1104 | t_vid = 0; | ||
1105 | is_lb_pkt = qlcnic_82xx_is_lb_pkt(sts_data0); | ||
1106 | qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, | ||
1107 | cpu_to_le16(t_vid)); | ||
1108 | } | ||
1109 | |||
1014 | if (timestamp) | 1110 | if (timestamp) |
1015 | data_offset = l4_hdr_offset + QLC_TCP_TS_HDR_SIZE; | 1111 | data_offset = l4_hdr_offset + QLC_TCP_TS_HDR_SIZE; |
1016 | else | 1112 | else |
@@ -1357,6 +1453,17 @@ void qlcnic_82xx_napi_disable(struct qlcnic_adapter *adapter) | |||
1357 | } | 1453 | } |
1358 | } | 1454 | } |
1359 | 1455 | ||
1456 | #define QLC_83XX_NORMAL_LB_PKT (1ULL << 36) | ||
1457 | #define QLC_83XX_LRO_LB_PKT (1ULL << 46) | ||
1458 | |||
1459 | static inline int qlcnic_83xx_is_lb_pkt(u64 sts_data, int lro_pkt) | ||
1460 | { | ||
1461 | if (lro_pkt) | ||
1462 | return (sts_data & QLC_83XX_LRO_LB_PKT) ? 1 : 0; | ||
1463 | else | ||
1464 | return (sts_data & QLC_83XX_NORMAL_LB_PKT) ? 1 : 0; | ||
1465 | } | ||
1466 | |||
1360 | static struct qlcnic_rx_buffer * | 1467 | static struct qlcnic_rx_buffer * |
1361 | qlcnic_83xx_process_rcv(struct qlcnic_adapter *adapter, | 1468 | qlcnic_83xx_process_rcv(struct qlcnic_adapter *adapter, |
1362 | struct qlcnic_host_sds_ring *sds_ring, | 1469 | struct qlcnic_host_sds_ring *sds_ring, |
@@ -1367,8 +1474,8 @@ qlcnic_83xx_process_rcv(struct qlcnic_adapter *adapter, | |||
1367 | struct qlcnic_rx_buffer *buffer; | 1474 | struct qlcnic_rx_buffer *buffer; |
1368 | struct sk_buff *skb; | 1475 | struct sk_buff *skb; |
1369 | struct qlcnic_host_rds_ring *rds_ring; | 1476 | struct qlcnic_host_rds_ring *rds_ring; |
1370 | int index, length, cksum; | 1477 | int index, length, cksum, is_lb_pkt; |
1371 | u16 vid = 0xffff; | 1478 | u16 vid = 0xffff, t_vid; |
1372 | 1479 | ||
1373 | if (unlikely(ring >= adapter->max_rds_rings)) | 1480 | if (unlikely(ring >= adapter->max_rds_rings)) |
1374 | return NULL; | 1481 | return NULL; |
@@ -1386,6 +1493,14 @@ qlcnic_83xx_process_rcv(struct qlcnic_adapter *adapter, | |||
1386 | if (!skb) | 1493 | if (!skb) |
1387 | return buffer; | 1494 | return buffer; |
1388 | 1495 | ||
1496 | if (adapter->drv_mac_learn && | ||
1497 | (adapter->flags & QLCNIC_ESWITCH_ENABLED)) { | ||
1498 | t_vid = 0; | ||
1499 | is_lb_pkt = qlcnic_83xx_is_lb_pkt(sts_data[1], 0); | ||
1500 | qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, | ||
1501 | cpu_to_le16(t_vid)); | ||
1502 | } | ||
1503 | |||
1389 | if (length > rds_ring->skb_size) | 1504 | if (length > rds_ring->skb_size) |
1390 | skb_put(skb, rds_ring->skb_size); | 1505 | skb_put(skb, rds_ring->skb_size); |
1391 | else | 1506 | else |
@@ -1424,9 +1539,9 @@ qlcnic_83xx_process_lro(struct qlcnic_adapter *adapter, | |||
1424 | struct tcphdr *th; | 1539 | struct tcphdr *th; |
1425 | bool push; | 1540 | bool push; |
1426 | int l2_hdr_offset, l4_hdr_offset; | 1541 | int l2_hdr_offset, l4_hdr_offset; |
1427 | int index; | 1542 | int index, is_lb_pkt; |
1428 | u16 lro_length, length, data_offset, gso_size; | 1543 | u16 lro_length, length, data_offset, gso_size; |
1429 | u16 vid = 0xffff; | 1544 | u16 vid = 0xffff, t_vid; |
1430 | 1545 | ||
1431 | if (unlikely(ring > adapter->max_rds_rings)) | 1546 | if (unlikely(ring > adapter->max_rds_rings)) |
1432 | return NULL; | 1547 | return NULL; |
@@ -1447,6 +1562,14 @@ qlcnic_83xx_process_lro(struct qlcnic_adapter *adapter, | |||
1447 | skb = qlcnic_process_rxbuf(adapter, rds_ring, index, STATUS_CKSUM_OK); | 1562 | skb = qlcnic_process_rxbuf(adapter, rds_ring, index, STATUS_CKSUM_OK); |
1448 | if (!skb) | 1563 | if (!skb) |
1449 | return buffer; | 1564 | return buffer; |
1565 | |||
1566 | if (adapter->drv_mac_learn && | ||
1567 | (adapter->flags & QLCNIC_ESWITCH_ENABLED)) { | ||
1568 | t_vid = 0; | ||
1569 | is_lb_pkt = qlcnic_83xx_is_lb_pkt(sts_data[1], 1); | ||
1570 | qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, | ||
1571 | cpu_to_le16(t_vid)); | ||
1572 | } | ||
1450 | if (qlcnic_83xx_is_tstamp(sts_data[1])) | 1573 | if (qlcnic_83xx_is_tstamp(sts_data[1])) |
1451 | data_offset = l4_hdr_offset + QLCNIC_TCP_TS_HDR_SIZE; | 1574 | data_offset = l4_hdr_offset + QLCNIC_TCP_TS_HDR_SIZE; |
1452 | else | 1575 | else |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index e03017a999b4..5d5fd06c4b42 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -2208,6 +2208,7 @@ void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter) | |||
2208 | 2208 | ||
2209 | act_pci_func = adapter->ahw->act_pci_func; | 2209 | act_pci_func = adapter->ahw->act_pci_func; |
2210 | spin_lock_init(&adapter->mac_learn_lock); | 2210 | spin_lock_init(&adapter->mac_learn_lock); |
2211 | spin_lock_init(&adapter->rx_mac_learn_lock); | ||
2211 | 2212 | ||
2212 | if (qlcnic_82xx_check(adapter)) { | 2213 | if (qlcnic_82xx_check(adapter)) { |
2213 | filter_size = QLCNIC_LB_MAX_FILTERS; | 2214 | filter_size = QLCNIC_LB_MAX_FILTERS; |
@@ -2231,6 +2232,20 @@ void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter) | |||
2231 | 2232 | ||
2232 | for (i = 0; i < adapter->fhash.fbucket_size; i++) | 2233 | for (i = 0; i < adapter->fhash.fbucket_size; i++) |
2233 | INIT_HLIST_HEAD(&adapter->fhash.fhead[i]); | 2234 | INIT_HLIST_HEAD(&adapter->fhash.fhead[i]); |
2235 | |||
2236 | adapter->rx_fhash.fbucket_size = adapter->fhash.fbucket_size; | ||
2237 | |||
2238 | head = kcalloc(adapter->rx_fhash.fbucket_size, | ||
2239 | sizeof(struct hlist_head), GFP_ATOMIC); | ||
2240 | |||
2241 | if (!head) | ||
2242 | return; | ||
2243 | |||
2244 | adapter->rx_fhash.fmax = (filter_size / act_pci_func); | ||
2245 | adapter->rx_fhash.fhead = head; | ||
2246 | |||
2247 | for (i = 0; i < adapter->rx_fhash.fbucket_size; i++) | ||
2248 | INIT_HLIST_HEAD(&adapter->rx_fhash.fhead[i]); | ||
2234 | } | 2249 | } |
2235 | 2250 | ||
2236 | static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter) | 2251 | static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter) |
@@ -2240,6 +2255,12 @@ static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter) | |||
2240 | 2255 | ||
2241 | adapter->fhash.fhead = NULL; | 2256 | adapter->fhash.fhead = NULL; |
2242 | adapter->fhash.fmax = 0; | 2257 | adapter->fhash.fmax = 0; |
2258 | |||
2259 | if (adapter->rx_fhash.fmax && adapter->rx_fhash.fhead) | ||
2260 | kfree(adapter->rx_fhash.fhead); | ||
2261 | |||
2262 | adapter->rx_fhash.fmax = 0; | ||
2263 | adapter->rx_fhash.fhead = NULL; | ||
2243 | } | 2264 | } |
2244 | 2265 | ||
2245 | int qlcnic_check_temp(struct qlcnic_adapter *adapter) | 2266 | int qlcnic_check_temp(struct qlcnic_adapter *adapter) |