diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-13 06:07:07 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-13 06:07:07 +0400 |
commit | 6be35c700f742e911ecedd07fcc43d4439922334 (patch) | |
tree | ca9f37214d204465fcc2d79c82efd291e357c53c /drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c | |
parent | e37aa63e87bd581f9be5555ed0ba83f5295c92fc (diff) | |
parent | 520dfe3a3645257bf83660f672c47f8558f3d4c4 (diff) | |
download | linux-6be35c700f742e911ecedd07fcc43d4439922334.tar.xz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking changes from David Miller:
1) Allow to dump, monitor, and change the bridge multicast database
using netlink. From Cong Wang.
2) RFC 5961 TCP blind data injection attack mitigation, from Eric
Dumazet.
3) Networking user namespace support from Eric W. Biederman.
4) tuntap/virtio-net multiqueue support by Jason Wang.
5) Support for checksum offload of encapsulated packets (basically,
tunneled traffic can still be checksummed by HW). From Joseph
Gasparakis.
6) Allow BPF filter access to VLAN tags, from Eric Dumazet and
Daniel Borkmann.
7) Bridge port parameters over netlink and BPDU blocking support
from Stephen Hemminger.
8) Improve data access patterns during inet socket demux by rearranging
socket layout, from Eric Dumazet.
9) TIPC protocol updates and cleanups from Ying Xue, Paul Gortmaker, and
Jon Maloy.
10) Update TCP socket hash sizing to be more in line with current day
realities. The existing heurstics were choosen a decade ago.
From Eric Dumazet.
11) Fix races, queue bloat, and excessive wakeups in ATM and
associated drivers, from Krzysztof Mazur and David Woodhouse.
12) Support DOVE (Distributed Overlay Virtual Ethernet) extensions
in VXLAN driver, from David Stevens.
13) Add "oops_only" mode to netconsole, from Amerigo Wang.
14) Support set and query of VEB/VEPA bridge mode via PF_BRIDGE, also
allow DCB netlink to work on namespaces other than the initial
namespace. From John Fastabend.
15) Support PTP in the Tigon3 driver, from Matt Carlson.
16) tun/vhost zero copy fixes and improvements, plus turn it on
by default, from Michael S. Tsirkin.
17) Support per-association statistics in SCTP, from Michele
Baldessari.
And many, many, driver updates, cleanups, and improvements. Too
numerous to mention individually.
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1722 commits)
net/mlx4_en: Add support for destination MAC in steering rules
net/mlx4_en: Use generic etherdevice.h functions.
net: ethtool: Add destination MAC address to flow steering API
bridge: add support of adding and deleting mdb entries
bridge: notify mdb changes via netlink
ndisc: Unexport ndisc_{build,send}_skb().
uapi: add missing netconf.h to export list
pkt_sched: avoid requeues if possible
solos-pci: fix double-free of TX skb in DMA mode
bnx2: Fix accidental reversions.
bna: Driver Version Updated to 3.1.2.1
bna: Firmware update
bna: Add RX State
bna: Rx Page Based Allocation
bna: TX Intr Coalescing Fix
bna: Tx and Rx Optimizations
bna: Code Cleanup and Enhancements
ath9k: check pdata variable before dereferencing it
ath5k: RX timestamp is reported at end of frame
ath9k_htc: RX timestamp is reported at end of frame
...
Diffstat (limited to 'drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c')
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c | 114 |
1 files changed, 70 insertions, 44 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c index 2a179d087207..58f094ca052e 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c @@ -7,6 +7,18 @@ #include "qlcnic.h" +static int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func) +{ + int i; + + for (i = 0; i < adapter->ahw->act_pci_func; i++) { + if (adapter->npars[i].pci_func == pci_func) + return i; + } + + return -1; +} + static u32 qlcnic_poll_rsp(struct qlcnic_adapter *adapter) { @@ -35,7 +47,7 @@ qlcnic_issue_cmd(struct qlcnic_adapter *adapter, struct qlcnic_cmd_args *cmd) struct qlcnic_hardware_context *ahw = adapter->ahw; signature = QLCNIC_CDRP_SIGNATURE_MAKE(ahw->pci_func, - adapter->fw_hal_version); + adapter->ahw->fw_hal_version); /* Acquire semaphore before accessing CRB */ if (qlcnic_api_lock(adapter)) { @@ -103,7 +115,7 @@ qlcnic_issue_cmd(struct qlcnic_adapter *adapter, struct qlcnic_cmd_args *cmd) } -static uint32_t qlcnic_temp_checksum(uint32_t *temp_buffer, u16 temp_size) +static uint32_t qlcnic_temp_checksum(uint32_t *temp_buffer, u32 temp_size) { uint64_t sum = 0; int count = temp_size / sizeof(uint32_t); @@ -117,9 +129,9 @@ static uint32_t qlcnic_temp_checksum(uint32_t *temp_buffer, u16 temp_size) int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter) { int err, i; - u16 temp_size; void *tmp_addr; - u32 version, csum, *template, *tmp_buf; + u32 temp_size, version, csum, *template; + __le32 *tmp_buf; struct qlcnic_cmd_args cmd; struct qlcnic_hardware_context *ahw; struct qlcnic_dump_template_hdr *tmpl_hdr, *tmp_tmpl; @@ -163,13 +175,6 @@ int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter) goto error; } tmp_tmpl = tmp_addr; - csum = qlcnic_temp_checksum((uint32_t *) tmp_addr, temp_size); - if (csum) { - dev_err(&adapter->pdev->dev, - "Template header checksum validation failed\n"); - err = -EIO; - goto error; - } ahw->fw_dump.tmpl_hdr = vzalloc(temp_size); if (!ahw->fw_dump.tmpl_hdr) { err = -EIO; @@ -180,6 +185,14 @@ int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter) for (i = 0; i < temp_size/sizeof(u32); i++) *template++ = __le32_to_cpu(*tmp_buf++); + csum = qlcnic_temp_checksum((u32 *)ahw->fw_dump.tmpl_hdr, temp_size); + if (csum) { + dev_err(&adapter->pdev->dev, + "Template header checksum validation failed\n"); + err = -EIO; + goto error; + } + tmpl_hdr = ahw->fw_dump.tmpl_hdr; tmpl_hdr->drv_cap_mask = QLCNIC_DUMP_MASK_DEF; ahw->fw_dump.enable = 1; @@ -231,6 +244,7 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) size_t rq_size, rsp_size; u32 cap, reg, val, reg2; int err; + u16 temp; struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; @@ -267,8 +281,8 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP) cap |= QLCNIC_CAP0_LRO_MSS; - prq->valid_field_offset = offsetof(struct qlcnic_hostrq_rx_ctx, - msix_handler); + temp = offsetof(struct qlcnic_hostrq_rx_ctx, msix_handler); + prq->valid_field_offset = cpu_to_le16(temp); prq->txrx_sds_binding = nsds_rings - 1; prq->capabilities[0] = cpu_to_le32(cap); @@ -453,8 +467,7 @@ qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter) temp = le32_to_cpu(prsp->cds_ring.host_producer_crb); tx_ring->crb_cmd_producer = adapter->ahw->pci_base0 + temp; - adapter->tx_context_id = - le16_to_cpu(prsp->context_id); + adapter->tx_ring->ctx_id = le16_to_cpu(prsp->context_id); } else { dev_err(&adapter->pdev->dev, "Failed to create tx ctx in firmware%d\n", err); @@ -476,7 +489,7 @@ qlcnic_fw_cmd_destroy_tx_ctx(struct qlcnic_adapter *adapter) struct qlcnic_cmd_args cmd; memset(&cmd, 0, sizeof(cmd)); - cmd.req.arg1 = adapter->tx_context_id; + cmd.req.arg1 = adapter->tx_ring->ctx_id; cmd.req.arg2 = QLCNIC_DESTROY_CTX_RESET; cmd.req.arg3 = 0; cmd.req.cmd = QLCNIC_CDRP_CMD_DESTROY_TX_CTX; @@ -671,7 +684,7 @@ int qlcnic_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac) err = cmd.rsp.cmd; if (err == QLCNIC_RCODE_SUCCESS) - qlcnic_fetch_mac(adapter, cmd.rsp.arg1, cmd.rsp.arg2, 0, mac); + qlcnic_fetch_mac(cmd.rsp.arg1, cmd.rsp.arg2, 0, mac); else { dev_err(&adapter->pdev->dev, "Failed to get mac address%d\n", err); @@ -687,10 +700,10 @@ int qlcnic_get_nic_info(struct qlcnic_adapter *adapter, { int err; dma_addr_t nic_dma_t; - struct qlcnic_info *nic_info; + struct qlcnic_info_le *nic_info; void *nic_info_addr; struct qlcnic_cmd_args cmd; - size_t nic_size = sizeof(struct qlcnic_info); + size_t nic_size = sizeof(struct qlcnic_info_le); nic_info_addr = dma_alloc_coherent(&adapter->pdev->dev, nic_size, &nic_dma_t, GFP_KERNEL); @@ -745,10 +758,10 @@ int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic) dma_addr_t nic_dma_t; void *nic_info_addr; struct qlcnic_cmd_args cmd; - struct qlcnic_info *nic_info; - size_t nic_size = sizeof(struct qlcnic_info); + struct qlcnic_info_le *nic_info; + size_t nic_size = sizeof(struct qlcnic_info_le); - if (adapter->op_mode != QLCNIC_MGMT_FUNC) + if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) return err; nic_info_addr = dma_alloc_coherent(&adapter->pdev->dev, nic_size, @@ -796,9 +809,9 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter, int err = 0, i; struct qlcnic_cmd_args cmd; dma_addr_t pci_info_dma_t; - struct qlcnic_pci_info *npar; + struct qlcnic_pci_info_le *npar; void *pci_info_addr; - size_t npar_size = sizeof(struct qlcnic_pci_info); + size_t npar_size = sizeof(struct qlcnic_pci_info_le); size_t pci_size = npar_size * QLCNIC_MAX_PCI_FUNC; pci_info_addr = dma_alloc_coherent(&adapter->pdev->dev, pci_size, @@ -816,11 +829,14 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter, qlcnic_issue_cmd(adapter, &cmd); err = cmd.rsp.cmd; + adapter->ahw->act_pci_func = 0; if (err == QLCNIC_RCODE_SUCCESS) { for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++, npar++, pci_info++) { pci_info->id = le16_to_cpu(npar->id); pci_info->active = le16_to_cpu(npar->active); pci_info->type = le16_to_cpu(npar->type); + if (pci_info->type == QLCNIC_TYPE_NIC) + adapter->ahw->act_pci_func++; pci_info->default_port = le16_to_cpu(npar->default_port); pci_info->tx_min_bw = @@ -848,8 +864,8 @@ int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id, u32 arg1; struct qlcnic_cmd_args cmd; - if (adapter->op_mode != QLCNIC_MGMT_FUNC || - !(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE)) + if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC || + !(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE)) return err; arg1 = id | (enable_mirroring ? BIT_4 : 0); @@ -877,8 +893,8 @@ int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id, int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func, const u8 rx_tx, struct __qlcnic_esw_statistics *esw_stats) { - size_t stats_size = sizeof(struct __qlcnic_esw_statistics); - struct __qlcnic_esw_statistics *stats; + size_t stats_size = sizeof(struct qlcnic_esw_stats_le); + struct qlcnic_esw_stats_le *stats; dma_addr_t stats_dma_t; void *stats_addr; u32 arg1; @@ -888,8 +904,8 @@ int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func, if (esw_stats == NULL) return -ENOMEM; - if (adapter->op_mode != QLCNIC_MGMT_FUNC && - func != adapter->ahw->pci_func) { + if ((adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) && + (func != adapter->ahw->pci_func)) { dev_err(&adapter->pdev->dev, "Not privilege to query stats for func=%d", func); return -EIO; @@ -939,9 +955,9 @@ int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func, int qlcnic_get_mac_stats(struct qlcnic_adapter *adapter, struct qlcnic_mac_statistics *mac_stats) { - struct qlcnic_mac_statistics *stats; + struct qlcnic_mac_statistics_le *stats; struct qlcnic_cmd_args cmd; - size_t stats_size = sizeof(struct qlcnic_mac_statistics); + size_t stats_size = sizeof(struct qlcnic_mac_statistics_le); dma_addr_t stats_dma_t; void *stats_addr; int err; @@ -1000,7 +1016,7 @@ int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch, if (esw_stats == NULL) return -ENOMEM; - if (adapter->op_mode != QLCNIC_MGMT_FUNC) + if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) return -EIO; if (adapter->npars == NULL) return -EIO; @@ -1015,12 +1031,13 @@ int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch, esw_stats->numbytes = QLCNIC_STATS_NOT_AVAIL; esw_stats->context_id = eswitch; - for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { + for (i = 0; i < adapter->ahw->act_pci_func; i++) { if (adapter->npars[i].phy_port != eswitch) continue; memset(&port_stats, 0, sizeof(struct __qlcnic_esw_statistics)); - if (qlcnic_get_port_stats(adapter, i, rx_tx, &port_stats)) + if (qlcnic_get_port_stats(adapter, adapter->npars[i].pci_func, + rx_tx, &port_stats)) continue; esw_stats->size = port_stats.size; @@ -1051,7 +1068,7 @@ int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, const u8 func_esw, u32 arg1; struct qlcnic_cmd_args cmd; - if (adapter->op_mode != QLCNIC_MGMT_FUNC) + if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) return -EIO; if (func_esw == QLCNIC_STATS_PORT) { @@ -1119,15 +1136,18 @@ op_type = 1 for port vlan_id int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, struct qlcnic_esw_func_cfg *esw_cfg) { - int err = -EIO; + int err = -EIO, index; u32 arg1, arg2 = 0; struct qlcnic_cmd_args cmd; u8 pci_func; - if (adapter->op_mode != QLCNIC_MGMT_FUNC) + if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) return err; pci_func = esw_cfg->pci_func; - arg1 = (adapter->npars[pci_func].phy_port & BIT_0); + index = qlcnic_is_valid_nic_func(adapter, pci_func); + if (index < 0) + return err; + arg1 = (adapter->npars[index].phy_port & BIT_0); arg1 |= (pci_func << 8); if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2)) @@ -1139,7 +1159,7 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, case QLCNIC_PORT_DEFAULTS: arg1 |= (BIT_4 | BIT_6 | BIT_7); arg2 |= (BIT_0 | BIT_1); - if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO) + if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO) arg2 |= (BIT_2 | BIT_3); if (!(esw_cfg->discard_tagged)) arg1 &= ~BIT_4; @@ -1191,11 +1211,17 @@ qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter, struct qlcnic_esw_func_cfg *esw_cfg) { u32 arg1, arg2; + int index; u8 phy_port; - if (adapter->op_mode == QLCNIC_MGMT_FUNC) - phy_port = adapter->npars[esw_cfg->pci_func].phy_port; - else - phy_port = adapter->physical_port; + + if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) { + index = qlcnic_is_valid_nic_func(adapter, esw_cfg->pci_func); + if (index < 0) + return -EIO; + phy_port = adapter->npars[index].phy_port; + } else { + phy_port = adapter->ahw->physical_port; + } arg1 = phy_port; arg1 |= (esw_cfg->pci_func << 8); if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2)) |