162306a36Sopenharmony_ci/* bnx2x_cmn.h: QLogic Everest network driver. 262306a36Sopenharmony_ci * 362306a36Sopenharmony_ci * Copyright (c) 2007-2013 Broadcom Corporation 462306a36Sopenharmony_ci * Copyright (c) 2014 QLogic Corporation 562306a36Sopenharmony_ci * All rights reserved 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * This program is free software; you can redistribute it and/or modify 862306a36Sopenharmony_ci * it under the terms of the GNU General Public License as published by 962306a36Sopenharmony_ci * the Free Software Foundation. 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * Maintained by: Ariel Elior <ariel.elior@qlogic.com> 1262306a36Sopenharmony_ci * Written by: Eliezer Tamir 1362306a36Sopenharmony_ci * Based on code from Michael Chan's bnx2 driver 1462306a36Sopenharmony_ci * UDP CSUM errata workaround by Arik Gendelman 1562306a36Sopenharmony_ci * Slowpath and fastpath rework by Vladislav Zolotarov 1662306a36Sopenharmony_ci * Statistics and Link management by Yitchak Gertner 1762306a36Sopenharmony_ci * 1862306a36Sopenharmony_ci */ 1962306a36Sopenharmony_ci#ifndef BNX2X_CMN_H 2062306a36Sopenharmony_ci#define BNX2X_CMN_H 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#include <linux/types.h> 2362306a36Sopenharmony_ci#include <linux/pci.h> 2462306a36Sopenharmony_ci#include <linux/netdevice.h> 2562306a36Sopenharmony_ci#include <linux/etherdevice.h> 2662306a36Sopenharmony_ci#include <linux/irq.h> 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#include "bnx2x.h" 2962306a36Sopenharmony_ci#include "bnx2x_sriov.h" 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci/* This is used as a replacement for an MCP if it's not present */ 3262306a36Sopenharmony_ciextern int bnx2x_load_count[2][3]; /* per-path: 0-common, 1-port0, 2-port1 */ 3362306a36Sopenharmony_ciextern int bnx2x_num_queues; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci/************************ Macros ********************************/ 3662306a36Sopenharmony_ci#define BNX2X_PCI_FREE(x, y, size) \ 3762306a36Sopenharmony_ci do { \ 3862306a36Sopenharmony_ci if (x) { \ 3962306a36Sopenharmony_ci dma_free_coherent(&bp->pdev->dev, size, (void *)x, y); \ 4062306a36Sopenharmony_ci x = NULL; \ 4162306a36Sopenharmony_ci y = 0; \ 4262306a36Sopenharmony_ci } \ 4362306a36Sopenharmony_ci } while (0) 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci#define BNX2X_FREE(x) \ 4662306a36Sopenharmony_ci do { \ 4762306a36Sopenharmony_ci if (x) { \ 4862306a36Sopenharmony_ci kfree((void *)x); \ 4962306a36Sopenharmony_ci x = NULL; \ 5062306a36Sopenharmony_ci } \ 5162306a36Sopenharmony_ci } while (0) 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci#define BNX2X_PCI_ALLOC(y, size) \ 5462306a36Sopenharmony_ci({ \ 5562306a36Sopenharmony_ci void *x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \ 5662306a36Sopenharmony_ci if (x) \ 5762306a36Sopenharmony_ci DP(NETIF_MSG_HW, \ 5862306a36Sopenharmony_ci "BNX2X_PCI_ALLOC: Physical %Lx Virtual %p\n", \ 5962306a36Sopenharmony_ci (unsigned long long)(*y), x); \ 6062306a36Sopenharmony_ci x; \ 6162306a36Sopenharmony_ci}) 6262306a36Sopenharmony_ci#define BNX2X_PCI_FALLOC(y, size) \ 6362306a36Sopenharmony_ci({ \ 6462306a36Sopenharmony_ci void *x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \ 6562306a36Sopenharmony_ci if (x) { \ 6662306a36Sopenharmony_ci memset(x, 0xff, size); \ 6762306a36Sopenharmony_ci DP(NETIF_MSG_HW, \ 6862306a36Sopenharmony_ci "BNX2X_PCI_FALLOC: Physical %Lx Virtual %p\n", \ 6962306a36Sopenharmony_ci (unsigned long long)(*y), x); \ 7062306a36Sopenharmony_ci } \ 7162306a36Sopenharmony_ci x; \ 7262306a36Sopenharmony_ci}) 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci/*********************** Interfaces **************************** 7562306a36Sopenharmony_ci * Functions that need to be implemented by each driver version 7662306a36Sopenharmony_ci */ 7762306a36Sopenharmony_ci/* Init */ 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci/** 8062306a36Sopenharmony_ci * bnx2x_send_unload_req - request unload mode from the MCP. 8162306a36Sopenharmony_ci * 8262306a36Sopenharmony_ci * @bp: driver handle 8362306a36Sopenharmony_ci * @unload_mode: requested function's unload mode 8462306a36Sopenharmony_ci * 8562306a36Sopenharmony_ci * Return unload mode returned by the MCP: COMMON, PORT or FUNC. 8662306a36Sopenharmony_ci */ 8762306a36Sopenharmony_ciu32 bnx2x_send_unload_req(struct bnx2x *bp, int unload_mode); 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci/** 9062306a36Sopenharmony_ci * bnx2x_send_unload_done - send UNLOAD_DONE command to the MCP. 9162306a36Sopenharmony_ci * 9262306a36Sopenharmony_ci * @bp: driver handle 9362306a36Sopenharmony_ci * @keep_link: true iff link should be kept up 9462306a36Sopenharmony_ci */ 9562306a36Sopenharmony_civoid bnx2x_send_unload_done(struct bnx2x *bp, bool keep_link); 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci/** 9862306a36Sopenharmony_ci * bnx2x_config_rss_pf - configure RSS parameters in a PF. 9962306a36Sopenharmony_ci * 10062306a36Sopenharmony_ci * @bp: driver handle 10162306a36Sopenharmony_ci * @rss_obj: RSS object to use 10262306a36Sopenharmony_ci * @ind_table: indirection table to configure 10362306a36Sopenharmony_ci * @config_hash: re-configure RSS hash keys configuration 10462306a36Sopenharmony_ci * @enable: enabled or disabled configuration 10562306a36Sopenharmony_ci */ 10662306a36Sopenharmony_ciint bnx2x_rss(struct bnx2x *bp, struct bnx2x_rss_config_obj *rss_obj, 10762306a36Sopenharmony_ci bool config_hash, bool enable); 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci/** 11062306a36Sopenharmony_ci * bnx2x__init_func_obj - init function object 11162306a36Sopenharmony_ci * 11262306a36Sopenharmony_ci * @bp: driver handle 11362306a36Sopenharmony_ci * 11462306a36Sopenharmony_ci * Initializes the Function Object with the appropriate 11562306a36Sopenharmony_ci * parameters which include a function slow path driver 11662306a36Sopenharmony_ci * interface. 11762306a36Sopenharmony_ci */ 11862306a36Sopenharmony_civoid bnx2x__init_func_obj(struct bnx2x *bp); 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci/** 12162306a36Sopenharmony_ci * bnx2x_setup_queue - setup eth queue. 12262306a36Sopenharmony_ci * 12362306a36Sopenharmony_ci * @bp: driver handle 12462306a36Sopenharmony_ci * @fp: pointer to the fastpath structure 12562306a36Sopenharmony_ci * @leading: boolean 12662306a36Sopenharmony_ci * 12762306a36Sopenharmony_ci */ 12862306a36Sopenharmony_ciint bnx2x_setup_queue(struct bnx2x *bp, struct bnx2x_fastpath *fp, 12962306a36Sopenharmony_ci bool leading); 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci/** 13262306a36Sopenharmony_ci * bnx2x_setup_leading - bring up a leading eth queue. 13362306a36Sopenharmony_ci * 13462306a36Sopenharmony_ci * @bp: driver handle 13562306a36Sopenharmony_ci */ 13662306a36Sopenharmony_ciint bnx2x_setup_leading(struct bnx2x *bp); 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci/** 13962306a36Sopenharmony_ci * bnx2x_fw_command - send the MCP a request 14062306a36Sopenharmony_ci * 14162306a36Sopenharmony_ci * @bp: driver handle 14262306a36Sopenharmony_ci * @command: request 14362306a36Sopenharmony_ci * @param: request's parameter 14462306a36Sopenharmony_ci * 14562306a36Sopenharmony_ci * block until there is a reply 14662306a36Sopenharmony_ci */ 14762306a36Sopenharmony_ciu32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param); 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci/** 15062306a36Sopenharmony_ci * bnx2x_initial_phy_init - initialize link parameters structure variables. 15162306a36Sopenharmony_ci * 15262306a36Sopenharmony_ci * @bp: driver handle 15362306a36Sopenharmony_ci * @load_mode: current mode 15462306a36Sopenharmony_ci */ 15562306a36Sopenharmony_ciint bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode); 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci/** 15862306a36Sopenharmony_ci * bnx2x_link_set - configure hw according to link parameters structure. 15962306a36Sopenharmony_ci * 16062306a36Sopenharmony_ci * @bp: driver handle 16162306a36Sopenharmony_ci */ 16262306a36Sopenharmony_civoid bnx2x_link_set(struct bnx2x *bp); 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci/** 16562306a36Sopenharmony_ci * bnx2x_force_link_reset - Forces link reset, and put the PHY 16662306a36Sopenharmony_ci * in reset as well. 16762306a36Sopenharmony_ci * 16862306a36Sopenharmony_ci * @bp: driver handle 16962306a36Sopenharmony_ci */ 17062306a36Sopenharmony_civoid bnx2x_force_link_reset(struct bnx2x *bp); 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci/** 17362306a36Sopenharmony_ci * bnx2x_link_test - query link status. 17462306a36Sopenharmony_ci * 17562306a36Sopenharmony_ci * @bp: driver handle 17662306a36Sopenharmony_ci * @is_serdes: bool 17762306a36Sopenharmony_ci * 17862306a36Sopenharmony_ci * Returns 0 if link is UP. 17962306a36Sopenharmony_ci */ 18062306a36Sopenharmony_ciu8 bnx2x_link_test(struct bnx2x *bp, u8 is_serdes); 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci/** 18362306a36Sopenharmony_ci * bnx2x_drv_pulse - write driver pulse to shmem 18462306a36Sopenharmony_ci * 18562306a36Sopenharmony_ci * @bp: driver handle 18662306a36Sopenharmony_ci * 18762306a36Sopenharmony_ci * writes the value in bp->fw_drv_pulse_wr_seq to drv_pulse mbox 18862306a36Sopenharmony_ci * in the shmem. 18962306a36Sopenharmony_ci */ 19062306a36Sopenharmony_civoid bnx2x_drv_pulse(struct bnx2x *bp); 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci/** 19362306a36Sopenharmony_ci * bnx2x_igu_ack_sb - update IGU with current SB value 19462306a36Sopenharmony_ci * 19562306a36Sopenharmony_ci * @bp: driver handle 19662306a36Sopenharmony_ci * @igu_sb_id: SB id 19762306a36Sopenharmony_ci * @segment: SB segment 19862306a36Sopenharmony_ci * @index: SB index 19962306a36Sopenharmony_ci * @op: SB operation 20062306a36Sopenharmony_ci * @update: is HW update required 20162306a36Sopenharmony_ci */ 20262306a36Sopenharmony_civoid bnx2x_igu_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 segment, 20362306a36Sopenharmony_ci u16 index, u8 op, u8 update); 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci/* Disable transactions from chip to host */ 20662306a36Sopenharmony_civoid bnx2x_pf_disable(struct bnx2x *bp); 20762306a36Sopenharmony_ciint bnx2x_pretend_func(struct bnx2x *bp, u16 pretend_func_val); 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci/** 21062306a36Sopenharmony_ci * bnx2x__link_status_update - handles link status change. 21162306a36Sopenharmony_ci * 21262306a36Sopenharmony_ci * @bp: driver handle 21362306a36Sopenharmony_ci */ 21462306a36Sopenharmony_civoid bnx2x__link_status_update(struct bnx2x *bp); 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci/** 21762306a36Sopenharmony_ci * bnx2x_link_report - report link status to upper layer. 21862306a36Sopenharmony_ci * 21962306a36Sopenharmony_ci * @bp: driver handle 22062306a36Sopenharmony_ci */ 22162306a36Sopenharmony_civoid bnx2x_link_report(struct bnx2x *bp); 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci/* None-atomic version of bnx2x_link_report() */ 22462306a36Sopenharmony_civoid __bnx2x_link_report(struct bnx2x *bp); 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci/** 22762306a36Sopenharmony_ci * bnx2x_get_mf_speed - calculate MF speed. 22862306a36Sopenharmony_ci * 22962306a36Sopenharmony_ci * @bp: driver handle 23062306a36Sopenharmony_ci * 23162306a36Sopenharmony_ci * Takes into account current linespeed and MF configuration. 23262306a36Sopenharmony_ci */ 23362306a36Sopenharmony_ciu16 bnx2x_get_mf_speed(struct bnx2x *bp); 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci/** 23662306a36Sopenharmony_ci * bnx2x_msix_sp_int - MSI-X slowpath interrupt handler 23762306a36Sopenharmony_ci * 23862306a36Sopenharmony_ci * @irq: irq number 23962306a36Sopenharmony_ci * @dev_instance: private instance 24062306a36Sopenharmony_ci */ 24162306a36Sopenharmony_ciirqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance); 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci/** 24462306a36Sopenharmony_ci * bnx2x_interrupt - non MSI-X interrupt handler 24562306a36Sopenharmony_ci * 24662306a36Sopenharmony_ci * @irq: irq number 24762306a36Sopenharmony_ci * @dev_instance: private instance 24862306a36Sopenharmony_ci */ 24962306a36Sopenharmony_ciirqreturn_t bnx2x_interrupt(int irq, void *dev_instance); 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci/** 25262306a36Sopenharmony_ci * bnx2x_cnic_notify - send command to cnic driver 25362306a36Sopenharmony_ci * 25462306a36Sopenharmony_ci * @bp: driver handle 25562306a36Sopenharmony_ci * @cmd: command 25662306a36Sopenharmony_ci */ 25762306a36Sopenharmony_ciint bnx2x_cnic_notify(struct bnx2x *bp, int cmd); 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci/** 26062306a36Sopenharmony_ci * bnx2x_setup_cnic_irq_info - provides cnic with IRQ information 26162306a36Sopenharmony_ci * 26262306a36Sopenharmony_ci * @bp: driver handle 26362306a36Sopenharmony_ci */ 26462306a36Sopenharmony_civoid bnx2x_setup_cnic_irq_info(struct bnx2x *bp); 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci/** 26762306a36Sopenharmony_ci * bnx2x_setup_cnic_info - provides cnic with updated info 26862306a36Sopenharmony_ci * 26962306a36Sopenharmony_ci * @bp: driver handle 27062306a36Sopenharmony_ci */ 27162306a36Sopenharmony_civoid bnx2x_setup_cnic_info(struct bnx2x *bp); 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci/** 27462306a36Sopenharmony_ci * bnx2x_int_enable - enable HW interrupts. 27562306a36Sopenharmony_ci * 27662306a36Sopenharmony_ci * @bp: driver handle 27762306a36Sopenharmony_ci */ 27862306a36Sopenharmony_civoid bnx2x_int_enable(struct bnx2x *bp); 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci/** 28162306a36Sopenharmony_ci * bnx2x_int_disable_sync - disable interrupts. 28262306a36Sopenharmony_ci * 28362306a36Sopenharmony_ci * @bp: driver handle 28462306a36Sopenharmony_ci * @disable_hw: true, disable HW interrupts. 28562306a36Sopenharmony_ci * 28662306a36Sopenharmony_ci * This function ensures that there are no 28762306a36Sopenharmony_ci * ISRs or SP DPCs (sp_task) are running after it returns. 28862306a36Sopenharmony_ci */ 28962306a36Sopenharmony_civoid bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw); 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci/** 29262306a36Sopenharmony_ci * bnx2x_nic_init_cnic - init driver internals for cnic. 29362306a36Sopenharmony_ci * 29462306a36Sopenharmony_ci * @bp: driver handle 29562306a36Sopenharmony_ci * @load_code: COMMON, PORT or FUNCTION 29662306a36Sopenharmony_ci * 29762306a36Sopenharmony_ci * Initializes: 29862306a36Sopenharmony_ci * - rings 29962306a36Sopenharmony_ci * - status blocks 30062306a36Sopenharmony_ci * - etc. 30162306a36Sopenharmony_ci */ 30262306a36Sopenharmony_civoid bnx2x_nic_init_cnic(struct bnx2x *bp); 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci/** 30562306a36Sopenharmony_ci * bnx2x_preirq_nic_init - init driver internals. 30662306a36Sopenharmony_ci * 30762306a36Sopenharmony_ci * @bp: driver handle 30862306a36Sopenharmony_ci * 30962306a36Sopenharmony_ci * Initializes: 31062306a36Sopenharmony_ci * - fastpath object 31162306a36Sopenharmony_ci * - fastpath rings 31262306a36Sopenharmony_ci * etc. 31362306a36Sopenharmony_ci */ 31462306a36Sopenharmony_civoid bnx2x_pre_irq_nic_init(struct bnx2x *bp); 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci/** 31762306a36Sopenharmony_ci * bnx2x_postirq_nic_init - init driver internals. 31862306a36Sopenharmony_ci * 31962306a36Sopenharmony_ci * @bp: driver handle 32062306a36Sopenharmony_ci * @load_code: COMMON, PORT or FUNCTION 32162306a36Sopenharmony_ci * 32262306a36Sopenharmony_ci * Initializes: 32362306a36Sopenharmony_ci * - status blocks 32462306a36Sopenharmony_ci * - slowpath rings 32562306a36Sopenharmony_ci * - etc. 32662306a36Sopenharmony_ci */ 32762306a36Sopenharmony_civoid bnx2x_post_irq_nic_init(struct bnx2x *bp, u32 load_code); 32862306a36Sopenharmony_ci/** 32962306a36Sopenharmony_ci * bnx2x_alloc_mem_cnic - allocate driver's memory for cnic. 33062306a36Sopenharmony_ci * 33162306a36Sopenharmony_ci * @bp: driver handle 33262306a36Sopenharmony_ci */ 33362306a36Sopenharmony_ciint bnx2x_alloc_mem_cnic(struct bnx2x *bp); 33462306a36Sopenharmony_ci/** 33562306a36Sopenharmony_ci * bnx2x_alloc_mem - allocate driver's memory. 33662306a36Sopenharmony_ci * 33762306a36Sopenharmony_ci * @bp: driver handle 33862306a36Sopenharmony_ci */ 33962306a36Sopenharmony_ciint bnx2x_alloc_mem(struct bnx2x *bp); 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci/** 34262306a36Sopenharmony_ci * bnx2x_free_mem_cnic - release driver's memory for cnic. 34362306a36Sopenharmony_ci * 34462306a36Sopenharmony_ci * @bp: driver handle 34562306a36Sopenharmony_ci */ 34662306a36Sopenharmony_civoid bnx2x_free_mem_cnic(struct bnx2x *bp); 34762306a36Sopenharmony_ci/** 34862306a36Sopenharmony_ci * bnx2x_free_mem - release driver's memory. 34962306a36Sopenharmony_ci * 35062306a36Sopenharmony_ci * @bp: driver handle 35162306a36Sopenharmony_ci */ 35262306a36Sopenharmony_civoid bnx2x_free_mem(struct bnx2x *bp); 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci/** 35562306a36Sopenharmony_ci * bnx2x_set_num_queues - set number of queues according to mode. 35662306a36Sopenharmony_ci * 35762306a36Sopenharmony_ci * @bp: driver handle 35862306a36Sopenharmony_ci */ 35962306a36Sopenharmony_civoid bnx2x_set_num_queues(struct bnx2x *bp); 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci/** 36262306a36Sopenharmony_ci * bnx2x_chip_cleanup - cleanup chip internals. 36362306a36Sopenharmony_ci * 36462306a36Sopenharmony_ci * @bp: driver handle 36562306a36Sopenharmony_ci * @unload_mode: COMMON, PORT, FUNCTION 36662306a36Sopenharmony_ci * @keep_link: true iff link should be kept up. 36762306a36Sopenharmony_ci * 36862306a36Sopenharmony_ci * - Cleanup MAC configuration. 36962306a36Sopenharmony_ci * - Closes clients. 37062306a36Sopenharmony_ci * - etc. 37162306a36Sopenharmony_ci */ 37262306a36Sopenharmony_civoid bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode, bool keep_link); 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci/** 37562306a36Sopenharmony_ci * bnx2x_acquire_hw_lock - acquire HW lock. 37662306a36Sopenharmony_ci * 37762306a36Sopenharmony_ci * @bp: driver handle 37862306a36Sopenharmony_ci * @resource: resource bit which was locked 37962306a36Sopenharmony_ci */ 38062306a36Sopenharmony_ciint bnx2x_acquire_hw_lock(struct bnx2x *bp, u32 resource); 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ci/** 38362306a36Sopenharmony_ci * bnx2x_release_hw_lock - release HW lock. 38462306a36Sopenharmony_ci * 38562306a36Sopenharmony_ci * @bp: driver handle 38662306a36Sopenharmony_ci * @resource: resource bit which was locked 38762306a36Sopenharmony_ci */ 38862306a36Sopenharmony_ciint bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource); 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci/** 39162306a36Sopenharmony_ci * bnx2x_release_leader_lock - release recovery leader lock 39262306a36Sopenharmony_ci * 39362306a36Sopenharmony_ci * @bp: driver handle 39462306a36Sopenharmony_ci */ 39562306a36Sopenharmony_ciint bnx2x_release_leader_lock(struct bnx2x *bp); 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_ci/** 39862306a36Sopenharmony_ci * bnx2x_set_eth_mac - configure eth MAC address in the HW 39962306a36Sopenharmony_ci * 40062306a36Sopenharmony_ci * @bp: driver handle 40162306a36Sopenharmony_ci * @set: set or clear 40262306a36Sopenharmony_ci * 40362306a36Sopenharmony_ci * Configures according to the value in netdev->dev_addr. 40462306a36Sopenharmony_ci */ 40562306a36Sopenharmony_ciint bnx2x_set_eth_mac(struct bnx2x *bp, bool set); 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_ci/** 40862306a36Sopenharmony_ci * bnx2x_set_rx_mode - set MAC filtering configurations. 40962306a36Sopenharmony_ci * 41062306a36Sopenharmony_ci * @dev: netdevice 41162306a36Sopenharmony_ci * 41262306a36Sopenharmony_ci * called with netif_tx_lock from dev_mcast.c 41362306a36Sopenharmony_ci * If bp->state is OPEN, should be called with 41462306a36Sopenharmony_ci * netif_addr_lock_bh() 41562306a36Sopenharmony_ci */ 41662306a36Sopenharmony_civoid bnx2x_set_rx_mode_inner(struct bnx2x *bp); 41762306a36Sopenharmony_ci 41862306a36Sopenharmony_ci/* Parity errors related */ 41962306a36Sopenharmony_civoid bnx2x_set_pf_load(struct bnx2x *bp); 42062306a36Sopenharmony_cibool bnx2x_clear_pf_load(struct bnx2x *bp); 42162306a36Sopenharmony_cibool bnx2x_chk_parity_attn(struct bnx2x *bp, bool *global, bool print); 42262306a36Sopenharmony_cibool bnx2x_reset_is_done(struct bnx2x *bp, int engine); 42362306a36Sopenharmony_civoid bnx2x_set_reset_in_progress(struct bnx2x *bp); 42462306a36Sopenharmony_civoid bnx2x_set_reset_global(struct bnx2x *bp); 42562306a36Sopenharmony_civoid bnx2x_disable_close_the_gate(struct bnx2x *bp); 42662306a36Sopenharmony_ciint bnx2x_init_hw_func_cnic(struct bnx2x *bp); 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_civoid bnx2x_clear_vlan_info(struct bnx2x *bp); 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci/** 43162306a36Sopenharmony_ci * bnx2x_sp_event - handle ramrods completion. 43262306a36Sopenharmony_ci * 43362306a36Sopenharmony_ci * @fp: fastpath handle for the event 43462306a36Sopenharmony_ci * @rr_cqe: eth_rx_cqe 43562306a36Sopenharmony_ci */ 43662306a36Sopenharmony_civoid bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe); 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci/** 43962306a36Sopenharmony_ci * bnx2x_ilt_set_info - prepare ILT configurations. 44062306a36Sopenharmony_ci * 44162306a36Sopenharmony_ci * @bp: driver handle 44262306a36Sopenharmony_ci */ 44362306a36Sopenharmony_civoid bnx2x_ilt_set_info(struct bnx2x *bp); 44462306a36Sopenharmony_ci 44562306a36Sopenharmony_ci/** 44662306a36Sopenharmony_ci * bnx2x_ilt_set_cnic_info - prepare ILT configurations for SRC 44762306a36Sopenharmony_ci * and TM. 44862306a36Sopenharmony_ci * 44962306a36Sopenharmony_ci * @bp: driver handle 45062306a36Sopenharmony_ci */ 45162306a36Sopenharmony_civoid bnx2x_ilt_set_info_cnic(struct bnx2x *bp); 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_ci/** 45462306a36Sopenharmony_ci * bnx2x_dcbx_init - initialize dcbx protocol. 45562306a36Sopenharmony_ci * 45662306a36Sopenharmony_ci * @bp: driver handle 45762306a36Sopenharmony_ci */ 45862306a36Sopenharmony_civoid bnx2x_dcbx_init(struct bnx2x *bp, bool update_shmem); 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci/** 46162306a36Sopenharmony_ci * bnx2x_set_power_state - set power state to the requested value. 46262306a36Sopenharmony_ci * 46362306a36Sopenharmony_ci * @bp: driver handle 46462306a36Sopenharmony_ci * @state: required state D0 or D3hot 46562306a36Sopenharmony_ci * 46662306a36Sopenharmony_ci * Currently only D0 and D3hot are supported. 46762306a36Sopenharmony_ci */ 46862306a36Sopenharmony_ciint bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state); 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ci/** 47162306a36Sopenharmony_ci * bnx2x_update_max_mf_config - update MAX part of MF configuration in HW. 47262306a36Sopenharmony_ci * 47362306a36Sopenharmony_ci * @bp: driver handle 47462306a36Sopenharmony_ci * @value: new value 47562306a36Sopenharmony_ci */ 47662306a36Sopenharmony_civoid bnx2x_update_max_mf_config(struct bnx2x *bp, u32 value); 47762306a36Sopenharmony_ci/* Error handling */ 47862306a36Sopenharmony_civoid bnx2x_fw_dump_lvl(struct bnx2x *bp, const char *lvl); 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ci/* dev_close main block */ 48162306a36Sopenharmony_ciint bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link); 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_ci/* dev_open main block */ 48462306a36Sopenharmony_ciint bnx2x_nic_load(struct bnx2x *bp, int load_mode); 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ci/* hard_xmit callback */ 48762306a36Sopenharmony_cinetdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev); 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci/* setup_tc callback */ 49062306a36Sopenharmony_ciint bnx2x_setup_tc(struct net_device *dev, u8 num_tc); 49162306a36Sopenharmony_ciint __bnx2x_setup_tc(struct net_device *dev, enum tc_setup_type type, 49262306a36Sopenharmony_ci void *type_data); 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_ciint bnx2x_get_vf_config(struct net_device *dev, int vf, 49562306a36Sopenharmony_ci struct ifla_vf_info *ivi); 49662306a36Sopenharmony_ciint bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac); 49762306a36Sopenharmony_ciint bnx2x_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos, 49862306a36Sopenharmony_ci __be16 vlan_proto); 49962306a36Sopenharmony_ciint bnx2x_set_vf_spoofchk(struct net_device *dev, int idx, bool val); 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_ci/* select_queue callback */ 50262306a36Sopenharmony_ciu16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, 50362306a36Sopenharmony_ci struct net_device *sb_dev); 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_cistatic inline void bnx2x_update_rx_prod(struct bnx2x *bp, 50662306a36Sopenharmony_ci struct bnx2x_fastpath *fp, 50762306a36Sopenharmony_ci u16 bd_prod, u16 rx_comp_prod, 50862306a36Sopenharmony_ci u16 rx_sge_prod) 50962306a36Sopenharmony_ci{ 51062306a36Sopenharmony_ci struct ustorm_eth_rx_producers rx_prods = {0}; 51162306a36Sopenharmony_ci u32 i; 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ci /* Update producers */ 51462306a36Sopenharmony_ci rx_prods.bd_prod = bd_prod; 51562306a36Sopenharmony_ci rx_prods.cqe_prod = rx_comp_prod; 51662306a36Sopenharmony_ci rx_prods.sge_prod = rx_sge_prod; 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_ci /* Make sure that the BD and SGE data is updated before updating the 51962306a36Sopenharmony_ci * producers since FW might read the BD/SGE right after the producer 52062306a36Sopenharmony_ci * is updated. 52162306a36Sopenharmony_ci * This is only applicable for weak-ordered memory model archs such 52262306a36Sopenharmony_ci * as IA-64. The following barrier is also mandatory since FW will 52362306a36Sopenharmony_ci * assumes BDs must have buffers. 52462306a36Sopenharmony_ci */ 52562306a36Sopenharmony_ci wmb(); 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_ci for (i = 0; i < sizeof(rx_prods)/4; i++) 52862306a36Sopenharmony_ci REG_WR_RELAXED(bp, fp->ustorm_rx_prods_offset + i * 4, 52962306a36Sopenharmony_ci ((u32 *)&rx_prods)[i]); 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_ci DP(NETIF_MSG_RX_STATUS, 53262306a36Sopenharmony_ci "queue[%d]: wrote bd_prod %u cqe_prod %u sge_prod %u\n", 53362306a36Sopenharmony_ci fp->index, bd_prod, rx_comp_prod, rx_sge_prod); 53462306a36Sopenharmony_ci} 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_ci/* reload helper */ 53762306a36Sopenharmony_ciint bnx2x_reload_if_running(struct net_device *dev); 53862306a36Sopenharmony_ci 53962306a36Sopenharmony_ciint bnx2x_change_mac_addr(struct net_device *dev, void *p); 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_ci/* NAPI poll Tx part */ 54262306a36Sopenharmony_ciint bnx2x_tx_int(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata); 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_ciextern const struct dev_pm_ops bnx2x_pm_ops; 54562306a36Sopenharmony_ci 54662306a36Sopenharmony_ci/* Release IRQ vectors */ 54762306a36Sopenharmony_civoid bnx2x_free_irq(struct bnx2x *bp); 54862306a36Sopenharmony_ci 54962306a36Sopenharmony_civoid bnx2x_free_fp_mem(struct bnx2x *bp); 55062306a36Sopenharmony_civoid bnx2x_init_rx_rings(struct bnx2x *bp); 55162306a36Sopenharmony_civoid bnx2x_init_rx_rings_cnic(struct bnx2x *bp); 55262306a36Sopenharmony_civoid bnx2x_free_skbs(struct bnx2x *bp); 55362306a36Sopenharmony_civoid bnx2x_netif_stop(struct bnx2x *bp, int disable_hw); 55462306a36Sopenharmony_civoid bnx2x_netif_start(struct bnx2x *bp); 55562306a36Sopenharmony_ciint bnx2x_load_cnic(struct bnx2x *bp); 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci/** 55862306a36Sopenharmony_ci * bnx2x_enable_msix - set msix configuration. 55962306a36Sopenharmony_ci * 56062306a36Sopenharmony_ci * @bp: driver handle 56162306a36Sopenharmony_ci * 56262306a36Sopenharmony_ci * fills msix_table, requests vectors, updates num_queues 56362306a36Sopenharmony_ci * according to number of available vectors. 56462306a36Sopenharmony_ci */ 56562306a36Sopenharmony_ciint bnx2x_enable_msix(struct bnx2x *bp); 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_ci/** 56862306a36Sopenharmony_ci * bnx2x_enable_msi - request msi mode from OS, updated internals accordingly 56962306a36Sopenharmony_ci * 57062306a36Sopenharmony_ci * @bp: driver handle 57162306a36Sopenharmony_ci */ 57262306a36Sopenharmony_ciint bnx2x_enable_msi(struct bnx2x *bp); 57362306a36Sopenharmony_ci 57462306a36Sopenharmony_ci/** 57562306a36Sopenharmony_ci * bnx2x_alloc_mem_bp - allocate memories outsize main driver structure 57662306a36Sopenharmony_ci * 57762306a36Sopenharmony_ci * @bp: driver handle 57862306a36Sopenharmony_ci */ 57962306a36Sopenharmony_ciint bnx2x_alloc_mem_bp(struct bnx2x *bp); 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci/** 58262306a36Sopenharmony_ci * bnx2x_free_mem_bp - release memories outsize main driver structure 58362306a36Sopenharmony_ci * 58462306a36Sopenharmony_ci * @bp: driver handle 58562306a36Sopenharmony_ci */ 58662306a36Sopenharmony_civoid bnx2x_free_mem_bp(struct bnx2x *bp); 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_ci/** 58962306a36Sopenharmony_ci * bnx2x_change_mtu - change mtu netdev callback 59062306a36Sopenharmony_ci * 59162306a36Sopenharmony_ci * @dev: net device 59262306a36Sopenharmony_ci * @new_mtu: requested mtu 59362306a36Sopenharmony_ci * 59462306a36Sopenharmony_ci */ 59562306a36Sopenharmony_ciint bnx2x_change_mtu(struct net_device *dev, int new_mtu); 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_ci#ifdef NETDEV_FCOE_WWNN 59862306a36Sopenharmony_ci/** 59962306a36Sopenharmony_ci * bnx2x_fcoe_get_wwn - return the requested WWN value for this port 60062306a36Sopenharmony_ci * 60162306a36Sopenharmony_ci * @dev: net_device 60262306a36Sopenharmony_ci * @wwn: output buffer 60362306a36Sopenharmony_ci * @type: WWN type: NETDEV_FCOE_WWNN (node) or NETDEV_FCOE_WWPN (port) 60462306a36Sopenharmony_ci * 60562306a36Sopenharmony_ci */ 60662306a36Sopenharmony_ciint bnx2x_fcoe_get_wwn(struct net_device *dev, u64 *wwn, int type); 60762306a36Sopenharmony_ci#endif 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_cinetdev_features_t bnx2x_fix_features(struct net_device *dev, 61062306a36Sopenharmony_ci netdev_features_t features); 61162306a36Sopenharmony_ciint bnx2x_set_features(struct net_device *dev, netdev_features_t features); 61262306a36Sopenharmony_ci 61362306a36Sopenharmony_ci/** 61462306a36Sopenharmony_ci * bnx2x_tx_timeout - tx timeout netdev callback 61562306a36Sopenharmony_ci * 61662306a36Sopenharmony_ci * @dev: net device 61762306a36Sopenharmony_ci */ 61862306a36Sopenharmony_civoid bnx2x_tx_timeout(struct net_device *dev, unsigned int txqueue); 61962306a36Sopenharmony_ci 62062306a36Sopenharmony_ci/** bnx2x_get_c2s_mapping - read inner-to-outer vlan configuration 62162306a36Sopenharmony_ci * c2s_map should have BNX2X_MAX_PRIORITY entries. 62262306a36Sopenharmony_ci * @bp: driver handle 62362306a36Sopenharmony_ci * @c2s_map: should have BNX2X_MAX_PRIORITY entries for mapping 62462306a36Sopenharmony_ci * @c2s_default: entry for non-tagged configuration 62562306a36Sopenharmony_ci */ 62662306a36Sopenharmony_civoid bnx2x_get_c2s_mapping(struct bnx2x *bp, u8 *c2s_map, u8 *c2s_default); 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_ci/*********************** Inlines **********************************/ 62962306a36Sopenharmony_ci/*********************** Fast path ********************************/ 63062306a36Sopenharmony_cistatic inline void bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp) 63162306a36Sopenharmony_ci{ 63262306a36Sopenharmony_ci barrier(); /* status block is written to by the chip */ 63362306a36Sopenharmony_ci fp->fp_hc_idx = fp->sb_running_index[SM_RX_ID]; 63462306a36Sopenharmony_ci} 63562306a36Sopenharmony_ci 63662306a36Sopenharmony_cistatic inline void bnx2x_igu_ack_sb_gen(struct bnx2x *bp, u8 igu_sb_id, 63762306a36Sopenharmony_ci u8 segment, u16 index, u8 op, 63862306a36Sopenharmony_ci u8 update, u32 igu_addr) 63962306a36Sopenharmony_ci{ 64062306a36Sopenharmony_ci struct igu_regular cmd_data = {0}; 64162306a36Sopenharmony_ci 64262306a36Sopenharmony_ci cmd_data.sb_id_and_flags = 64362306a36Sopenharmony_ci ((index << IGU_REGULAR_SB_INDEX_SHIFT) | 64462306a36Sopenharmony_ci (segment << IGU_REGULAR_SEGMENT_ACCESS_SHIFT) | 64562306a36Sopenharmony_ci (update << IGU_REGULAR_BUPDATE_SHIFT) | 64662306a36Sopenharmony_ci (op << IGU_REGULAR_ENABLE_INT_SHIFT)); 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_ci DP(NETIF_MSG_INTR, "write 0x%08x to IGU addr 0x%x\n", 64962306a36Sopenharmony_ci cmd_data.sb_id_and_flags, igu_addr); 65062306a36Sopenharmony_ci REG_WR(bp, igu_addr, cmd_data.sb_id_and_flags); 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_ci /* Make sure that ACK is written */ 65362306a36Sopenharmony_ci barrier(); 65462306a36Sopenharmony_ci} 65562306a36Sopenharmony_ci 65662306a36Sopenharmony_cistatic inline void bnx2x_hc_ack_sb(struct bnx2x *bp, u8 sb_id, 65762306a36Sopenharmony_ci u8 storm, u16 index, u8 op, u8 update) 65862306a36Sopenharmony_ci{ 65962306a36Sopenharmony_ci u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 + 66062306a36Sopenharmony_ci COMMAND_REG_INT_ACK); 66162306a36Sopenharmony_ci struct igu_ack_register igu_ack; 66262306a36Sopenharmony_ci 66362306a36Sopenharmony_ci igu_ack.status_block_index = index; 66462306a36Sopenharmony_ci igu_ack.sb_id_and_flags = 66562306a36Sopenharmony_ci ((sb_id << IGU_ACK_REGISTER_STATUS_BLOCK_ID_SHIFT) | 66662306a36Sopenharmony_ci (storm << IGU_ACK_REGISTER_STORM_ID_SHIFT) | 66762306a36Sopenharmony_ci (update << IGU_ACK_REGISTER_UPDATE_INDEX_SHIFT) | 66862306a36Sopenharmony_ci (op << IGU_ACK_REGISTER_INTERRUPT_MODE_SHIFT)); 66962306a36Sopenharmony_ci 67062306a36Sopenharmony_ci REG_WR(bp, hc_addr, (*(u32 *)&igu_ack)); 67162306a36Sopenharmony_ci 67262306a36Sopenharmony_ci /* Make sure that ACK is written */ 67362306a36Sopenharmony_ci barrier(); 67462306a36Sopenharmony_ci} 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_cistatic inline void bnx2x_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 storm, 67762306a36Sopenharmony_ci u16 index, u8 op, u8 update) 67862306a36Sopenharmony_ci{ 67962306a36Sopenharmony_ci if (bp->common.int_block == INT_BLOCK_HC) 68062306a36Sopenharmony_ci bnx2x_hc_ack_sb(bp, igu_sb_id, storm, index, op, update); 68162306a36Sopenharmony_ci else { 68262306a36Sopenharmony_ci u8 segment; 68362306a36Sopenharmony_ci 68462306a36Sopenharmony_ci if (CHIP_INT_MODE_IS_BC(bp)) 68562306a36Sopenharmony_ci segment = storm; 68662306a36Sopenharmony_ci else if (igu_sb_id != bp->igu_dsb_id) 68762306a36Sopenharmony_ci segment = IGU_SEG_ACCESS_DEF; 68862306a36Sopenharmony_ci else if (storm == ATTENTION_ID) 68962306a36Sopenharmony_ci segment = IGU_SEG_ACCESS_ATTN; 69062306a36Sopenharmony_ci else 69162306a36Sopenharmony_ci segment = IGU_SEG_ACCESS_DEF; 69262306a36Sopenharmony_ci bnx2x_igu_ack_sb(bp, igu_sb_id, segment, index, op, update); 69362306a36Sopenharmony_ci } 69462306a36Sopenharmony_ci} 69562306a36Sopenharmony_ci 69662306a36Sopenharmony_cistatic inline u16 bnx2x_hc_ack_int(struct bnx2x *bp) 69762306a36Sopenharmony_ci{ 69862306a36Sopenharmony_ci u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 + 69962306a36Sopenharmony_ci COMMAND_REG_SIMD_MASK); 70062306a36Sopenharmony_ci u32 result = REG_RD(bp, hc_addr); 70162306a36Sopenharmony_ci 70262306a36Sopenharmony_ci barrier(); 70362306a36Sopenharmony_ci return result; 70462306a36Sopenharmony_ci} 70562306a36Sopenharmony_ci 70662306a36Sopenharmony_cistatic inline u16 bnx2x_igu_ack_int(struct bnx2x *bp) 70762306a36Sopenharmony_ci{ 70862306a36Sopenharmony_ci u32 igu_addr = (BAR_IGU_INTMEM + IGU_REG_SISR_MDPC_WMASK_LSB_UPPER*8); 70962306a36Sopenharmony_ci u32 result = REG_RD(bp, igu_addr); 71062306a36Sopenharmony_ci 71162306a36Sopenharmony_ci DP(NETIF_MSG_INTR, "read 0x%08x from IGU addr 0x%x\n", 71262306a36Sopenharmony_ci result, igu_addr); 71362306a36Sopenharmony_ci 71462306a36Sopenharmony_ci barrier(); 71562306a36Sopenharmony_ci return result; 71662306a36Sopenharmony_ci} 71762306a36Sopenharmony_ci 71862306a36Sopenharmony_cistatic inline u16 bnx2x_ack_int(struct bnx2x *bp) 71962306a36Sopenharmony_ci{ 72062306a36Sopenharmony_ci barrier(); 72162306a36Sopenharmony_ci if (bp->common.int_block == INT_BLOCK_HC) 72262306a36Sopenharmony_ci return bnx2x_hc_ack_int(bp); 72362306a36Sopenharmony_ci else 72462306a36Sopenharmony_ci return bnx2x_igu_ack_int(bp); 72562306a36Sopenharmony_ci} 72662306a36Sopenharmony_ci 72762306a36Sopenharmony_cistatic inline int bnx2x_has_tx_work_unload(struct bnx2x_fp_txdata *txdata) 72862306a36Sopenharmony_ci{ 72962306a36Sopenharmony_ci /* Tell compiler that consumer and producer can change */ 73062306a36Sopenharmony_ci barrier(); 73162306a36Sopenharmony_ci return txdata->tx_pkt_prod != txdata->tx_pkt_cons; 73262306a36Sopenharmony_ci} 73362306a36Sopenharmony_ci 73462306a36Sopenharmony_cistatic inline u16 bnx2x_tx_avail(struct bnx2x *bp, 73562306a36Sopenharmony_ci struct bnx2x_fp_txdata *txdata) 73662306a36Sopenharmony_ci{ 73762306a36Sopenharmony_ci s16 used; 73862306a36Sopenharmony_ci u16 prod; 73962306a36Sopenharmony_ci u16 cons; 74062306a36Sopenharmony_ci 74162306a36Sopenharmony_ci prod = txdata->tx_bd_prod; 74262306a36Sopenharmony_ci cons = txdata->tx_bd_cons; 74362306a36Sopenharmony_ci 74462306a36Sopenharmony_ci used = SUB_S16(prod, cons); 74562306a36Sopenharmony_ci 74662306a36Sopenharmony_ci#ifdef BNX2X_STOP_ON_ERROR 74762306a36Sopenharmony_ci WARN_ON(used < 0); 74862306a36Sopenharmony_ci WARN_ON(used > txdata->tx_ring_size); 74962306a36Sopenharmony_ci WARN_ON((txdata->tx_ring_size - used) > MAX_TX_AVAIL); 75062306a36Sopenharmony_ci#endif 75162306a36Sopenharmony_ci 75262306a36Sopenharmony_ci return (s16)(txdata->tx_ring_size) - used; 75362306a36Sopenharmony_ci} 75462306a36Sopenharmony_ci 75562306a36Sopenharmony_cistatic inline int bnx2x_tx_queue_has_work(struct bnx2x_fp_txdata *txdata) 75662306a36Sopenharmony_ci{ 75762306a36Sopenharmony_ci u16 hw_cons; 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_ci /* Tell compiler that status block fields can change */ 76062306a36Sopenharmony_ci barrier(); 76162306a36Sopenharmony_ci hw_cons = le16_to_cpu(*txdata->tx_cons_sb); 76262306a36Sopenharmony_ci return hw_cons != txdata->tx_pkt_cons; 76362306a36Sopenharmony_ci} 76462306a36Sopenharmony_ci 76562306a36Sopenharmony_cistatic inline bool bnx2x_has_tx_work(struct bnx2x_fastpath *fp) 76662306a36Sopenharmony_ci{ 76762306a36Sopenharmony_ci u8 cos; 76862306a36Sopenharmony_ci for_each_cos_in_tx_queue(fp, cos) 76962306a36Sopenharmony_ci if (bnx2x_tx_queue_has_work(fp->txdata_ptr[cos])) 77062306a36Sopenharmony_ci return true; 77162306a36Sopenharmony_ci return false; 77262306a36Sopenharmony_ci} 77362306a36Sopenharmony_ci 77462306a36Sopenharmony_ci#define BNX2X_IS_CQE_COMPLETED(cqe_fp) (cqe_fp->marker == 0x0) 77562306a36Sopenharmony_ci#define BNX2X_SEED_CQE(cqe_fp) (cqe_fp->marker = 0xFFFFFFFF) 77662306a36Sopenharmony_cistatic inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp) 77762306a36Sopenharmony_ci{ 77862306a36Sopenharmony_ci u16 cons; 77962306a36Sopenharmony_ci union eth_rx_cqe *cqe; 78062306a36Sopenharmony_ci struct eth_fast_path_rx_cqe *cqe_fp; 78162306a36Sopenharmony_ci 78262306a36Sopenharmony_ci cons = RCQ_BD(fp->rx_comp_cons); 78362306a36Sopenharmony_ci cqe = &fp->rx_comp_ring[cons]; 78462306a36Sopenharmony_ci cqe_fp = &cqe->fast_path_cqe; 78562306a36Sopenharmony_ci return BNX2X_IS_CQE_COMPLETED(cqe_fp); 78662306a36Sopenharmony_ci} 78762306a36Sopenharmony_ci 78862306a36Sopenharmony_ci/** 78962306a36Sopenharmony_ci * bnx2x_tx_disable - disables tx from stack point of view 79062306a36Sopenharmony_ci * 79162306a36Sopenharmony_ci * @bp: driver handle 79262306a36Sopenharmony_ci */ 79362306a36Sopenharmony_cistatic inline void bnx2x_tx_disable(struct bnx2x *bp) 79462306a36Sopenharmony_ci{ 79562306a36Sopenharmony_ci netif_tx_disable(bp->dev); 79662306a36Sopenharmony_ci netif_carrier_off(bp->dev); 79762306a36Sopenharmony_ci} 79862306a36Sopenharmony_ci 79962306a36Sopenharmony_cistatic inline void bnx2x_free_rx_sge(struct bnx2x *bp, 80062306a36Sopenharmony_ci struct bnx2x_fastpath *fp, u16 index) 80162306a36Sopenharmony_ci{ 80262306a36Sopenharmony_ci struct sw_rx_page *sw_buf = &fp->rx_page_ring[index]; 80362306a36Sopenharmony_ci struct page *page = sw_buf->page; 80462306a36Sopenharmony_ci struct eth_rx_sge *sge = &fp->rx_sge_ring[index]; 80562306a36Sopenharmony_ci 80662306a36Sopenharmony_ci /* Skip "next page" elements */ 80762306a36Sopenharmony_ci if (!page) 80862306a36Sopenharmony_ci return; 80962306a36Sopenharmony_ci 81062306a36Sopenharmony_ci /* Since many fragments can share the same page, make sure to 81162306a36Sopenharmony_ci * only unmap and free the page once. 81262306a36Sopenharmony_ci */ 81362306a36Sopenharmony_ci dma_unmap_page(&bp->pdev->dev, dma_unmap_addr(sw_buf, mapping), 81462306a36Sopenharmony_ci SGE_PAGE_SIZE, DMA_FROM_DEVICE); 81562306a36Sopenharmony_ci 81662306a36Sopenharmony_ci put_page(page); 81762306a36Sopenharmony_ci 81862306a36Sopenharmony_ci sw_buf->page = NULL; 81962306a36Sopenharmony_ci sge->addr_hi = 0; 82062306a36Sopenharmony_ci sge->addr_lo = 0; 82162306a36Sopenharmony_ci} 82262306a36Sopenharmony_ci 82362306a36Sopenharmony_cistatic inline void bnx2x_del_all_napi_cnic(struct bnx2x *bp) 82462306a36Sopenharmony_ci{ 82562306a36Sopenharmony_ci int i; 82662306a36Sopenharmony_ci 82762306a36Sopenharmony_ci for_each_rx_queue_cnic(bp, i) { 82862306a36Sopenharmony_ci __netif_napi_del(&bnx2x_fp(bp, i, napi)); 82962306a36Sopenharmony_ci } 83062306a36Sopenharmony_ci synchronize_net(); 83162306a36Sopenharmony_ci} 83262306a36Sopenharmony_ci 83362306a36Sopenharmony_cistatic inline void bnx2x_del_all_napi(struct bnx2x *bp) 83462306a36Sopenharmony_ci{ 83562306a36Sopenharmony_ci int i; 83662306a36Sopenharmony_ci 83762306a36Sopenharmony_ci for_each_eth_queue(bp, i) { 83862306a36Sopenharmony_ci __netif_napi_del(&bnx2x_fp(bp, i, napi)); 83962306a36Sopenharmony_ci } 84062306a36Sopenharmony_ci synchronize_net(); 84162306a36Sopenharmony_ci} 84262306a36Sopenharmony_ci 84362306a36Sopenharmony_ciint bnx2x_set_int_mode(struct bnx2x *bp); 84462306a36Sopenharmony_ci 84562306a36Sopenharmony_cistatic inline void bnx2x_disable_msi(struct bnx2x *bp) 84662306a36Sopenharmony_ci{ 84762306a36Sopenharmony_ci if (bp->flags & USING_MSIX_FLAG) { 84862306a36Sopenharmony_ci pci_disable_msix(bp->pdev); 84962306a36Sopenharmony_ci bp->flags &= ~(USING_MSIX_FLAG | USING_SINGLE_MSIX_FLAG); 85062306a36Sopenharmony_ci } else if (bp->flags & USING_MSI_FLAG) { 85162306a36Sopenharmony_ci pci_disable_msi(bp->pdev); 85262306a36Sopenharmony_ci bp->flags &= ~USING_MSI_FLAG; 85362306a36Sopenharmony_ci } 85462306a36Sopenharmony_ci} 85562306a36Sopenharmony_ci 85662306a36Sopenharmony_cistatic inline void bnx2x_clear_sge_mask_next_elems(struct bnx2x_fastpath *fp) 85762306a36Sopenharmony_ci{ 85862306a36Sopenharmony_ci int i, j; 85962306a36Sopenharmony_ci 86062306a36Sopenharmony_ci for (i = 1; i <= NUM_RX_SGE_PAGES; i++) { 86162306a36Sopenharmony_ci int idx = RX_SGE_CNT * i - 1; 86262306a36Sopenharmony_ci 86362306a36Sopenharmony_ci for (j = 0; j < 2; j++) { 86462306a36Sopenharmony_ci BIT_VEC64_CLEAR_BIT(fp->sge_mask, idx); 86562306a36Sopenharmony_ci idx--; 86662306a36Sopenharmony_ci } 86762306a36Sopenharmony_ci } 86862306a36Sopenharmony_ci} 86962306a36Sopenharmony_ci 87062306a36Sopenharmony_cistatic inline void bnx2x_init_sge_ring_bit_mask(struct bnx2x_fastpath *fp) 87162306a36Sopenharmony_ci{ 87262306a36Sopenharmony_ci /* Set the mask to all 1-s: it's faster to compare to 0 than to 0xf-s */ 87362306a36Sopenharmony_ci memset(fp->sge_mask, 0xff, sizeof(fp->sge_mask)); 87462306a36Sopenharmony_ci 87562306a36Sopenharmony_ci /* Clear the two last indices in the page to 1: 87662306a36Sopenharmony_ci these are the indices that correspond to the "next" element, 87762306a36Sopenharmony_ci hence will never be indicated and should be removed from 87862306a36Sopenharmony_ci the calculations. */ 87962306a36Sopenharmony_ci bnx2x_clear_sge_mask_next_elems(fp); 88062306a36Sopenharmony_ci} 88162306a36Sopenharmony_ci 88262306a36Sopenharmony_ci/* note that we are not allocating a new buffer, 88362306a36Sopenharmony_ci * we are just moving one from cons to prod 88462306a36Sopenharmony_ci * we are not creating a new mapping, 88562306a36Sopenharmony_ci * so there is no need to check for dma_mapping_error(). 88662306a36Sopenharmony_ci */ 88762306a36Sopenharmony_cistatic inline void bnx2x_reuse_rx_data(struct bnx2x_fastpath *fp, 88862306a36Sopenharmony_ci u16 cons, u16 prod) 88962306a36Sopenharmony_ci{ 89062306a36Sopenharmony_ci struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons]; 89162306a36Sopenharmony_ci struct sw_rx_bd *prod_rx_buf = &fp->rx_buf_ring[prod]; 89262306a36Sopenharmony_ci struct eth_rx_bd *cons_bd = &fp->rx_desc_ring[cons]; 89362306a36Sopenharmony_ci struct eth_rx_bd *prod_bd = &fp->rx_desc_ring[prod]; 89462306a36Sopenharmony_ci 89562306a36Sopenharmony_ci dma_unmap_addr_set(prod_rx_buf, mapping, 89662306a36Sopenharmony_ci dma_unmap_addr(cons_rx_buf, mapping)); 89762306a36Sopenharmony_ci prod_rx_buf->data = cons_rx_buf->data; 89862306a36Sopenharmony_ci *prod_bd = *cons_bd; 89962306a36Sopenharmony_ci} 90062306a36Sopenharmony_ci 90162306a36Sopenharmony_ci/************************* Init ******************************************/ 90262306a36Sopenharmony_ci 90362306a36Sopenharmony_ci/* returns func by VN for current port */ 90462306a36Sopenharmony_cistatic inline int func_by_vn(struct bnx2x *bp, int vn) 90562306a36Sopenharmony_ci{ 90662306a36Sopenharmony_ci return 2 * vn + BP_PORT(bp); 90762306a36Sopenharmony_ci} 90862306a36Sopenharmony_ci 90962306a36Sopenharmony_cistatic inline int bnx2x_config_rss_eth(struct bnx2x *bp, bool config_hash) 91062306a36Sopenharmony_ci{ 91162306a36Sopenharmony_ci return bnx2x_rss(bp, &bp->rss_conf_obj, config_hash, true); 91262306a36Sopenharmony_ci} 91362306a36Sopenharmony_ci 91462306a36Sopenharmony_ci/** 91562306a36Sopenharmony_ci * bnx2x_func_start - init function 91662306a36Sopenharmony_ci * 91762306a36Sopenharmony_ci * @bp: driver handle 91862306a36Sopenharmony_ci * 91962306a36Sopenharmony_ci * Must be called before sending CLIENT_SETUP for the first client. 92062306a36Sopenharmony_ci */ 92162306a36Sopenharmony_cistatic inline int bnx2x_func_start(struct bnx2x *bp) 92262306a36Sopenharmony_ci{ 92362306a36Sopenharmony_ci struct bnx2x_func_state_params func_params = {NULL}; 92462306a36Sopenharmony_ci struct bnx2x_func_start_params *start_params = 92562306a36Sopenharmony_ci &func_params.params.start; 92662306a36Sopenharmony_ci u16 port; 92762306a36Sopenharmony_ci 92862306a36Sopenharmony_ci /* Prepare parameters for function state transitions */ 92962306a36Sopenharmony_ci __set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags); 93062306a36Sopenharmony_ci 93162306a36Sopenharmony_ci func_params.f_obj = &bp->func_obj; 93262306a36Sopenharmony_ci func_params.cmd = BNX2X_F_CMD_START; 93362306a36Sopenharmony_ci 93462306a36Sopenharmony_ci /* Function parameters */ 93562306a36Sopenharmony_ci start_params->mf_mode = bp->mf_mode; 93662306a36Sopenharmony_ci start_params->sd_vlan_tag = bp->mf_ov; 93762306a36Sopenharmony_ci 93862306a36Sopenharmony_ci /* Configure Ethertype for BD mode */ 93962306a36Sopenharmony_ci if (IS_MF_BD(bp)) { 94062306a36Sopenharmony_ci DP(NETIF_MSG_IFUP, "Configuring ethertype 0x88a8 for BD\n"); 94162306a36Sopenharmony_ci start_params->sd_vlan_eth_type = ETH_P_8021AD; 94262306a36Sopenharmony_ci REG_WR(bp, PRS_REG_VLAN_TYPE_0, ETH_P_8021AD); 94362306a36Sopenharmony_ci REG_WR(bp, PBF_REG_VLAN_TYPE_0, ETH_P_8021AD); 94462306a36Sopenharmony_ci REG_WR(bp, NIG_REG_LLH_E1HOV_TYPE_1, ETH_P_8021AD); 94562306a36Sopenharmony_ci 94662306a36Sopenharmony_ci bnx2x_get_c2s_mapping(bp, start_params->c2s_pri, 94762306a36Sopenharmony_ci &start_params->c2s_pri_default); 94862306a36Sopenharmony_ci start_params->c2s_pri_valid = 1; 94962306a36Sopenharmony_ci 95062306a36Sopenharmony_ci DP(NETIF_MSG_IFUP, 95162306a36Sopenharmony_ci "Inner-to-Outer priority: %02x %02x %02x %02x %02x %02x %02x %02x [Default %02x]\n", 95262306a36Sopenharmony_ci start_params->c2s_pri[0], start_params->c2s_pri[1], 95362306a36Sopenharmony_ci start_params->c2s_pri[2], start_params->c2s_pri[3], 95462306a36Sopenharmony_ci start_params->c2s_pri[4], start_params->c2s_pri[5], 95562306a36Sopenharmony_ci start_params->c2s_pri[6], start_params->c2s_pri[7], 95662306a36Sopenharmony_ci start_params->c2s_pri_default); 95762306a36Sopenharmony_ci } 95862306a36Sopenharmony_ci 95962306a36Sopenharmony_ci if (CHIP_IS_E2(bp) || CHIP_IS_E3(bp)) 96062306a36Sopenharmony_ci start_params->network_cos_mode = STATIC_COS; 96162306a36Sopenharmony_ci else /* CHIP_IS_E1X */ 96262306a36Sopenharmony_ci start_params->network_cos_mode = FW_WRR; 96362306a36Sopenharmony_ci if (bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN]) { 96462306a36Sopenharmony_ci port = bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN]; 96562306a36Sopenharmony_ci start_params->vxlan_dst_port = port; 96662306a36Sopenharmony_ci } 96762306a36Sopenharmony_ci if (bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE]) { 96862306a36Sopenharmony_ci port = bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE]; 96962306a36Sopenharmony_ci start_params->geneve_dst_port = port; 97062306a36Sopenharmony_ci } 97162306a36Sopenharmony_ci 97262306a36Sopenharmony_ci start_params->inner_rss = 1; 97362306a36Sopenharmony_ci 97462306a36Sopenharmony_ci if (IS_MF_UFP(bp) && BNX2X_IS_MF_SD_PROTOCOL_FCOE(bp)) { 97562306a36Sopenharmony_ci start_params->class_fail_ethtype = ETH_P_FIP; 97662306a36Sopenharmony_ci start_params->class_fail = 1; 97762306a36Sopenharmony_ci start_params->no_added_tags = 1; 97862306a36Sopenharmony_ci } 97962306a36Sopenharmony_ci 98062306a36Sopenharmony_ci return bnx2x_func_state_change(bp, &func_params); 98162306a36Sopenharmony_ci} 98262306a36Sopenharmony_ci 98362306a36Sopenharmony_ci/** 98462306a36Sopenharmony_ci * bnx2x_set_fw_mac_addr - fill in a MAC address in FW format 98562306a36Sopenharmony_ci * 98662306a36Sopenharmony_ci * @fw_hi: pointer to upper part 98762306a36Sopenharmony_ci * @fw_mid: pointer to middle part 98862306a36Sopenharmony_ci * @fw_lo: pointer to lower part 98962306a36Sopenharmony_ci * @mac: pointer to MAC address 99062306a36Sopenharmony_ci */ 99162306a36Sopenharmony_cistatic inline void bnx2x_set_fw_mac_addr(__le16 *fw_hi, __le16 *fw_mid, 99262306a36Sopenharmony_ci __le16 *fw_lo, u8 *mac) 99362306a36Sopenharmony_ci{ 99462306a36Sopenharmony_ci ((u8 *)fw_hi)[0] = mac[1]; 99562306a36Sopenharmony_ci ((u8 *)fw_hi)[1] = mac[0]; 99662306a36Sopenharmony_ci ((u8 *)fw_mid)[0] = mac[3]; 99762306a36Sopenharmony_ci ((u8 *)fw_mid)[1] = mac[2]; 99862306a36Sopenharmony_ci ((u8 *)fw_lo)[0] = mac[5]; 99962306a36Sopenharmony_ci ((u8 *)fw_lo)[1] = mac[4]; 100062306a36Sopenharmony_ci} 100162306a36Sopenharmony_ci 100262306a36Sopenharmony_cistatic inline void bnx2x_free_rx_mem_pool(struct bnx2x *bp, 100362306a36Sopenharmony_ci struct bnx2x_alloc_pool *pool) 100462306a36Sopenharmony_ci{ 100562306a36Sopenharmony_ci put_page(pool->page); 100662306a36Sopenharmony_ci 100762306a36Sopenharmony_ci pool->page = NULL; 100862306a36Sopenharmony_ci} 100962306a36Sopenharmony_ci 101062306a36Sopenharmony_cistatic inline void bnx2x_free_rx_sge_range(struct bnx2x *bp, 101162306a36Sopenharmony_ci struct bnx2x_fastpath *fp, int last) 101262306a36Sopenharmony_ci{ 101362306a36Sopenharmony_ci int i; 101462306a36Sopenharmony_ci 101562306a36Sopenharmony_ci if (!fp->page_pool.page) 101662306a36Sopenharmony_ci return; 101762306a36Sopenharmony_ci 101862306a36Sopenharmony_ci if (fp->mode == TPA_MODE_DISABLED) 101962306a36Sopenharmony_ci return; 102062306a36Sopenharmony_ci 102162306a36Sopenharmony_ci for (i = 0; i < last; i++) 102262306a36Sopenharmony_ci bnx2x_free_rx_sge(bp, fp, i); 102362306a36Sopenharmony_ci 102462306a36Sopenharmony_ci bnx2x_free_rx_mem_pool(bp, &fp->page_pool); 102562306a36Sopenharmony_ci} 102662306a36Sopenharmony_ci 102762306a36Sopenharmony_cistatic inline void bnx2x_set_next_page_rx_bd(struct bnx2x_fastpath *fp) 102862306a36Sopenharmony_ci{ 102962306a36Sopenharmony_ci int i; 103062306a36Sopenharmony_ci 103162306a36Sopenharmony_ci for (i = 1; i <= NUM_RX_RINGS; i++) { 103262306a36Sopenharmony_ci struct eth_rx_bd *rx_bd; 103362306a36Sopenharmony_ci 103462306a36Sopenharmony_ci rx_bd = &fp->rx_desc_ring[RX_DESC_CNT * i - 2]; 103562306a36Sopenharmony_ci rx_bd->addr_hi = 103662306a36Sopenharmony_ci cpu_to_le32(U64_HI(fp->rx_desc_mapping + 103762306a36Sopenharmony_ci BCM_PAGE_SIZE*(i % NUM_RX_RINGS))); 103862306a36Sopenharmony_ci rx_bd->addr_lo = 103962306a36Sopenharmony_ci cpu_to_le32(U64_LO(fp->rx_desc_mapping + 104062306a36Sopenharmony_ci BCM_PAGE_SIZE*(i % NUM_RX_RINGS))); 104162306a36Sopenharmony_ci } 104262306a36Sopenharmony_ci} 104362306a36Sopenharmony_ci 104462306a36Sopenharmony_ci/* Statistics ID are global per chip/path, while Client IDs for E1x are per 104562306a36Sopenharmony_ci * port. 104662306a36Sopenharmony_ci */ 104762306a36Sopenharmony_cistatic inline u8 bnx2x_stats_id(struct bnx2x_fastpath *fp) 104862306a36Sopenharmony_ci{ 104962306a36Sopenharmony_ci struct bnx2x *bp = fp->bp; 105062306a36Sopenharmony_ci if (!CHIP_IS_E1x(bp)) { 105162306a36Sopenharmony_ci /* there are special statistics counters for FCoE 136..140 */ 105262306a36Sopenharmony_ci if (IS_FCOE_FP(fp)) 105362306a36Sopenharmony_ci return bp->cnic_base_cl_id + (bp->pf_num >> 1); 105462306a36Sopenharmony_ci return fp->cl_id; 105562306a36Sopenharmony_ci } 105662306a36Sopenharmony_ci return fp->cl_id + BP_PORT(bp) * FP_SB_MAX_E1x; 105762306a36Sopenharmony_ci} 105862306a36Sopenharmony_ci 105962306a36Sopenharmony_cistatic inline void bnx2x_init_vlan_mac_fp_objs(struct bnx2x_fastpath *fp, 106062306a36Sopenharmony_ci bnx2x_obj_type obj_type) 106162306a36Sopenharmony_ci{ 106262306a36Sopenharmony_ci struct bnx2x *bp = fp->bp; 106362306a36Sopenharmony_ci 106462306a36Sopenharmony_ci /* Configure classification DBs */ 106562306a36Sopenharmony_ci bnx2x_init_mac_obj(bp, &bnx2x_sp_obj(bp, fp).mac_obj, fp->cl_id, 106662306a36Sopenharmony_ci fp->cid, BP_FUNC(bp), bnx2x_sp(bp, mac_rdata), 106762306a36Sopenharmony_ci bnx2x_sp_mapping(bp, mac_rdata), 106862306a36Sopenharmony_ci BNX2X_FILTER_MAC_PENDING, 106962306a36Sopenharmony_ci &bp->sp_state, obj_type, 107062306a36Sopenharmony_ci &bp->macs_pool); 107162306a36Sopenharmony_ci 107262306a36Sopenharmony_ci if (!CHIP_IS_E1x(bp)) 107362306a36Sopenharmony_ci bnx2x_init_vlan_obj(bp, &bnx2x_sp_obj(bp, fp).vlan_obj, 107462306a36Sopenharmony_ci fp->cl_id, fp->cid, BP_FUNC(bp), 107562306a36Sopenharmony_ci bnx2x_sp(bp, vlan_rdata), 107662306a36Sopenharmony_ci bnx2x_sp_mapping(bp, vlan_rdata), 107762306a36Sopenharmony_ci BNX2X_FILTER_VLAN_PENDING, 107862306a36Sopenharmony_ci &bp->sp_state, obj_type, 107962306a36Sopenharmony_ci &bp->vlans_pool); 108062306a36Sopenharmony_ci} 108162306a36Sopenharmony_ci 108262306a36Sopenharmony_ci/** 108362306a36Sopenharmony_ci * bnx2x_get_path_func_num - get number of active functions 108462306a36Sopenharmony_ci * 108562306a36Sopenharmony_ci * @bp: driver handle 108662306a36Sopenharmony_ci * 108762306a36Sopenharmony_ci * Calculates the number of active (not hidden) functions on the 108862306a36Sopenharmony_ci * current path. 108962306a36Sopenharmony_ci */ 109062306a36Sopenharmony_cistatic inline u8 bnx2x_get_path_func_num(struct bnx2x *bp) 109162306a36Sopenharmony_ci{ 109262306a36Sopenharmony_ci u8 func_num = 0, i; 109362306a36Sopenharmony_ci 109462306a36Sopenharmony_ci /* 57710 has only one function per-port */ 109562306a36Sopenharmony_ci if (CHIP_IS_E1(bp)) 109662306a36Sopenharmony_ci return 1; 109762306a36Sopenharmony_ci 109862306a36Sopenharmony_ci /* Calculate a number of functions enabled on the current 109962306a36Sopenharmony_ci * PATH/PORT. 110062306a36Sopenharmony_ci */ 110162306a36Sopenharmony_ci if (CHIP_REV_IS_SLOW(bp)) { 110262306a36Sopenharmony_ci if (IS_MF(bp)) 110362306a36Sopenharmony_ci func_num = 4; 110462306a36Sopenharmony_ci else 110562306a36Sopenharmony_ci func_num = 2; 110662306a36Sopenharmony_ci } else { 110762306a36Sopenharmony_ci for (i = 0; i < E1H_FUNC_MAX / 2; i++) { 110862306a36Sopenharmony_ci u32 func_config = 110962306a36Sopenharmony_ci MF_CFG_RD(bp, 111062306a36Sopenharmony_ci func_mf_config[BP_PATH(bp) + 2 * i]. 111162306a36Sopenharmony_ci config); 111262306a36Sopenharmony_ci func_num += 111362306a36Sopenharmony_ci ((func_config & FUNC_MF_CFG_FUNC_HIDE) ? 0 : 1); 111462306a36Sopenharmony_ci } 111562306a36Sopenharmony_ci } 111662306a36Sopenharmony_ci 111762306a36Sopenharmony_ci WARN_ON(!func_num); 111862306a36Sopenharmony_ci 111962306a36Sopenharmony_ci return func_num; 112062306a36Sopenharmony_ci} 112162306a36Sopenharmony_ci 112262306a36Sopenharmony_cistatic inline void bnx2x_init_bp_objs(struct bnx2x *bp) 112362306a36Sopenharmony_ci{ 112462306a36Sopenharmony_ci /* RX_MODE controlling object */ 112562306a36Sopenharmony_ci bnx2x_init_rx_mode_obj(bp, &bp->rx_mode_obj); 112662306a36Sopenharmony_ci 112762306a36Sopenharmony_ci /* multicast configuration controlling object */ 112862306a36Sopenharmony_ci bnx2x_init_mcast_obj(bp, &bp->mcast_obj, bp->fp->cl_id, bp->fp->cid, 112962306a36Sopenharmony_ci BP_FUNC(bp), BP_FUNC(bp), 113062306a36Sopenharmony_ci bnx2x_sp(bp, mcast_rdata), 113162306a36Sopenharmony_ci bnx2x_sp_mapping(bp, mcast_rdata), 113262306a36Sopenharmony_ci BNX2X_FILTER_MCAST_PENDING, &bp->sp_state, 113362306a36Sopenharmony_ci BNX2X_OBJ_TYPE_RX); 113462306a36Sopenharmony_ci 113562306a36Sopenharmony_ci /* Setup CAM credit pools */ 113662306a36Sopenharmony_ci bnx2x_init_mac_credit_pool(bp, &bp->macs_pool, BP_FUNC(bp), 113762306a36Sopenharmony_ci bnx2x_get_path_func_num(bp)); 113862306a36Sopenharmony_ci 113962306a36Sopenharmony_ci bnx2x_init_vlan_credit_pool(bp, &bp->vlans_pool, BP_FUNC(bp), 114062306a36Sopenharmony_ci bnx2x_get_path_func_num(bp)); 114162306a36Sopenharmony_ci 114262306a36Sopenharmony_ci /* RSS configuration object */ 114362306a36Sopenharmony_ci bnx2x_init_rss_config_obj(bp, &bp->rss_conf_obj, bp->fp->cl_id, 114462306a36Sopenharmony_ci bp->fp->cid, BP_FUNC(bp), BP_FUNC(bp), 114562306a36Sopenharmony_ci bnx2x_sp(bp, rss_rdata), 114662306a36Sopenharmony_ci bnx2x_sp_mapping(bp, rss_rdata), 114762306a36Sopenharmony_ci BNX2X_FILTER_RSS_CONF_PENDING, &bp->sp_state, 114862306a36Sopenharmony_ci BNX2X_OBJ_TYPE_RX); 114962306a36Sopenharmony_ci 115062306a36Sopenharmony_ci bp->vlan_credit = PF_VLAN_CREDIT_E2(bp, bnx2x_get_path_func_num(bp)); 115162306a36Sopenharmony_ci} 115262306a36Sopenharmony_ci 115362306a36Sopenharmony_cistatic inline u8 bnx2x_fp_qzone_id(struct bnx2x_fastpath *fp) 115462306a36Sopenharmony_ci{ 115562306a36Sopenharmony_ci if (CHIP_IS_E1x(fp->bp)) 115662306a36Sopenharmony_ci return fp->cl_id + BP_PORT(fp->bp) * ETH_MAX_RX_CLIENTS_E1H; 115762306a36Sopenharmony_ci else 115862306a36Sopenharmony_ci return fp->cl_id; 115962306a36Sopenharmony_ci} 116062306a36Sopenharmony_ci 116162306a36Sopenharmony_cistatic inline void bnx2x_init_txdata(struct bnx2x *bp, 116262306a36Sopenharmony_ci struct bnx2x_fp_txdata *txdata, u32 cid, 116362306a36Sopenharmony_ci int txq_index, __le16 *tx_cons_sb, 116462306a36Sopenharmony_ci struct bnx2x_fastpath *fp) 116562306a36Sopenharmony_ci{ 116662306a36Sopenharmony_ci txdata->cid = cid; 116762306a36Sopenharmony_ci txdata->txq_index = txq_index; 116862306a36Sopenharmony_ci txdata->tx_cons_sb = tx_cons_sb; 116962306a36Sopenharmony_ci txdata->parent_fp = fp; 117062306a36Sopenharmony_ci txdata->tx_ring_size = IS_FCOE_FP(fp) ? MAX_TX_AVAIL : bp->tx_ring_size; 117162306a36Sopenharmony_ci 117262306a36Sopenharmony_ci DP(NETIF_MSG_IFUP, "created tx data cid %d, txq %d\n", 117362306a36Sopenharmony_ci txdata->cid, txdata->txq_index); 117462306a36Sopenharmony_ci} 117562306a36Sopenharmony_ci 117662306a36Sopenharmony_cistatic inline u8 bnx2x_cnic_eth_cl_id(struct bnx2x *bp, u8 cl_idx) 117762306a36Sopenharmony_ci{ 117862306a36Sopenharmony_ci return bp->cnic_base_cl_id + cl_idx + 117962306a36Sopenharmony_ci (bp->pf_num >> 1) * BNX2X_MAX_CNIC_ETH_CL_ID_IDX; 118062306a36Sopenharmony_ci} 118162306a36Sopenharmony_ci 118262306a36Sopenharmony_cistatic inline u8 bnx2x_cnic_fw_sb_id(struct bnx2x *bp) 118362306a36Sopenharmony_ci{ 118462306a36Sopenharmony_ci /* the 'first' id is allocated for the cnic */ 118562306a36Sopenharmony_ci return bp->base_fw_ndsb; 118662306a36Sopenharmony_ci} 118762306a36Sopenharmony_ci 118862306a36Sopenharmony_cistatic inline u8 bnx2x_cnic_igu_sb_id(struct bnx2x *bp) 118962306a36Sopenharmony_ci{ 119062306a36Sopenharmony_ci return bp->igu_base_sb; 119162306a36Sopenharmony_ci} 119262306a36Sopenharmony_ci 119362306a36Sopenharmony_cistatic inline int bnx2x_clean_tx_queue(struct bnx2x *bp, 119462306a36Sopenharmony_ci struct bnx2x_fp_txdata *txdata) 119562306a36Sopenharmony_ci{ 119662306a36Sopenharmony_ci int cnt = 1000; 119762306a36Sopenharmony_ci 119862306a36Sopenharmony_ci while (bnx2x_has_tx_work_unload(txdata)) { 119962306a36Sopenharmony_ci if (!cnt) { 120062306a36Sopenharmony_ci BNX2X_ERR("timeout waiting for queue[%d]: txdata->tx_pkt_prod(%d) != txdata->tx_pkt_cons(%d)\n", 120162306a36Sopenharmony_ci txdata->txq_index, txdata->tx_pkt_prod, 120262306a36Sopenharmony_ci txdata->tx_pkt_cons); 120362306a36Sopenharmony_ci#ifdef BNX2X_STOP_ON_ERROR 120462306a36Sopenharmony_ci bnx2x_panic(); 120562306a36Sopenharmony_ci return -EBUSY; 120662306a36Sopenharmony_ci#else 120762306a36Sopenharmony_ci break; 120862306a36Sopenharmony_ci#endif 120962306a36Sopenharmony_ci } 121062306a36Sopenharmony_ci cnt--; 121162306a36Sopenharmony_ci usleep_range(1000, 2000); 121262306a36Sopenharmony_ci } 121362306a36Sopenharmony_ci 121462306a36Sopenharmony_ci return 0; 121562306a36Sopenharmony_ci} 121662306a36Sopenharmony_ci 121762306a36Sopenharmony_ciint bnx2x_get_link_cfg_idx(struct bnx2x *bp); 121862306a36Sopenharmony_ci 121962306a36Sopenharmony_cistatic inline void __storm_memset_struct(struct bnx2x *bp, 122062306a36Sopenharmony_ci u32 addr, size_t size, u32 *data) 122162306a36Sopenharmony_ci{ 122262306a36Sopenharmony_ci int i; 122362306a36Sopenharmony_ci for (i = 0; i < size/4; i++) 122462306a36Sopenharmony_ci REG_WR(bp, addr + (i * 4), data[i]); 122562306a36Sopenharmony_ci} 122662306a36Sopenharmony_ci 122762306a36Sopenharmony_ci/** 122862306a36Sopenharmony_ci * bnx2x_wait_sp_comp - wait for the outstanding SP commands. 122962306a36Sopenharmony_ci * 123062306a36Sopenharmony_ci * @bp: driver handle 123162306a36Sopenharmony_ci * @mask: bits that need to be cleared 123262306a36Sopenharmony_ci */ 123362306a36Sopenharmony_cistatic inline bool bnx2x_wait_sp_comp(struct bnx2x *bp, unsigned long mask) 123462306a36Sopenharmony_ci{ 123562306a36Sopenharmony_ci int tout = 5000; /* Wait for 5 secs tops */ 123662306a36Sopenharmony_ci 123762306a36Sopenharmony_ci while (tout--) { 123862306a36Sopenharmony_ci smp_mb(); 123962306a36Sopenharmony_ci netif_addr_lock_bh(bp->dev); 124062306a36Sopenharmony_ci if (!(bp->sp_state & mask)) { 124162306a36Sopenharmony_ci netif_addr_unlock_bh(bp->dev); 124262306a36Sopenharmony_ci return true; 124362306a36Sopenharmony_ci } 124462306a36Sopenharmony_ci netif_addr_unlock_bh(bp->dev); 124562306a36Sopenharmony_ci 124662306a36Sopenharmony_ci usleep_range(1000, 2000); 124762306a36Sopenharmony_ci } 124862306a36Sopenharmony_ci 124962306a36Sopenharmony_ci smp_mb(); 125062306a36Sopenharmony_ci 125162306a36Sopenharmony_ci netif_addr_lock_bh(bp->dev); 125262306a36Sopenharmony_ci if (bp->sp_state & mask) { 125362306a36Sopenharmony_ci BNX2X_ERR("Filtering completion timed out. sp_state 0x%lx, mask 0x%lx\n", 125462306a36Sopenharmony_ci bp->sp_state, mask); 125562306a36Sopenharmony_ci netif_addr_unlock_bh(bp->dev); 125662306a36Sopenharmony_ci return false; 125762306a36Sopenharmony_ci } 125862306a36Sopenharmony_ci netif_addr_unlock_bh(bp->dev); 125962306a36Sopenharmony_ci 126062306a36Sopenharmony_ci return true; 126162306a36Sopenharmony_ci} 126262306a36Sopenharmony_ci 126362306a36Sopenharmony_ci/** 126462306a36Sopenharmony_ci * bnx2x_set_ctx_validation - set CDU context validation values 126562306a36Sopenharmony_ci * 126662306a36Sopenharmony_ci * @bp: driver handle 126762306a36Sopenharmony_ci * @cxt: context of the connection on the host memory 126862306a36Sopenharmony_ci * @cid: SW CID of the connection to be configured 126962306a36Sopenharmony_ci */ 127062306a36Sopenharmony_civoid bnx2x_set_ctx_validation(struct bnx2x *bp, struct eth_context *cxt, 127162306a36Sopenharmony_ci u32 cid); 127262306a36Sopenharmony_ci 127362306a36Sopenharmony_civoid bnx2x_update_coalesce_sb_index(struct bnx2x *bp, u8 fw_sb_id, 127462306a36Sopenharmony_ci u8 sb_index, u8 disable, u16 usec); 127562306a36Sopenharmony_civoid bnx2x_acquire_phy_lock(struct bnx2x *bp); 127662306a36Sopenharmony_civoid bnx2x_release_phy_lock(struct bnx2x *bp); 127762306a36Sopenharmony_ci 127862306a36Sopenharmony_ci/** 127962306a36Sopenharmony_ci * bnx2x_extract_max_cfg - extract MAX BW part from MF configuration. 128062306a36Sopenharmony_ci * 128162306a36Sopenharmony_ci * @bp: driver handle 128262306a36Sopenharmony_ci * @mf_cfg: MF configuration 128362306a36Sopenharmony_ci * 128462306a36Sopenharmony_ci */ 128562306a36Sopenharmony_cistatic inline u16 bnx2x_extract_max_cfg(struct bnx2x *bp, u32 mf_cfg) 128662306a36Sopenharmony_ci{ 128762306a36Sopenharmony_ci u16 max_cfg = (mf_cfg & FUNC_MF_CFG_MAX_BW_MASK) >> 128862306a36Sopenharmony_ci FUNC_MF_CFG_MAX_BW_SHIFT; 128962306a36Sopenharmony_ci if (!max_cfg) { 129062306a36Sopenharmony_ci DP(NETIF_MSG_IFUP | BNX2X_MSG_ETHTOOL, 129162306a36Sopenharmony_ci "Max BW configured to 0 - using 100 instead\n"); 129262306a36Sopenharmony_ci max_cfg = 100; 129362306a36Sopenharmony_ci } 129462306a36Sopenharmony_ci return max_cfg; 129562306a36Sopenharmony_ci} 129662306a36Sopenharmony_ci 129762306a36Sopenharmony_ci/* checks if HW supports GRO for given MTU */ 129862306a36Sopenharmony_cistatic inline bool bnx2x_mtu_allows_gro(int mtu) 129962306a36Sopenharmony_ci{ 130062306a36Sopenharmony_ci /* gro frags per page */ 130162306a36Sopenharmony_ci int fpp = SGE_PAGE_SIZE / (mtu - ETH_MAX_TPA_HEADER_SIZE); 130262306a36Sopenharmony_ci 130362306a36Sopenharmony_ci /* 130462306a36Sopenharmony_ci * 1. Number of frags should not grow above MAX_SKB_FRAGS 130562306a36Sopenharmony_ci * 2. Frag must fit the page 130662306a36Sopenharmony_ci */ 130762306a36Sopenharmony_ci return mtu <= SGE_PAGE_SIZE && (U_ETH_SGL_SIZE * fpp) <= MAX_SKB_FRAGS; 130862306a36Sopenharmony_ci} 130962306a36Sopenharmony_ci 131062306a36Sopenharmony_ci/** 131162306a36Sopenharmony_ci * bnx2x_get_iscsi_info - update iSCSI params according to licensing info. 131262306a36Sopenharmony_ci * 131362306a36Sopenharmony_ci * @bp: driver handle 131462306a36Sopenharmony_ci * 131562306a36Sopenharmony_ci */ 131662306a36Sopenharmony_civoid bnx2x_get_iscsi_info(struct bnx2x *bp); 131762306a36Sopenharmony_ci 131862306a36Sopenharmony_ci/** 131962306a36Sopenharmony_ci * bnx2x_link_sync_notify - send notification to other functions. 132062306a36Sopenharmony_ci * 132162306a36Sopenharmony_ci * @bp: driver handle 132262306a36Sopenharmony_ci * 132362306a36Sopenharmony_ci */ 132462306a36Sopenharmony_cistatic inline void bnx2x_link_sync_notify(struct bnx2x *bp) 132562306a36Sopenharmony_ci{ 132662306a36Sopenharmony_ci int func; 132762306a36Sopenharmony_ci int vn; 132862306a36Sopenharmony_ci 132962306a36Sopenharmony_ci /* Set the attention towards other drivers on the same port */ 133062306a36Sopenharmony_ci for (vn = VN_0; vn < BP_MAX_VN_NUM(bp); vn++) { 133162306a36Sopenharmony_ci if (vn == BP_VN(bp)) 133262306a36Sopenharmony_ci continue; 133362306a36Sopenharmony_ci 133462306a36Sopenharmony_ci func = func_by_vn(bp, vn); 133562306a36Sopenharmony_ci REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 + 133662306a36Sopenharmony_ci (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1); 133762306a36Sopenharmony_ci } 133862306a36Sopenharmony_ci} 133962306a36Sopenharmony_ci 134062306a36Sopenharmony_ci/** 134162306a36Sopenharmony_ci * bnx2x_update_drv_flags - update flags in shmem 134262306a36Sopenharmony_ci * 134362306a36Sopenharmony_ci * @bp: driver handle 134462306a36Sopenharmony_ci * @flags: flags to update 134562306a36Sopenharmony_ci * @set: set or clear 134662306a36Sopenharmony_ci * 134762306a36Sopenharmony_ci */ 134862306a36Sopenharmony_cistatic inline void bnx2x_update_drv_flags(struct bnx2x *bp, u32 flags, u32 set) 134962306a36Sopenharmony_ci{ 135062306a36Sopenharmony_ci if (SHMEM2_HAS(bp, drv_flags)) { 135162306a36Sopenharmony_ci u32 drv_flags; 135262306a36Sopenharmony_ci bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_DRV_FLAGS); 135362306a36Sopenharmony_ci drv_flags = SHMEM2_RD(bp, drv_flags); 135462306a36Sopenharmony_ci 135562306a36Sopenharmony_ci if (set) 135662306a36Sopenharmony_ci SET_FLAGS(drv_flags, flags); 135762306a36Sopenharmony_ci else 135862306a36Sopenharmony_ci RESET_FLAGS(drv_flags, flags); 135962306a36Sopenharmony_ci 136062306a36Sopenharmony_ci SHMEM2_WR(bp, drv_flags, drv_flags); 136162306a36Sopenharmony_ci DP(NETIF_MSG_IFUP, "drv_flags 0x%08x\n", drv_flags); 136262306a36Sopenharmony_ci bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_DRV_FLAGS); 136362306a36Sopenharmony_ci } 136462306a36Sopenharmony_ci} 136562306a36Sopenharmony_ci 136662306a36Sopenharmony_ci 136762306a36Sopenharmony_ci 136862306a36Sopenharmony_ci/** 136962306a36Sopenharmony_ci * bnx2x_fill_fw_str - Fill buffer with FW version string 137062306a36Sopenharmony_ci * 137162306a36Sopenharmony_ci * @bp: driver handle 137262306a36Sopenharmony_ci * @buf: character buffer to fill with the fw name 137362306a36Sopenharmony_ci * @buf_len: length of the above buffer 137462306a36Sopenharmony_ci * 137562306a36Sopenharmony_ci */ 137662306a36Sopenharmony_civoid bnx2x_fill_fw_str(struct bnx2x *bp, char *buf, size_t buf_len); 137762306a36Sopenharmony_ci 137862306a36Sopenharmony_ciint bnx2x_drain_tx_queues(struct bnx2x *bp); 137962306a36Sopenharmony_civoid bnx2x_squeeze_objects(struct bnx2x *bp); 138062306a36Sopenharmony_ci 138162306a36Sopenharmony_civoid bnx2x_schedule_sp_rtnl(struct bnx2x*, enum sp_rtnl_flag, 138262306a36Sopenharmony_ci u32 verbose); 138362306a36Sopenharmony_ci 138462306a36Sopenharmony_ci/** 138562306a36Sopenharmony_ci * bnx2x_set_os_driver_state - write driver state for management FW usage 138662306a36Sopenharmony_ci * 138762306a36Sopenharmony_ci * @bp: driver handle 138862306a36Sopenharmony_ci * @state: OS_DRIVER_STATE_* value reflecting current driver state 138962306a36Sopenharmony_ci */ 139062306a36Sopenharmony_civoid bnx2x_set_os_driver_state(struct bnx2x *bp, u32 state); 139162306a36Sopenharmony_ci 139262306a36Sopenharmony_ci/** 139362306a36Sopenharmony_ci * bnx2x_nvram_read - reads data from nvram [might sleep] 139462306a36Sopenharmony_ci * 139562306a36Sopenharmony_ci * @bp: driver handle 139662306a36Sopenharmony_ci * @offset: byte offset in nvram 139762306a36Sopenharmony_ci * @ret_buf: pointer to buffer where data is to be stored 139862306a36Sopenharmony_ci * @buf_size: Length of 'ret_buf' in bytes 139962306a36Sopenharmony_ci */ 140062306a36Sopenharmony_ciint bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf, 140162306a36Sopenharmony_ci int buf_size); 140262306a36Sopenharmony_ci 140362306a36Sopenharmony_ci#endif /* BNX2X_CMN_H */ 1404