diff options
Diffstat (limited to 'drivers/net/qlcnic/qlcnic_init.c')
-rw-r--r-- | drivers/net/qlcnic/qlcnic_init.c | 123 |
1 files changed, 5 insertions, 118 deletions
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 0d180c6e41f..9b9c7c39d3e 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c | |||
@@ -1,25 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2009 - QLogic Corporation. | 2 | * QLogic qlcnic NIC Driver |
3 | * All rights reserved. | 3 | * Copyright (c) 2009-2010 QLogic Corporation |
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version 2 | ||
8 | * of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
18 | * MA 02111-1307, USA. | ||
19 | * | ||
20 | * The full GNU General Public License is included in this distribution | ||
21 | * in the file called "COPYING". | ||
22 | * | 4 | * |
5 | * See LICENSE.qlcnic for copyright and licensing details. | ||
23 | */ | 6 | */ |
24 | 7 | ||
25 | #include <linux/netdevice.h> | 8 | #include <linux/netdevice.h> |
@@ -236,12 +219,11 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter) | |||
236 | tx_ring->num_desc = adapter->num_txd; | 219 | tx_ring->num_desc = adapter->num_txd; |
237 | tx_ring->txq = netdev_get_tx_queue(netdev, 0); | 220 | tx_ring->txq = netdev_get_tx_queue(netdev, 0); |
238 | 221 | ||
239 | cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring)); | 222 | cmd_buf_arr = vzalloc(TX_BUFF_RINGSIZE(tx_ring)); |
240 | if (cmd_buf_arr == NULL) { | 223 | if (cmd_buf_arr == NULL) { |
241 | dev_err(&netdev->dev, "failed to allocate cmd buffer ring\n"); | 224 | dev_err(&netdev->dev, "failed to allocate cmd buffer ring\n"); |
242 | goto err_out; | 225 | goto err_out; |
243 | } | 226 | } |
244 | memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring)); | ||
245 | tx_ring->cmd_buf_arr = cmd_buf_arr; | 227 | tx_ring->cmd_buf_arr = cmd_buf_arr; |
246 | 228 | ||
247 | recv_ctx = &adapter->recv_ctx; | 229 | recv_ctx = &adapter->recv_ctx; |
@@ -275,14 +257,12 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter) | |||
275 | rds_ring->dma_size + NET_IP_ALIGN; | 257 | rds_ring->dma_size + NET_IP_ALIGN; |
276 | break; | 258 | break; |
277 | } | 259 | } |
278 | rds_ring->rx_buf_arr = (struct qlcnic_rx_buffer *) | 260 | rds_ring->rx_buf_arr = vzalloc(RCV_BUFF_RINGSIZE(rds_ring)); |
279 | vmalloc(RCV_BUFF_RINGSIZE(rds_ring)); | ||
280 | if (rds_ring->rx_buf_arr == NULL) { | 261 | if (rds_ring->rx_buf_arr == NULL) { |
281 | dev_err(&netdev->dev, "Failed to allocate " | 262 | dev_err(&netdev->dev, "Failed to allocate " |
282 | "rx buffer ring %d\n", ring); | 263 | "rx buffer ring %d\n", ring); |
283 | goto err_out; | 264 | goto err_out; |
284 | } | 265 | } |
285 | memset(rds_ring->rx_buf_arr, 0, RCV_BUFF_RINGSIZE(rds_ring)); | ||
286 | INIT_LIST_HEAD(&rds_ring->free_list); | 266 | INIT_LIST_HEAD(&rds_ring->free_list); |
287 | /* | 267 | /* |
288 | * Now go through all of them, set reference handles | 268 | * Now go through all of them, set reference handles |
@@ -1693,99 +1673,6 @@ qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter, | |||
1693 | spin_unlock(&rds_ring->lock); | 1673 | spin_unlock(&rds_ring->lock); |
1694 | } | 1674 | } |
1695 | 1675 | ||
1696 | static void dump_skb(struct sk_buff *skb) | ||
1697 | { | ||
1698 | int i; | ||
1699 | unsigned char *data = skb->data; | ||
1700 | |||
1701 | for (i = 0; i < skb->len; i++) { | ||
1702 | printk("%02x ", data[i]); | ||
1703 | if ((i & 0x0f) == 8) | ||
1704 | printk("\n"); | ||
1705 | } | ||
1706 | } | ||
1707 | |||
1708 | static struct qlcnic_rx_buffer * | ||
1709 | qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter, | ||
1710 | struct qlcnic_host_sds_ring *sds_ring, | ||
1711 | int ring, u64 sts_data0) | ||
1712 | { | ||
1713 | struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; | ||
1714 | struct qlcnic_rx_buffer *buffer; | ||
1715 | struct sk_buff *skb; | ||
1716 | struct qlcnic_host_rds_ring *rds_ring; | ||
1717 | int index, length, cksum, pkt_offset; | ||
1718 | |||
1719 | if (unlikely(ring >= adapter->max_rds_rings)) | ||
1720 | return NULL; | ||
1721 | |||
1722 | rds_ring = &recv_ctx->rds_rings[ring]; | ||
1723 | |||
1724 | index = qlcnic_get_sts_refhandle(sts_data0); | ||
1725 | if (unlikely(index >= rds_ring->num_desc)) | ||
1726 | return NULL; | ||
1727 | |||
1728 | buffer = &rds_ring->rx_buf_arr[index]; | ||
1729 | |||
1730 | length = qlcnic_get_sts_totallength(sts_data0); | ||
1731 | cksum = qlcnic_get_sts_status(sts_data0); | ||
1732 | pkt_offset = qlcnic_get_sts_pkt_offset(sts_data0); | ||
1733 | |||
1734 | skb = qlcnic_process_rxbuf(adapter, rds_ring, index, cksum); | ||
1735 | if (!skb) | ||
1736 | return buffer; | ||
1737 | |||
1738 | if (length > rds_ring->skb_size) | ||
1739 | skb_put(skb, rds_ring->skb_size); | ||
1740 | else | ||
1741 | skb_put(skb, length); | ||
1742 | |||
1743 | if (pkt_offset) | ||
1744 | skb_pull(skb, pkt_offset); | ||
1745 | |||
1746 | if (!qlcnic_check_loopback_buff(skb->data)) | ||
1747 | adapter->diag_cnt++; | ||
1748 | else | ||
1749 | dump_skb(skb); | ||
1750 | |||
1751 | dev_kfree_skb_any(skb); | ||
1752 | adapter->stats.rx_pkts++; | ||
1753 | adapter->stats.rxbytes += length; | ||
1754 | |||
1755 | return buffer; | ||
1756 | } | ||
1757 | |||
1758 | void | ||
1759 | qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring) | ||
1760 | { | ||
1761 | struct qlcnic_adapter *adapter = sds_ring->adapter; | ||
1762 | struct status_desc *desc; | ||
1763 | struct qlcnic_rx_buffer *rxbuf; | ||
1764 | u64 sts_data0; | ||
1765 | |||
1766 | int opcode, ring, desc_cnt; | ||
1767 | u32 consumer = sds_ring->consumer; | ||
1768 | |||
1769 | desc = &sds_ring->desc_head[consumer]; | ||
1770 | sts_data0 = le64_to_cpu(desc->status_desc_data[0]); | ||
1771 | |||
1772 | if (!(sts_data0 & STATUS_OWNER_HOST)) | ||
1773 | return; | ||
1774 | |||
1775 | desc_cnt = qlcnic_get_sts_desc_cnt(sts_data0); | ||
1776 | opcode = qlcnic_get_sts_opcode(sts_data0); | ||
1777 | |||
1778 | ring = qlcnic_get_sts_type(sts_data0); | ||
1779 | rxbuf = qlcnic_process_rcv_diag(adapter, sds_ring, | ||
1780 | ring, sts_data0); | ||
1781 | |||
1782 | desc->status_desc_data[0] = cpu_to_le64(STATUS_OWNER_PHANTOM); | ||
1783 | consumer = get_next_index(consumer, sds_ring->num_desc); | ||
1784 | |||
1785 | sds_ring->consumer = consumer; | ||
1786 | writel(consumer, sds_ring->crb_sts_consumer); | ||
1787 | } | ||
1788 | |||
1789 | void | 1676 | void |
1790 | qlcnic_fetch_mac(struct qlcnic_adapter *adapter, u32 off1, u32 off2, | 1677 | qlcnic_fetch_mac(struct qlcnic_adapter *adapter, u32 off1, u32 off2, |
1791 | u8 alt_mac, u8 *mac) | 1678 | u8 alt_mac, u8 *mac) |