linux/drivers/net/ethernet/brocade/bna/bnad.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Linux network driver for QLogic BR-series Converged Network Adapter.
 */
/*
 * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
 * Copyright (c) 2014-2015 QLogic Corporation
 * All rights reserved
 * www.qlogic.com
 */
#include <linux/bitops.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/in.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/prefetch.h>
#include <linux/module.h>

#include "bnad.h"
#include "bna.h"
#include "cna.h"

static DEFINE_MUTEX(bnad_fwimg_mutex);

/*
 * Module params
 */
static uint bnad_msix_disable;
module_param(bnad_msix_disable, uint, 0444);
MODULE_PARM_DESC();

static uint bnad_ioc_auto_recover =;
module_param(bnad_ioc_auto_recover, uint, 0444);
MODULE_PARM_DESC();

static uint bna_debugfs_enable =;
module_param(bna_debugfs_enable, uint, 0644);
MODULE_PARM_DESC();

/*
 * Global variables
 */
static u32 bnad_rxqs_per_cq =;
static atomic_t bna_id;
static const u8 bnad_bcast_addr[] __aligned(2) =;

/*
 * Local MACROS
 */
#define BNAD_GET_MBOX_IRQ(_bnad)

#define BNAD_FILL_UNMAPQ_MEM_REQ(_res_info, _num, _size)

/*
 * Reinitialize completions in CQ, once Rx is taken down
 */
static void
bnad_cq_cleanup(struct bnad *bnad, struct bna_ccb *ccb)
{}

/* Tx Datapath functions */


/* Caller should ensure that the entry at unmap_q[index] is valid */
static u32
bnad_tx_buff_unmap(struct bnad *bnad,
			      struct bnad_tx_unmap *unmap_q,
			      u32 q_depth, u32 index)
{}

/*
 * Frees all pending Tx Bufs
 * At this point no activity is expected on the Q,
 * so DMA unmap & freeing is fine.
 */
static void
bnad_txq_cleanup(struct bnad *bnad, struct bna_tcb *tcb)
{}

/*
 * bnad_txcmpl_process : Frees the Tx bufs on Tx completion
 * Can be called in a) Interrupt context
 *		    b) Sending context
 */
static u32
bnad_txcmpl_process(struct bnad *bnad, struct bna_tcb *tcb)
{}

static u32
bnad_tx_complete(struct bnad *bnad, struct bna_tcb *tcb)
{}

/* MSIX Tx Completion Handler */
static irqreturn_t
bnad_msix_tx(int irq, void *data)
{}

static inline void
bnad_rxq_alloc_uninit(struct bnad *bnad, struct bna_rcb *rcb)
{}

/* Default is page-based allocation. Multi-buffer support - TBD */
static int
bnad_rxq_alloc_init(struct bnad *bnad, struct bna_rcb *rcb)
{}

static inline void
bnad_rxq_cleanup_page(struct bnad *bnad, struct bnad_rx_unmap *unmap)
{}

static inline void
bnad_rxq_cleanup_skb(struct bnad *bnad, struct bnad_rx_unmap *unmap)
{}

static void
bnad_rxq_cleanup(struct bnad *bnad, struct bna_rcb *rcb)
{}

static u32
bnad_rxq_refill_page(struct bnad *bnad, struct bna_rcb *rcb, u32 nalloc)
{}

static u32
bnad_rxq_refill_skb(struct bnad *bnad, struct bna_rcb *rcb, u32 nalloc)
{}

static inline void
bnad_rxq_post(struct bnad *bnad, struct bna_rcb *rcb)
{}

#define flags_cksum_prot_mask

#define flags_tcp4
#define flags_tcp6
#define flags_udp4
#define flags_udp6

static void
bnad_cq_drop_packet(struct bnad *bnad, struct bna_rcb *rcb,
		    u32 sop_ci, u32 nvecs)
{}

static void
bnad_cq_setup_skb_frags(struct bna_ccb *ccb, struct sk_buff *skb, u32 nvecs)
{}

static inline void
bnad_cq_setup_skb(struct bnad *bnad, struct sk_buff *skb,
		  struct bnad_rx_unmap *unmap, u32 len)
{}

static u32
bnad_cq_process(struct bnad *bnad, struct bna_ccb *ccb, int budget)
{}

static void
bnad_netif_rx_schedule_poll(struct bnad *bnad, struct bna_ccb *ccb)
{}

/* MSIX Rx Path Handler */
static irqreturn_t
bnad_msix_rx(int irq, void *data)
{}

/* Interrupt handlers */

/* Mbox Interrupt Handlers */
static irqreturn_t
bnad_msix_mbox_handler(int irq, void *data)
{}

static irqreturn_t
bnad_isr(int irq, void *data)
{}

/*
 * Called in interrupt / callback context
 * with bna_lock held, so cfg_flags access is OK
 */
static void
bnad_enable_mbox_irq(struct bnad *bnad)
{}

/*
 * Called with bnad->bna_lock held b'cos of
 * bnad->cfg_flags access.
 */
static void
bnad_disable_mbox_irq(struct bnad *bnad)
{}

static void
bnad_set_netdev_perm_addr(struct bnad *bnad)
{}

/* Control Path Handlers */

/* Callbacks */
void
bnad_cb_mbox_intr_enable(struct bnad *bnad)
{}

void
bnad_cb_mbox_intr_disable(struct bnad *bnad)
{}

void
bnad_cb_ioceth_ready(struct bnad *bnad)
{}

void
bnad_cb_ioceth_failed(struct bnad *bnad)
{}

void
bnad_cb_ioceth_disabled(struct bnad *bnad)
{}

static void
bnad_cb_enet_disabled(void *arg)
{}

void
bnad_cb_ethport_link_status(struct bnad *bnad,
			enum bna_link_status link_status)
{}

static void
bnad_cb_tx_disabled(void *arg, struct bna_tx *tx)
{}

static void
bnad_cb_tcb_setup(struct bnad *bnad, struct bna_tcb *tcb)
{}

static void
bnad_cb_tcb_destroy(struct bnad *bnad, struct bna_tcb *tcb)
{}

static void
bnad_cb_ccb_setup(struct bnad *bnad, struct bna_ccb *ccb)
{}

static void
bnad_cb_ccb_destroy(struct bnad *bnad, struct bna_ccb *ccb)
{}

static void
bnad_cb_tx_stall(struct bnad *bnad, struct bna_tx *tx)
{}

static void
bnad_cb_tx_resume(struct bnad *bnad, struct bna_tx *tx)
{}

/*
 * Free all TxQs buffers and then notify TX_E_CLEANUP_DONE to Tx fsm.
 */
static void
bnad_tx_cleanup(struct work_struct *work)
{}

static void
bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tx *tx)
{}

static void
bnad_cb_rx_stall(struct bnad *bnad, struct bna_rx *rx)
{}

/*
 * Free all RxQs buffers and then notify RX_E_CLEANUP_DONE to Rx fsm.
 */
static void
bnad_rx_cleanup(struct work_struct *work)
{}

static void
bnad_cb_rx_cleanup(struct bnad *bnad, struct bna_rx *rx)
{}

static void
bnad_cb_rx_post(struct bnad *bnad, struct bna_rx *rx)
{}

static void
bnad_cb_rx_disabled(void *arg, struct bna_rx *rx)
{}

static void
bnad_cb_rx_mcast_add(struct bnad *bnad, struct bna_rx *rx)
{}

void
bnad_cb_stats_get(struct bnad *bnad, enum bna_cb_status status,
		       struct bna_stats *stats)
{}

static void
bnad_cb_enet_mtu_set(struct bnad *bnad)
{}

void
bnad_cb_completion(void *arg, enum bfa_status status)
{}

/* Resource allocation, free functions */

static void
bnad_mem_free(struct bnad *bnad,
	      struct bna_mem_info *mem_info)
{}

static int
bnad_mem_alloc(struct bnad *bnad,
	       struct bna_mem_info *mem_info)
{}

/* Free IRQ for Mailbox */
static void
bnad_mbox_irq_free(struct bnad *bnad)
{}

/*
 * Allocates IRQ for Mailbox, but keep it disabled
 * This will be enabled once we get the mbox enable callback
 * from bna
 */
static int
bnad_mbox_irq_alloc(struct bnad *bnad)
{}

static void
bnad_txrx_irq_free(struct bnad *bnad, struct bna_intr_info *intr_info)
{}

/* Allocates Interrupt Descriptor List for MSIX/INT-X vectors */
static int
bnad_txrx_irq_alloc(struct bnad *bnad, enum bnad_intr_source src,
		    u32 txrx_id, struct bna_intr_info *intr_info)
{}

/* NOTE: Should be called for MSIX only
 * Unregisters Tx MSIX vector(s) from the kernel
 */
static void
bnad_tx_msix_unregister(struct bnad *bnad, struct bnad_tx_info *tx_info,
			int num_txqs)
{}

/* NOTE: Should be called for MSIX only
 * Registers Tx MSIX vector(s) and ISR(s), cookie with the kernel
 */
static int
bnad_tx_msix_register(struct bnad *bnad, struct bnad_tx_info *tx_info,
			u32 tx_id, int num_txqs)
{}

/* NOTE: Should be called for MSIX only
 * Unregisters Rx MSIX vector(s) from the kernel
 */
static void
bnad_rx_msix_unregister(struct bnad *bnad, struct bnad_rx_info *rx_info,
			int num_rxps)
{}

/* NOTE: Should be called for MSIX only
 * Registers Tx MSIX vector(s) and ISR(s), cookie with the kernel
 */
static int
bnad_rx_msix_register(struct bnad *bnad, struct bnad_rx_info *rx_info,
			u32 rx_id, int num_rxps)
{}

/* Free Tx object Resources */
static void
bnad_tx_res_free(struct bnad *bnad, struct bna_res_info *res_info)
{}

/* Allocates memory and interrupt resources for Tx object */
static int
bnad_tx_res_alloc(struct bnad *bnad, struct bna_res_info *res_info,
		  u32 tx_id)
{}

/* Free Rx object Resources */
static void
bnad_rx_res_free(struct bnad *bnad, struct bna_res_info *res_info)
{}

/* Allocates memory and interrupt resources for Rx object */
static int
bnad_rx_res_alloc(struct bnad *bnad, struct bna_res_info *res_info,
		  uint rx_id)
{}

/* Timer callbacks */
/* a) IOC timer */
static void
bnad_ioc_timeout(struct timer_list *t)
{}

static void
bnad_ioc_hb_check(struct timer_list *t)
{}

static void
bnad_iocpf_timeout(struct timer_list *t)
{}

static void
bnad_iocpf_sem_timeout(struct timer_list *t)
{}

/*
 * All timer routines use bnad->bna_lock to protect against
 * the following race, which may occur in case of no locking:
 *	Time	CPU m	CPU n
 *	0       1 = test_bit
 *	1			clear_bit
 *	2			del_timer_sync
 *	3	mod_timer
 */

/* b) Dynamic Interrupt Moderation Timer */
static void
bnad_dim_timeout(struct timer_list *t)
{}

/* c)  Statistics Timer */
static void
bnad_stats_timeout(struct timer_list *t)
{}

/*
 * Set up timer for DIM
 * Called with bnad->bna_lock held
 */
void
bnad_dim_timer_start(struct bnad *bnad)
{}

/*
 * Set up timer for statistics
 * Called with mutex_lock(&bnad->conf_mutex) held
 */
static void
bnad_stats_timer_start(struct bnad *bnad)
{}

/*
 * Stops the stats timer
 * Called with mutex_lock(&bnad->conf_mutex) held
 */
static void
bnad_stats_timer_stop(struct bnad *bnad)
{}

/* Utilities */

static void
bnad_netdev_mc_list_get(struct net_device *netdev, u8 *mc_list)
{}

static int
bnad_napi_poll_rx(struct napi_struct *napi, int budget)
{}

static void
bnad_napi_add(struct bnad *bnad, u32 rx_id)
{}

static void
bnad_napi_delete(struct bnad *bnad, u32 rx_id)
{}

/* Should be held with conf_lock held */
void
bnad_destroy_tx(struct bnad *bnad, u32 tx_id)
{}

/* Should be held with conf_lock held */
int
bnad_setup_tx(struct bnad *bnad, u32 tx_id)
{}

/* Setup the rx config for bna_rx_create */
/* bnad decides the configuration */
static void
bnad_init_rx_config(struct bnad *bnad, struct bna_rx_config *rx_config)
{}

static void
bnad_rx_ctrl_init(struct bnad *bnad, u32 rx_id)
{}

/* Called with mutex_lock(&bnad->conf_mutex) held */
static u32
bnad_reinit_rx(struct bnad *bnad)
{}

/* Called with bnad_conf_lock() held */
void
bnad_destroy_rx(struct bnad *bnad, u32 rx_id)
{}

/* Called with mutex_lock(&bnad->conf_mutex) held */
int
bnad_setup_rx(struct bnad *bnad, u32 rx_id)
{}

/* Called with conf_lock & bnad->bna_lock held */
void
bnad_tx_coalescing_timeo_set(struct bnad *bnad)
{}

/* Called with conf_lock & bnad->bna_lock held */
void
bnad_rx_coalescing_timeo_set(struct bnad *bnad)
{}

/*
 * Called with bnad->bna_lock held
 */
int
bnad_mac_addr_set_locked(struct bnad *bnad, const u8 *mac_addr)
{}

/* Should be called with conf_lock held */
int
bnad_enable_default_bcast(struct bnad *bnad)
{}

/* Called with mutex_lock(&bnad->conf_mutex) held */
void
bnad_restore_vlans(struct bnad *bnad, u32 rx_id)
{}

/* Statistics utilities */
void
bnad_netdev_qstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats)
{}

/*
 * Must be called with the bna_lock held.
 */
void
bnad_netdev_hwstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats)
{}

static void
bnad_mbox_irq_sync(struct bnad *bnad)
{}

/* Utility used by bnad_start_xmit, for doing TSO */
static int
bnad_tso_prepare(struct bnad *bnad, struct sk_buff *skb)
{}

/*
 * Initialize Q numbers depending on Rx Paths
 * Called with bnad->bna_lock held, because of cfg_flags
 * access.
 */
static void
bnad_q_num_init(struct bnad *bnad)
{}

/*
 * Adjusts the Q numbers, given a number of msix vectors
 * Give preference to RSS as opposed to Tx priority Queues,
 * in such a case, just use 1 Tx Q
 * Called with bnad->bna_lock held b'cos of cfg_flags access
 */
static void
bnad_q_num_adjust(struct bnad *bnad, int msix_vectors, int temp)
{}

/* Enable / disable ioceth */
static int
bnad_ioceth_disable(struct bnad *bnad)
{}

static int
bnad_ioceth_enable(struct bnad *bnad)
{}

/* Free BNA resources */
static void
bnad_res_free(struct bnad *bnad, struct bna_res_info *res_info,
		u32 res_val_max)
{}

/* Allocates memory and interrupt resources for BNA */
static int
bnad_res_alloc(struct bnad *bnad, struct bna_res_info *res_info,
		u32 res_val_max)
{}

/* Interrupt enable / disable */
static void
bnad_enable_msix(struct bnad *bnad)
{}

static void
bnad_disable_msix(struct bnad *bnad)
{}

/* Netdev entry points */
static int
bnad_open(struct net_device *netdev)
{}

static int
bnad_stop(struct net_device *netdev)
{}

/* TX */
/* Returns 0 for success */
static int
bnad_txq_wi_prepare(struct bnad *bnad, struct bna_tcb *tcb,
		    struct sk_buff *skb, struct bna_txq_entry *txqent)
{}

/*
 * bnad_start_xmit : Netdev entry point for Transmit
 *		     Called under lock held by net_device
 */
static netdev_tx_t
bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
{}

/*
 * Used spin_lock to synchronize reading of stats structures, which
 * is written by BNA under the same lock.
 */
static void
bnad_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
{}

static void
bnad_set_rx_ucast_fltr(struct bnad *bnad)
{}

static void
bnad_set_rx_mcast_fltr(struct bnad *bnad)
{}

void
bnad_set_rx_mode(struct net_device *netdev)
{}

/*
 * bna_lock is used to sync writes to netdev->addr
 * conf_lock cannot be used since this call may be made
 * in a non-blocking context.
 */
static int
bnad_set_mac_address(struct net_device *netdev, void *addr)
{}

static int
bnad_mtu_set(struct bnad *bnad, int frame_size)
{}

static int
bnad_change_mtu(struct net_device *netdev, int new_mtu)
{}

static int
bnad_vlan_rx_add_vid(struct net_device *netdev, __be16 proto, u16 vid)
{}

static int
bnad_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid)
{}

static int bnad_set_features(struct net_device *dev, netdev_features_t features)
{}

#ifdef CONFIG_NET_POLL_CONTROLLER
static void
bnad_netpoll(struct net_device *netdev)
{}
#endif

static const struct net_device_ops bnad_netdev_ops =;

static void
bnad_netdev_init(struct bnad *bnad)
{}

/*
 * 1. Initialize the bnad structure
 * 2. Setup netdev pointer in pci_dev
 * 3. Initialize no. of TxQ & CQs & MSIX vectors
 * 4. Initialize work queue.
 */
static int
bnad_init(struct bnad *bnad,
	  struct pci_dev *pdev, struct net_device *netdev)
{}

/*
 * Must be called after bnad_pci_uninit()
 * so that iounmap() and pci_set_drvdata(NULL)
 * happens only after PCI uninitialization.
 */
static void
bnad_uninit(struct bnad *bnad)
{}

/*
 * Initialize locks
	a) Per ioceth mutes used for serializing configuration
	   changes from OS interface
	b) spin lock used to protect bna state machine
 */
static void
bnad_lock_init(struct bnad *bnad)
{}

static void
bnad_lock_uninit(struct bnad *bnad)
{}

/* PCI Initialization */
static int
bnad_pci_init(struct bnad *bnad, struct pci_dev *pdev)
{}

static void
bnad_pci_uninit(struct pci_dev *pdev)
{}

static int
bnad_pci_probe(struct pci_dev *pdev,
		const struct pci_device_id *pcidev_id)
{}

static void
bnad_pci_remove(struct pci_dev *pdev)
{}

static const struct pci_device_id bnad_pci_id_table[] =;

MODULE_DEVICE_TABLE(pci, bnad_pci_id_table);

static struct pci_driver bnad_pci_driver =;

static int __init
bnad_module_init(void)
{}

static void __exit
bnad_module_exit(void)
{}

module_init();
module_exit(bnad_module_exit);

MODULE_AUTHOR();
MODULE_LICENSE();
MODULE_DESCRIPTION();
MODULE_FIRMWARE();
MODULE_FIRMWARE();