Commit 6092db1a authored by David S. Miller's avatar David S. Miller

Merge branch 'qed-driver'

Ariel Elior says:

====================
Add new drivers: qed & qede

This series implements the driver set for Qlogic's new QL4xxx series.
These are 10/20/25/40/50/100 Gig capable converged nics, supporting
ethernet (obviously), iscsi, fcoe, roce and iwarp protocols.

The overall driver design includes a common module ('qed') and protocol
specific dependent modules for ethernet ('qede'), fcoe ('qedf'),
iscsi ('qedi') and roce ('qedr').
The common module contains all of the common logic, e.g. initialization,
cleanup, infrastructure for interrupt handling, link management, slowpath
etc. as well as protocol agnostic features, and supplying an abstraction
layer for other modules.
The protocol specific modules can be compiled and operated independently
of each other, with the exception of the rdma modules which are dependent
on the ethernet module, in accordance with the kernel rdma stack design.

This series only adds the core and ethernet modules, with basic L2
capabilities. Future series will add the rest of the modules and enhance
the L2 functionality.

Ths patch series is constructed of the following patches:
qed:  Add module with basic common support
qed:  Add basic L2 interface
qede: Add basic Network driver
qed:  Add slowpath L2 support
qede: Add basic network device support
qede: Add classification configuration
qed:  Add link support
qede: Add support for link
qed:  Add statistics support
qede: Add basic ethtool support

This project is a team effort, thanks go to Yuval Mintz, Dmitry Kravkov,
Michal Kalderon, Tomer Tayar, Manish Chopra, Sudarsana Kalluru,
Rajesh Borundia, Sony Chacko, Artum Zolotushko, Harish Patil, Rasesh Mody,
Sergey Ukhterov and Elad Manela, as well as former team members,
Eilon Greenstein and Shmulik Ravid.

Changes from previos version:
-----------------------------

From Version 7:
  - Various small fixes according to Dave's suggestions; Largest change
    [code-wise] - don't use tabs for indenting function arguments.

From Version 6:
  - Reduced the number of arguments for functions with exceptionally
    high number of parameters.

From Version 5:
  - Style change and fixes [mostly in 1, 4 and 7].
    Thanks go to Francois Romieu, a mere mortal. ;-)

From Version 4:
  - Drop dependency for x86_64.

From Version 3:
  - Limit support of initial submission to x86_64.
  - Fix endian problems appearing via sparse [although no BE support yet].
  - Fix small issues suggested by the kbuild test robot.

From Version 2:
  - Removed U64_{HI,LO}; Using {upper,lower}_32_bits instead.
  - Use regular napi weight definition.
  - [We still use the __le variants for variables, since we didn't get
     a reply regarding the change into non-user API types].

From Version 1:
  - Removed private license file; Instead revised comments at source headers.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 8941faa1 133fac0e
......@@ -8540,6 +8540,16 @@ L: netdev@vger.kernel.org
S: Supported
F: drivers/net/ethernet/qlogic/qlge/
QLOGIC QL4xxx ETHERNET DRIVER
M: Yuval Mintz <Yuval.Mintz@qlogic.com>
M: Ariel Elior <Ariel.Elior@qlogic.com>
M: everest-linux-l2@qlogic.com
L: netdev@vger.kernel.org
S: Supported
F: drivers/net/ethernet/qlogic/qed/
F: include/linux/qed/
F: drivers/net/ethernet/qlogic/qede/
QNX4 FILESYSTEM
M: Anders Larsen <al@alarsen.net>
W: http://www.alarsen.net/linux/qnx4fs/
......
......@@ -91,4 +91,15 @@ config NETXEN_NIC
---help---
This enables the support for NetXen's Gigabit Ethernet card.
config QED
tristate "QLogic QED 25/40/100Gb core driver"
depends on PCI
---help---
This enables the support for ...
config QEDE
tristate "QLogic QED 25/40/100Gb Ethernet NIC"
depends on QED
---help---
This enables the support for ...
endif # NET_VENDOR_QLOGIC
......@@ -6,3 +6,5 @@ obj-$(CONFIG_QLA3XXX) += qla3xxx.o
obj-$(CONFIG_QLCNIC) += qlcnic/
obj-$(CONFIG_QLGE) += qlge/
obj-$(CONFIG_NETXEN_NIC) += netxen/
obj-$(CONFIG_QED) += qed/
obj-$(CONFIG_QEDE)+= qede/
obj-$(CONFIG_QED) := qed.o
qed-y := qed_cxt.o qed_dev.o qed_hw.o qed_init_fw_funcs.o qed_init_ops.o \
qed_int.o qed_main.o qed_mcp.o qed_sp_commands.o qed_spq.o qed_l2.o
This diff is collapsed.
This diff is collapsed.
/* QLogic qed NIC Driver
* Copyright (c) 2015 QLogic Corporation
*
* This software is available under the terms of the GNU General Public License
* (GPL) Version 2, available from the file COPYING in the main directory of
* this source tree.
*/
#ifndef _QED_CXT_H
#define _QED_CXT_H
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/qed/qed_if.h>
#include "qed_hsi.h"
#include "qed.h"
struct qed_cxt_info {
void *p_cxt;
u32 iid;
enum protocol_type type;
};
/**
* @brief qed_cxt_acquire - Acquire a new cid of a specific protocol type
*
* @param p_hwfn
* @param type
* @param p_cid
*
* @return int
*/
int qed_cxt_acquire_cid(struct qed_hwfn *p_hwfn,
enum protocol_type type,
u32 *p_cid);
/**
* @brief qedo_cid_get_cxt_info - Returns the context info for a specific cid
*
*
* @param p_hwfn
* @param p_info in/out
*
* @return int
*/
int qed_cxt_get_cid_info(struct qed_hwfn *p_hwfn,
struct qed_cxt_info *p_info);
enum qed_cxt_elem_type {
QED_ELEM_CXT,
QED_ELEM_TASK
};
/**
* @brief qed_cxt_set_pf_params - Set the PF params for cxt init
*
* @param p_hwfn
*
* @return int
*/
int qed_cxt_set_pf_params(struct qed_hwfn *p_hwfn);
/**
* @brief qed_cxt_cfg_ilt_compute - compute ILT init parameters
*
* @param p_hwfn
*
* @return int
*/
int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn);
/**
* @brief qed_cxt_mngr_alloc - Allocate and init the context manager struct
*
* @param p_hwfn
*
* @return int
*/
int qed_cxt_mngr_alloc(struct qed_hwfn *p_hwfn);
/**
* @brief qed_cxt_mngr_free
*
* @param p_hwfn
*/
void qed_cxt_mngr_free(struct qed_hwfn *p_hwfn);
/**
* @brief qed_cxt_tables_alloc - Allocate ILT shadow, Searcher T2, acquired map
*
* @param p_hwfn
*
* @return int
*/
int qed_cxt_tables_alloc(struct qed_hwfn *p_hwfn);
/**
* @brief qed_cxt_mngr_setup - Reset the acquired CIDs
*
* @param p_hwfn
*/
void qed_cxt_mngr_setup(struct qed_hwfn *p_hwfn);
/**
* @brief qed_cxt_hw_init_common - Initailze ILT and DQ, common phase, per path.
*
*
*
* @param p_hwfn
*/
void qed_cxt_hw_init_common(struct qed_hwfn *p_hwfn);
/**
* @brief qed_cxt_hw_init_pf - Initailze ILT and DQ, PF phase, per path.
*
*
*
* @param p_hwfn
*/
void qed_cxt_hw_init_pf(struct qed_hwfn *p_hwfn);
/**
* @brief qed_qm_init_pf - Initailze the QM PF phase, per path
*
* @param p_hwfn
*/
void qed_qm_init_pf(struct qed_hwfn *p_hwfn);
/**
* @brief qed_cxt_release - Release a cid
*
* @param p_hwfn
* @param cid
*/
void qed_cxt_release_cid(struct qed_hwfn *p_hwfn,
u32 cid);
#endif
This diff is collapsed.
/* QLogic qed NIC Driver
* Copyright (c) 2015 QLogic Corporation
*
* This software is available under the terms of the GNU General Public License
* (GPL) Version 2, available from the file COPYING in the main directory of
* this source tree.
*/
#ifndef _QED_DEV_API_H
#define _QED_DEV_API_H
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/qed/qed_chain.h>
#include <linux/qed/qed_if.h>
#include "qed_int.h"
/**
* @brief qed_init_dp - initialize the debug level
*
* @param cdev
* @param dp_module
* @param dp_level
*/
void qed_init_dp(struct qed_dev *cdev,
u32 dp_module,
u8 dp_level);
/**
* @brief qed_init_struct - initialize the device structure to
* its defaults
*
* @param cdev
*/
void qed_init_struct(struct qed_dev *cdev);
/**
* @brief qed_resc_free -
*
* @param cdev
*/
void qed_resc_free(struct qed_dev *cdev);
/**
* @brief qed_resc_alloc -
*
* @param cdev
*
* @return int
*/
int qed_resc_alloc(struct qed_dev *cdev);
/**
* @brief qed_resc_setup -
*
* @param cdev
*/
void qed_resc_setup(struct qed_dev *cdev);
/**
* @brief qed_hw_init -
*
* @param cdev
* @param b_hw_start
* @param int_mode - interrupt mode [msix, inta, etc.] to use.
* @param allow_npar_tx_switch - npar tx switching to be used
* for vports configured for tx-switching.
* @param bin_fw_data - binary fw data pointer in binary fw file.
* Pass NULL if not using binary fw file.
*
* @return int
*/
int qed_hw_init(struct qed_dev *cdev,
bool b_hw_start,
enum qed_int_mode int_mode,
bool allow_npar_tx_switch,
const u8 *bin_fw_data);
/**
* @brief qed_hw_stop -
*
* @param cdev
*
* @return int
*/
int qed_hw_stop(struct qed_dev *cdev);
/**
* @brief qed_hw_stop_fastpath -should be called incase
* slowpath is still required for the device,
* but fastpath is not.
*
* @param cdev
*
*/
void qed_hw_stop_fastpath(struct qed_dev *cdev);
/**
* @brief qed_hw_start_fastpath -restart fastpath traffic,
* only if hw_stop_fastpath was called
*
* @param cdev
*
*/
void qed_hw_start_fastpath(struct qed_hwfn *p_hwfn);
/**
* @brief qed_hw_reset -
*
* @param cdev
*
* @return int
*/
int qed_hw_reset(struct qed_dev *cdev);
/**
* @brief qed_hw_prepare -
*
* @param cdev
* @param personality - personality to initialize
*
* @return int
*/
int qed_hw_prepare(struct qed_dev *cdev,
int personality);
/**
* @brief qed_hw_remove -
*
* @param cdev
*/
void qed_hw_remove(struct qed_dev *cdev);
/**
* @brief qed_ptt_acquire - Allocate a PTT window
*
* Should be called at the entry point to the driver (at the beginning of an
* exported function)
*
* @param p_hwfn
*
* @return struct qed_ptt
*/
struct qed_ptt *qed_ptt_acquire(struct qed_hwfn *p_hwfn);
/**
* @brief qed_ptt_release - Release PTT Window
*
* Should be called at the end of a flow - at the end of the function that
* acquired the PTT.
*
*
* @param p_hwfn
* @param p_ptt
*/
void qed_ptt_release(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt);
void qed_get_vport_stats(struct qed_dev *cdev,
struct qed_eth_stats *stats);
void qed_reset_vport_stats(struct qed_dev *cdev);
enum qed_dmae_address_type_t {
QED_DMAE_ADDRESS_HOST_VIRT,
QED_DMAE_ADDRESS_HOST_PHYS,
QED_DMAE_ADDRESS_GRC
};
/* value of flags If QED_DMAE_FLAG_RW_REPL_SRC flag is set and the
* source is a block of length DMAE_MAX_RW_SIZE and the
* destination is larger, the source block will be duplicated as
* many times as required to fill the destination block. This is
* used mostly to write a zeroed buffer to destination address
* using DMA
*/
#define QED_DMAE_FLAG_RW_REPL_SRC 0x00000001
#define QED_DMAE_FLAG_COMPLETION_DST 0x00000008
struct qed_dmae_params {
u32 flags; /* consists of QED_DMAE_FLAG_* values */
};
/**
* @brief qed_dmae_host2grc - copy data from source addr to
* dmae registers using the given ptt
*
* @param p_hwfn
* @param p_ptt
* @param source_addr
* @param grc_addr (dmae_data_offset)
* @param size_in_dwords
* @param flags (one of the flags defined above)
*/
int
qed_dmae_host2grc(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
u64 source_addr,
u32 grc_addr,
u32 size_in_dwords,
u32 flags);
/**
* @brief qed_chain_alloc - Allocate and initialize a chain
*
* @param p_hwfn
* @param intended_use
* @param mode
* @param num_elems
* @param elem_size
* @param p_chain
*
* @return int
*/
int
qed_chain_alloc(struct qed_dev *cdev,
enum qed_chain_use_mode intended_use,
enum qed_chain_mode mode,
u16 num_elems,
size_t elem_size,
struct qed_chain *p_chain);
/**
* @brief qed_chain_free - Free chain DMA memory
*
* @param p_hwfn
* @param p_chain
*/
void qed_chain_free(struct qed_dev *cdev,
struct qed_chain *p_chain);
/**
* @@brief qed_fw_l2_queue - Get absolute L2 queue ID
*
* @param p_hwfn
* @param src_id - relative to p_hwfn
* @param dst_id - absolute per engine
*
* @return int
*/
int qed_fw_l2_queue(struct qed_hwfn *p_hwfn,
u16 src_id,
u16 *dst_id);
/**
* @@brief qed_fw_vport - Get absolute vport ID
*
* @param p_hwfn
* @param src_id - relative to p_hwfn
* @param dst_id - absolute per engine
*
* @return int
*/
int qed_fw_vport(struct qed_hwfn *p_hwfn,
u8 src_id,
u8 *dst_id);
/**
* @@brief qed_fw_rss_eng - Get absolute RSS engine ID
*
* @param p_hwfn
* @param src_id - relative to p_hwfn
* @param dst_id - absolute per engine
*
* @return int
*/
int qed_fw_rss_eng(struct qed_hwfn *p_hwfn,
u8 src_id,
u8 *dst_id);
/**
* *@brief Cleanup of previous driver remains prior to load
*
* @param p_hwfn
* @param p_ptt
* @param id - For PF, engine-relative. For VF, PF-relative.
*
* @return int
*/
int qed_final_cleanup(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
u16 id);
#endif
This diff is collapsed.
This diff is collapsed.
/* QLogic qed NIC Driver
* Copyright (c) 2015 QLogic Corporation
*
* This software is available under the terms of the GNU General Public License
* (GPL) Version 2, available from the file COPYING in the main directory of
* this source tree.
*/
#ifndef _QED_HW_H
#define _QED_HW_H
#include <linux/types.h>
#include <linux/bitops.h>
#include <linux/slab.h>
#include <linux/string.h>
#include "qed.h"
#include "qed_dev_api.h"
/* Forward decleration */
struct qed_ptt;
enum reserved_ptts {
RESERVED_PTT_EDIAG,
RESERVED_PTT_USER_SPACE,
RESERVED_PTT_MAIN,
RESERVED_PTT_DPC,
RESERVED_PTT_MAX
};
enum _dmae_cmd_dst_mask {
DMAE_CMD_DST_MASK_NONE = 0,
DMAE_CMD_DST_MASK_PCIE = 1,
DMAE_CMD_DST_MASK_GRC = 2
};
enum _dmae_cmd_src_mask {
DMAE_CMD_SRC_MASK_PCIE = 0,
DMAE_CMD_SRC_MASK_GRC = 1
};
enum _dmae_cmd_crc_mask {
DMAE_CMD_COMP_CRC_EN_MASK_NONE = 0,
DMAE_CMD_COMP_CRC_EN_MASK_SET = 1
};
/* definitions for DMA constants */
#define DMAE_GO_VALUE 0x1
#define DMAE_COMPLETION_VAL 0xD1AE
#define DMAE_CMD_ENDIANITY 0x2
#define DMAE_CMD_SIZE 14
#define DMAE_CMD_SIZE_TO_FILL (DMAE_CMD_SIZE - 5)
#define DMAE_MIN_WAIT_TIME 0x2
#define DMAE_MAX_CLIENTS 32
/**
* @brief qed_gtt_init - Initialize GTT windows
*
* @param p_hwfn
*/
void qed_gtt_init(struct qed_hwfn *p_hwfn);
/**
* @brief qed_ptt_invalidate - Forces all ptt entries to be re-configured
*
* @param p_hwfn
*/
void qed_ptt_invalidate(struct qed_hwfn *p_hwfn);
/**
* @brief qed_ptt_pool_alloc - Allocate and initialize PTT pool
*
* @param p_hwfn
*
* @return struct _qed_status - success (0), negative - error.
*/
int qed_ptt_pool_alloc(struct qed_hwfn *p_hwfn);
/**
* @brief qed_ptt_pool_free -
*
* @param p_hwfn
*/
void qed_ptt_pool_free(struct qed_hwfn *p_hwfn);
/**
* @brief qed_ptt_get_hw_addr - Get PTT's GRC/HW address
*
* @param p_hwfn
* @param p_ptt
*
* @return u32
*/
u32 qed_ptt_get_hw_addr(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt);
/**
* @brief qed_ptt_get_bar_addr - Get PPT's external BAR address
*
* @param p_hwfn
* @param p_ptt
*
* @return u32
*/
u32 qed_ptt_get_bar_addr(struct qed_ptt *p_ptt);
/**
* @brief qed_ptt_set_win - Set PTT Window's GRC BAR address
*
* @param p_hwfn
* @param new_hw_addr
* @param p_ptt
*/
void qed_ptt_set_win(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
u32 new_hw_addr);
/**
* @brief qed_get_reserved_ptt - Get a specific reserved PTT
*
* @param p_hwfn
* @param ptt_idx
*
* @return struct qed_ptt *
*/
struct qed_ptt *qed_get_reserved_ptt(struct qed_hwfn *p_hwfn,
enum reserved_ptts ptt_idx);
/**
* @brief qed_wr - Write value to BAR using the given ptt
*
* @param p_hwfn
* @param p_ptt
* @param val
* @param hw_addr
*/
void qed_wr(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
u32 hw_addr,
u32 val);
/**
* @brief qed_rd - Read value from BAR using the given ptt
*
* @param p_hwfn
* @param p_ptt
* @param val
* @param hw_addr
*/
u32 qed_rd(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
u32 hw_addr);
/**
* @brief qed_memcpy_from - copy n bytes from BAR using the given
* ptt
*
* @param p_hwfn
* @param p_ptt
* @param dest
* @param hw_addr
* @param n
*/
void qed_memcpy_from(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
void *dest,
u32 hw_addr,
size_t n);
/**
* @brief qed_memcpy_to - copy n bytes to BAR using the given
* ptt
*
* @param p_hwfn
* @param p_ptt
* @param hw_addr
* @param src
* @param n
*/
void qed_memcpy_to(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
u32 hw_addr,
void *src,
size_t n);
/**
* @brief qed_fid_pretend - pretend to another function when
* accessing the ptt window. There is no way to unpretend
* a function. The only way to cancel a pretend is to
* pretend back to the original function.
*
* @param p_hwfn
* @param p_ptt
* @param fid - fid field of pxp_pretend structure. Can contain
* either pf / vf, port/path fields are don't care.
*/
void qed_fid_pretend(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
u16 fid);
/**
* @brief qed_port_pretend - pretend to another port when
* accessing the ptt window
*
* @param p_hwfn
* @param p_ptt
* @param port_id - the port to pretend to
*/
void qed_port_pretend(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
u8 port_id);
/**
* @brief qed_port_unpretend - cancel any previously set port
* pretend
*
* @param p_hwfn
* @param p_ptt
*/
void qed_port_unpretend(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt);
/**
* @brief qed_dmae_idx_to_go_cmd - map the idx to dmae cmd
* this is declared here since other files will require it.
* @param idx
*/
u32 qed_dmae_idx_to_go_cmd(u8 idx);
/**
* @brief qed_dmae_info_alloc - Init the dmae_info structure
* which is part of p_hwfn.
* @param p_hwfn
*/
int qed_dmae_info_alloc(struct qed_hwfn *p_hwfn);
/**
* @brief qed_dmae_info_free - Free the dmae_info structure
* which is part of p_hwfn
*
* @param p_hwfn
*/
void qed_dmae_info_free(struct qed_hwfn *p_hwfn);
union qed_qm_pq_params {
struct {
u8 tc;
} core;
struct {
u8 is_vf;
u8 vf_id;
u8 tc;
} eth;
};
u16 qed_get_qm_pq(struct qed_hwfn *p_hwfn,
enum protocol_type proto,
union qed_qm_pq_params *params);
int qed_init_fw_data(struct qed_dev *cdev,
const u8 *fw_data);
#endif
This diff is collapsed.
This diff is collapsed.
/* QLogic qed NIC Driver
* Copyright (c) 2015 QLogic Corporation
*
* This software is available under the terms of the GNU General Public License
* (GPL) Version 2, available from the file COPYING in the main directory of
* this source tree.
*/
#ifndef _QED_INIT_OPS_H
#define _QED_INIT_OPS_H
#include <linux/types.h>
#include <linux/slab.h>
#include "qed.h"
/**
* @brief qed_init_iro_array - init iro_arr.
*
*
* @param cdev
*/
void qed_init_iro_array(struct qed_dev *cdev);
/**
* @brief qed_init_run - Run the init-sequence.
*
*
* @param p_hwfn
* @param p_ptt
* @param phase
* @param phase_id
* @param modes
* @return _qed_status_t
*/
int qed_init_run(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
int phase,
int phase_id,
int modes);
/**
* @brief qed_init_hwfn_allocate - Allocate RT array, Store 'values' ptrs.
*
*
* @param p_hwfn
*
* @return _qed_status_t
*/
int qed_init_alloc(struct qed_hwfn *p_hwfn);
/**
* @brief qed_init_hwfn_deallocate
*
*
* @param p_hwfn
*/
void qed_init_free(struct qed_hwfn *p_hwfn);
/**
* @brief qed_init_clear_rt_data - Clears the runtime init array.
*
*
* @param p_hwfn
*/
void qed_init_clear_rt_data(struct qed_hwfn *p_hwfn);
/**
* @brief qed_init_store_rt_reg - Store a configuration value in the RT array.
*
*
* @param p_hwfn
* @param rt_offset
* @param val
*/
void qed_init_store_rt_reg(struct qed_hwfn *p_hwfn,
u32 rt_offset,
u32 val);
#define STORE_RT_REG(hwfn, offset, val) \
qed_init_store_rt_reg(hwfn, offset, val)
#define OVERWRITE_RT_REG(hwfn, offset, val) \
qed_init_store_rt_reg(hwfn, offset, val)
/**
* @brief
*
*
* @param p_hwfn
* @param rt_offset
* @param val
* @param size
*/
void qed_init_store_rt_agg(struct qed_hwfn *p_hwfn,
u32 rt_offset,
u32 *val,
size_t size);
#define STORE_RT_REG_AGG(hwfn, offset, val) \
qed_init_store_rt_agg(hwfn, offset, (u32 *)&val, sizeof(val))
/**
* @brief
* Initialize GTT global windows and set admin window
* related params of GTT/PTT to default values.
*
* @param p_hwfn
*/
void qed_gtt_init(struct qed_hwfn *p_hwfn);
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* QLogic qed NIC Driver
* Copyright (c) 2015 QLogic Corporation
*
* This software is available under the terms of the GNU General Public License
* (GPL) Version 2, available from the file COPYING in the main directory of
* this source tree.
*/
#include <linux/types.h>
#include <asm/byteorder.h>
#include <linux/bitops.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include "qed.h"
#include <linux/qed/qed_chain.h>
#include "qed_cxt.h"
#include "qed_hsi.h"
#include "qed_hw.h"
#include "qed_int.h"
#include "qed_reg_addr.h"
#include "qed_sp.h"
int qed_sp_init_request(struct qed_hwfn *p_hwfn,
struct qed_spq_entry **pp_ent,
u32 cid,
u16 opaque_fid,
u8 cmd,
u8 protocol,
struct qed_sp_init_request_params *p_params)
{
int rc = -EINVAL;
struct qed_spq_entry *p_ent = NULL;
u32 opaque_cid = opaque_fid << 16 | cid;
if (!pp_ent)
return -ENOMEM;
rc = qed_spq_get_entry(p_hwfn, pp_ent);
if (rc != 0)
return rc;
p_ent = *pp_ent;
p_ent->elem.hdr.cid = cpu_to_le32(opaque_cid);
p_ent->elem.hdr.cmd_id = cmd;
p_ent->elem.hdr.protocol_id = protocol;
p_ent->priority = QED_SPQ_PRIORITY_NORMAL;
p_ent->comp_mode = p_params->comp_mode;
p_ent->comp_done.done = 0;
switch (p_ent->comp_mode) {
case QED_SPQ_MODE_EBLOCK:
p_ent->comp_cb.cookie = &p_ent->comp_done;
break;
case QED_SPQ_MODE_BLOCK:
if (!p_params->p_comp_data)
return -EINVAL;
p_ent->comp_cb.cookie = p_params->p_comp_data->cookie;
break;
case QED_SPQ_MODE_CB:
if (!p_params->p_comp_data)
p_ent->comp_cb.function = NULL;
else
p_ent->comp_cb = *p_params->p_comp_data;
break;
default:
DP_NOTICE(p_hwfn, "Unknown SPQE completion mode %d\n",
p_ent->comp_mode);
return -EINVAL;
}
DP_VERBOSE(p_hwfn, QED_MSG_SPQ,
"Initialized: CID %08x cmd %02x protocol %02x data_addr %lu comp_mode [%s]\n",
opaque_cid, cmd, protocol,
(unsigned long)&p_ent->ramrod,
D_TRINE(p_ent->comp_mode, QED_SPQ_MODE_EBLOCK,
QED_SPQ_MODE_BLOCK, "MODE_EBLOCK", "MODE_BLOCK",
"MODE_CB"));
if (p_params->ramrod_data_size)
memset(&p_ent->ramrod, 0, p_params->ramrod_data_size);
return 0;
}
int qed_sp_pf_start(struct qed_hwfn *p_hwfn,
enum mf_mode mode)
{
struct qed_sp_init_request_params params;
struct pf_start_ramrod_data *p_ramrod = NULL;
u16 sb = qed_int_get_sp_sb_id(p_hwfn);
u8 sb_index = p_hwfn->p_eq->eq_sb_index;
struct qed_spq_entry *p_ent = NULL;
int rc = -EINVAL;
/* update initial eq producer */
qed_eq_prod_update(p_hwfn,
qed_chain_get_prod_idx(&p_hwfn->p_eq->chain));
memset(&params, 0, sizeof(params));
params.ramrod_data_size = sizeof(*p_ramrod);
params.comp_mode = QED_SPQ_MODE_EBLOCK;
rc = qed_sp_init_request(p_hwfn,
&p_ent,
qed_spq_get_cid(p_hwfn),
p_hwfn->hw_info.opaque_fid,
COMMON_RAMROD_PF_START,
PROTOCOLID_COMMON,
&params);
if (rc)
return rc;
p_ramrod = &p_ent->ramrod.pf_start;
p_ramrod->event_ring_sb_id = cpu_to_le16(sb);
p_ramrod->event_ring_sb_index = sb_index;
p_ramrod->path_id = QED_PATH_ID(p_hwfn);
p_ramrod->dont_log_ramrods = 0;
p_ramrod->log_type_mask = cpu_to_le16(0xf);
p_ramrod->mf_mode = mode;
p_ramrod->outer_tag = p_hwfn->hw_info.ovlan;
/* Place EQ address in RAMROD */
p_ramrod->event_ring_pbl_addr.hi =
DMA_HI_LE(p_hwfn->p_eq->chain.pbl.p_phys_table);
p_ramrod->event_ring_pbl_addr.lo =
DMA_LO_LE(p_hwfn->p_eq->chain.pbl.p_phys_table);
p_ramrod->event_ring_num_pages = (u8)p_hwfn->p_eq->chain.page_cnt;
p_ramrod->consolid_q_pbl_addr.hi =
DMA_HI_LE(p_hwfn->p_consq->chain.pbl.p_phys_table);
p_ramrod->consolid_q_pbl_addr.lo =
DMA_LO_LE(p_hwfn->p_consq->chain.pbl.p_phys_table);
p_hwfn->hw_info.personality = PERSONALITY_ETH;
DP_VERBOSE(p_hwfn, QED_MSG_SPQ,
"Setting event_ring_sb [id %04x index %02x], mf [%s] outer_tag [%d]\n",
sb, sb_index,
(p_ramrod->mf_mode == SF) ? "SF" : "Multi-Pf",
p_ramrod->outer_tag);
return qed_spq_post(p_hwfn, p_ent, NULL);
}
int qed_sp_pf_stop(struct qed_hwfn *p_hwfn)
{
struct qed_sp_init_request_params params;
struct qed_spq_entry *p_ent = NULL;
int rc = -EINVAL;
memset(&params, 0, sizeof(params));
params.comp_mode = QED_SPQ_MODE_EBLOCK;
rc = qed_sp_init_request(p_hwfn, &p_ent, qed_spq_get_cid(p_hwfn),
p_hwfn->hw_info.opaque_fid,
COMMON_RAMROD_PF_STOP, PROTOCOLID_COMMON,
&params);
if (rc)
return rc;
return qed_spq_post(p_hwfn, p_ent, NULL);
}
This diff is collapsed.
obj-$(CONFIG_QEDE) := qede.o
qede-y := qede_main.o qede_ethtool.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment