be2net: Move the Emulex driver
Moves the Emulex driver into drivers/net/ethernet/emulex/ and make the necessary Kconfig and Makefile changes. CC: Sathya Perla <sathya.perla@emulex.com> CC: Subbu Seetharaman <subbu.seetharaman@emulex.com> CC: Ajit Khaparde <ajit.khaparde@emulex.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
这个提交包含在:
@@ -0,0 +1,22 @@
|
||||
#
|
||||
# Emulex driver configuration
|
||||
#
|
||||
|
||||
config NET_VENDOR_EMULEX
|
||||
bool "Emulex devices"
|
||||
depends on PCI && INET
|
||||
---help---
|
||||
If you have a network (Ethernet) card belonging to this class, say Y
|
||||
and read the Ethernet-HOWTO, available from
|
||||
<http://www.tldp.org/docs.html#howto>.
|
||||
|
||||
Note that the answer to this question doesn't directly affect the
|
||||
kernel: saying N will just cause the configurator to skip all
|
||||
the questions about Emulex cards. If you say Y, you will be asked for
|
||||
your specific card in the following questions.
|
||||
|
||||
if NET_VENDOR_EMULEX
|
||||
|
||||
source "drivers/net/ethernet/emulex/benet/Kconfig"
|
||||
|
||||
endif # NET_VENDOR_EMULEX
|
@@ -0,0 +1,5 @@
|
||||
#
|
||||
# Makefile for the Emulex device drivers.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_BE2NET) += benet/
|
@@ -0,0 +1,6 @@
|
||||
config BE2NET
|
||||
tristate "ServerEngines' 10Gbps NIC - BladeEngine"
|
||||
depends on PCI && INET
|
||||
---help---
|
||||
This driver implements the NIC functionality for ServerEngines'
|
||||
10Gbps network adapter - BladeEngine.
|
@@ -0,0 +1,7 @@
|
||||
#
|
||||
# Makefile to build the network driver for ServerEngine's BladeEngine.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_BE2NET) += be2net.o
|
||||
|
||||
be2net-y := be_main.o be_cmds.o be_ethtool.o
|
@@ -0,0 +1,529 @@
|
||||
/*
|
||||
* Copyright (C) 2005 - 2011 Emulex
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation. The full GNU General
|
||||
* Public License is included in this distribution in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* linux-drivers@emulex.com
|
||||
*
|
||||
* Emulex
|
||||
* 3333 Susan Street
|
||||
* Costa Mesa, CA 92626
|
||||
*/
|
||||
|
||||
#ifndef BE_H
|
||||
#define BE_H
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/delay.h>
|
||||
#include <net/tcp.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/ipv6.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/u64_stats_sync.h>
|
||||
|
||||
#include "be_hw.h"
|
||||
|
||||
#define DRV_VER "4.0.100u"
|
||||
#define DRV_NAME "be2net"
|
||||
#define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC"
|
||||
#define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC"
|
||||
#define OC_NAME "Emulex OneConnect 10Gbps NIC"
|
||||
#define OC_NAME_BE OC_NAME "(be3)"
|
||||
#define OC_NAME_LANCER OC_NAME "(Lancer)"
|
||||
#define DRV_DESC "ServerEngines BladeEngine 10Gbps NIC Driver"
|
||||
|
||||
#define BE_VENDOR_ID 0x19a2
|
||||
#define EMULEX_VENDOR_ID 0x10df
|
||||
#define BE_DEVICE_ID1 0x211
|
||||
#define BE_DEVICE_ID2 0x221
|
||||
#define OC_DEVICE_ID1 0x700 /* Device Id for BE2 cards */
|
||||
#define OC_DEVICE_ID2 0x710 /* Device Id for BE3 cards */
|
||||
#define OC_DEVICE_ID3 0xe220 /* Device id for Lancer cards */
|
||||
#define OC_DEVICE_ID4 0xe228 /* Device id for VF in Lancer */
|
||||
|
||||
static inline char *nic_name(struct pci_dev *pdev)
|
||||
{
|
||||
switch (pdev->device) {
|
||||
case OC_DEVICE_ID1:
|
||||
return OC_NAME;
|
||||
case OC_DEVICE_ID2:
|
||||
return OC_NAME_BE;
|
||||
case OC_DEVICE_ID3:
|
||||
case OC_DEVICE_ID4:
|
||||
return OC_NAME_LANCER;
|
||||
case BE_DEVICE_ID2:
|
||||
return BE3_NAME;
|
||||
default:
|
||||
return BE_NAME;
|
||||
}
|
||||
}
|
||||
|
||||
/* Number of bytes of an RX frame that are copied to skb->data */
|
||||
#define BE_HDR_LEN ((u16) 64)
|
||||
#define BE_MAX_JUMBO_FRAME_SIZE 9018
|
||||
#define BE_MIN_MTU 256
|
||||
|
||||
#define BE_NUM_VLANS_SUPPORTED 64
|
||||
#define BE_MAX_EQD 96
|
||||
#define BE_MAX_TX_FRAG_COUNT 30
|
||||
|
||||
#define EVNT_Q_LEN 1024
|
||||
#define TX_Q_LEN 2048
|
||||
#define TX_CQ_LEN 1024
|
||||
#define RX_Q_LEN 1024 /* Does not support any other value */
|
||||
#define RX_CQ_LEN 1024
|
||||
#define MCC_Q_LEN 128 /* total size not to exceed 8 pages */
|
||||
#define MCC_CQ_LEN 256
|
||||
|
||||
#define MAX_RSS_QS 4 /* BE limit is 4 queues/port */
|
||||
#define MAX_RX_QS (MAX_RSS_QS + 1) /* RSS qs + 1 def Rx */
|
||||
#define MAX_TX_QS 8
|
||||
#define BE_MAX_MSIX_VECTORS (MAX_RX_QS + 1)/* RX + TX */
|
||||
#define BE_NAPI_WEIGHT 64
|
||||
#define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */
|
||||
#define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST)
|
||||
|
||||
#define FW_VER_LEN 32
|
||||
|
||||
struct be_dma_mem {
|
||||
void *va;
|
||||
dma_addr_t dma;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct be_queue_info {
|
||||
struct be_dma_mem dma_mem;
|
||||
u16 len;
|
||||
u16 entry_size; /* Size of an element in the queue */
|
||||
u16 id;
|
||||
u16 tail, head;
|
||||
bool created;
|
||||
atomic_t used; /* Number of valid elements in the queue */
|
||||
};
|
||||
|
||||
static inline u32 MODULO(u16 val, u16 limit)
|
||||
{
|
||||
BUG_ON(limit & (limit - 1));
|
||||
return val & (limit - 1);
|
||||
}
|
||||
|
||||
static inline void index_adv(u16 *index, u16 val, u16 limit)
|
||||
{
|
||||
*index = MODULO((*index + val), limit);
|
||||
}
|
||||
|
||||
static inline void index_inc(u16 *index, u16 limit)
|
||||
{
|
||||
*index = MODULO((*index + 1), limit);
|
||||
}
|
||||
|
||||
static inline void *queue_head_node(struct be_queue_info *q)
|
||||
{
|
||||
return q->dma_mem.va + q->head * q->entry_size;
|
||||
}
|
||||
|
||||
static inline void *queue_tail_node(struct be_queue_info *q)
|
||||
{
|
||||
return q->dma_mem.va + q->tail * q->entry_size;
|
||||
}
|
||||
|
||||
static inline void queue_head_inc(struct be_queue_info *q)
|
||||
{
|
||||
index_inc(&q->head, q->len);
|
||||
}
|
||||
|
||||
static inline void queue_tail_inc(struct be_queue_info *q)
|
||||
{
|
||||
index_inc(&q->tail, q->len);
|
||||
}
|
||||
|
||||
struct be_eq_obj {
|
||||
struct be_queue_info q;
|
||||
char desc[32];
|
||||
|
||||
/* Adaptive interrupt coalescing (AIC) info */
|
||||
bool enable_aic;
|
||||
u16 min_eqd; /* in usecs */
|
||||
u16 max_eqd; /* in usecs */
|
||||
u16 cur_eqd; /* in usecs */
|
||||
u8 eq_idx;
|
||||
|
||||
struct napi_struct napi;
|
||||
};
|
||||
|
||||
struct be_mcc_obj {
|
||||
struct be_queue_info q;
|
||||
struct be_queue_info cq;
|
||||
bool rearm_cq;
|
||||
};
|
||||
|
||||
struct be_tx_stats {
|
||||
u64 tx_bytes;
|
||||
u64 tx_pkts;
|
||||
u64 tx_reqs;
|
||||
u64 tx_wrbs;
|
||||
u64 tx_compl;
|
||||
ulong tx_jiffies;
|
||||
u32 tx_stops;
|
||||
struct u64_stats_sync sync;
|
||||
struct u64_stats_sync sync_compl;
|
||||
};
|
||||
|
||||
struct be_tx_obj {
|
||||
struct be_queue_info q;
|
||||
struct be_queue_info cq;
|
||||
/* Remember the skbs that were transmitted */
|
||||
struct sk_buff *sent_skb_list[TX_Q_LEN];
|
||||
struct be_tx_stats stats;
|
||||
};
|
||||
|
||||
/* Struct to remember the pages posted for rx frags */
|
||||
struct be_rx_page_info {
|
||||
struct page *page;
|
||||
DEFINE_DMA_UNMAP_ADDR(bus);
|
||||
u16 page_offset;
|
||||
bool last_page_user;
|
||||
};
|
||||
|
||||
struct be_rx_stats {
|
||||
u64 rx_bytes;
|
||||
u64 rx_pkts;
|
||||
u64 rx_pkts_prev;
|
||||
ulong rx_jiffies;
|
||||
u32 rx_drops_no_skbs; /* skb allocation errors */
|
||||
u32 rx_drops_no_frags; /* HW has no fetched frags */
|
||||
u32 rx_post_fail; /* page post alloc failures */
|
||||
u32 rx_polls; /* NAPI calls */
|
||||
u32 rx_events;
|
||||
u32 rx_compl;
|
||||
u32 rx_mcast_pkts;
|
||||
u32 rx_compl_err; /* completions with err set */
|
||||
u32 rx_pps; /* pkts per second */
|
||||
struct u64_stats_sync sync;
|
||||
};
|
||||
|
||||
struct be_rx_compl_info {
|
||||
u32 rss_hash;
|
||||
u16 vlan_tag;
|
||||
u16 pkt_size;
|
||||
u16 rxq_idx;
|
||||
u16 port;
|
||||
u8 vlanf;
|
||||
u8 num_rcvd;
|
||||
u8 err;
|
||||
u8 ipf;
|
||||
u8 tcpf;
|
||||
u8 udpf;
|
||||
u8 ip_csum;
|
||||
u8 l4_csum;
|
||||
u8 ipv6;
|
||||
u8 vtm;
|
||||
u8 pkt_type;
|
||||
};
|
||||
|
||||
struct be_rx_obj {
|
||||
struct be_adapter *adapter;
|
||||
struct be_queue_info q;
|
||||
struct be_queue_info cq;
|
||||
struct be_rx_compl_info rxcp;
|
||||
struct be_rx_page_info page_info_tbl[RX_Q_LEN];
|
||||
struct be_eq_obj rx_eq;
|
||||
struct be_rx_stats stats;
|
||||
u8 rss_id;
|
||||
bool rx_post_starved; /* Zero rx frags have been posted to BE */
|
||||
u32 cache_line_barrier[16];
|
||||
};
|
||||
|
||||
struct be_drv_stats {
|
||||
u8 be_on_die_temperature;
|
||||
u32 tx_events;
|
||||
u32 eth_red_drops;
|
||||
u32 rx_drops_no_pbuf;
|
||||
u32 rx_drops_no_txpb;
|
||||
u32 rx_drops_no_erx_descr;
|
||||
u32 rx_drops_no_tpre_descr;
|
||||
u32 rx_drops_too_many_frags;
|
||||
u32 rx_drops_invalid_ring;
|
||||
u32 forwarded_packets;
|
||||
u32 rx_drops_mtu;
|
||||
u32 rx_crc_errors;
|
||||
u32 rx_alignment_symbol_errors;
|
||||
u32 rx_pause_frames;
|
||||
u32 rx_priority_pause_frames;
|
||||
u32 rx_control_frames;
|
||||
u32 rx_in_range_errors;
|
||||
u32 rx_out_range_errors;
|
||||
u32 rx_frame_too_long;
|
||||
u32 rx_address_match_errors;
|
||||
u32 rx_dropped_too_small;
|
||||
u32 rx_dropped_too_short;
|
||||
u32 rx_dropped_header_too_small;
|
||||
u32 rx_dropped_tcp_length;
|
||||
u32 rx_dropped_runt;
|
||||
u32 rx_ip_checksum_errs;
|
||||
u32 rx_tcp_checksum_errs;
|
||||
u32 rx_udp_checksum_errs;
|
||||
u32 tx_pauseframes;
|
||||
u32 tx_priority_pauseframes;
|
||||
u32 tx_controlframes;
|
||||
u32 rxpp_fifo_overflow_drop;
|
||||
u32 rx_input_fifo_overflow_drop;
|
||||
u32 pmem_fifo_overflow_drop;
|
||||
u32 jabber_events;
|
||||
};
|
||||
|
||||
struct be_vf_cfg {
|
||||
unsigned char vf_mac_addr[ETH_ALEN];
|
||||
u32 vf_if_handle;
|
||||
u32 vf_pmac_id;
|
||||
u16 vf_vlan_tag;
|
||||
u32 vf_tx_rate;
|
||||
};
|
||||
|
||||
#define BE_INVALID_PMAC_ID 0xffffffff
|
||||
|
||||
struct be_adapter {
|
||||
struct pci_dev *pdev;
|
||||
struct net_device *netdev;
|
||||
|
||||
u8 __iomem *csr;
|
||||
u8 __iomem *db; /* Door Bell */
|
||||
u8 __iomem *pcicfg; /* PCI config space */
|
||||
|
||||
struct mutex mbox_lock; /* For serializing mbox cmds to BE card */
|
||||
struct be_dma_mem mbox_mem;
|
||||
/* Mbox mem is adjusted to align to 16 bytes. The allocated addr
|
||||
* is stored for freeing purpose */
|
||||
struct be_dma_mem mbox_mem_alloced;
|
||||
|
||||
struct be_mcc_obj mcc_obj;
|
||||
spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */
|
||||
spinlock_t mcc_cq_lock;
|
||||
|
||||
struct msix_entry msix_entries[BE_MAX_MSIX_VECTORS];
|
||||
u32 num_msix_vec;
|
||||
bool isr_registered;
|
||||
|
||||
/* TX Rings */
|
||||
struct be_eq_obj tx_eq;
|
||||
struct be_tx_obj tx_obj[MAX_TX_QS];
|
||||
u8 num_tx_qs;
|
||||
|
||||
u32 cache_line_break[8];
|
||||
|
||||
/* Rx rings */
|
||||
struct be_rx_obj rx_obj[MAX_RX_QS];
|
||||
u32 num_rx_qs;
|
||||
u32 big_page_size; /* Compounded page size shared by rx wrbs */
|
||||
|
||||
u8 eq_next_idx;
|
||||
struct be_drv_stats drv_stats;
|
||||
|
||||
u16 vlans_added;
|
||||
u16 max_vlans; /* Number of vlans supported */
|
||||
u8 vlan_tag[VLAN_N_VID];
|
||||
u8 vlan_prio_bmap; /* Available Priority BitMap */
|
||||
u16 recommended_prio; /* Recommended Priority */
|
||||
struct be_dma_mem rx_filter; /* Cmd DMA mem for rx-filter */
|
||||
|
||||
struct be_dma_mem stats_cmd;
|
||||
/* Work queue used to perform periodic tasks like getting statistics */
|
||||
struct delayed_work work;
|
||||
u16 work_counter;
|
||||
|
||||
/* Ethtool knobs and info */
|
||||
char fw_ver[FW_VER_LEN];
|
||||
u32 if_handle; /* Used to configure filtering */
|
||||
u32 pmac_id; /* MAC addr handle used by BE card */
|
||||
u32 beacon_state; /* for set_phys_id */
|
||||
|
||||
bool eeh_err;
|
||||
bool link_up;
|
||||
u32 port_num;
|
||||
bool promiscuous;
|
||||
bool wol;
|
||||
u32 function_mode;
|
||||
u32 function_caps;
|
||||
u32 rx_fc; /* Rx flow control */
|
||||
u32 tx_fc; /* Tx flow control */
|
||||
bool ue_detected;
|
||||
bool stats_cmd_sent;
|
||||
int link_speed;
|
||||
u8 port_type;
|
||||
u8 transceiver;
|
||||
u8 autoneg;
|
||||
u8 generation; /* BladeEngine ASIC generation */
|
||||
u32 flash_status;
|
||||
struct completion flash_compl;
|
||||
|
||||
bool be3_native;
|
||||
bool sriov_enabled;
|
||||
struct be_vf_cfg *vf_cfg;
|
||||
u8 is_virtfn;
|
||||
u32 sli_family;
|
||||
u8 hba_port_num;
|
||||
u16 pvid;
|
||||
};
|
||||
|
||||
#define be_physfn(adapter) (!adapter->is_virtfn)
|
||||
|
||||
/* BladeEngine Generation numbers */
|
||||
#define BE_GEN2 2
|
||||
#define BE_GEN3 3
|
||||
|
||||
#define ON 1
|
||||
#define OFF 0
|
||||
#define lancer_chip(adapter) ((adapter->pdev->device == OC_DEVICE_ID3) || \
|
||||
(adapter->pdev->device == OC_DEVICE_ID4))
|
||||
|
||||
extern const struct ethtool_ops be_ethtool_ops;
|
||||
|
||||
#define msix_enabled(adapter) (adapter->num_msix_vec > 0)
|
||||
#define tx_stats(txo) (&txo->stats)
|
||||
#define rx_stats(rxo) (&rxo->stats)
|
||||
|
||||
#define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops)
|
||||
|
||||
#define for_all_rx_queues(adapter, rxo, i) \
|
||||
for (i = 0, rxo = &adapter->rx_obj[i]; i < adapter->num_rx_qs; \
|
||||
i++, rxo++)
|
||||
|
||||
/* Just skip the first default non-rss queue */
|
||||
#define for_all_rss_queues(adapter, rxo, i) \
|
||||
for (i = 0, rxo = &adapter->rx_obj[i+1]; i < (adapter->num_rx_qs - 1);\
|
||||
i++, rxo++)
|
||||
|
||||
#define for_all_tx_queues(adapter, txo, i) \
|
||||
for (i = 0, txo = &adapter->tx_obj[i]; i < adapter->num_tx_qs; \
|
||||
i++, txo++)
|
||||
|
||||
#define PAGE_SHIFT_4K 12
|
||||
#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K)
|
||||
|
||||
/* Returns number of pages spanned by the data starting at the given addr */
|
||||
#define PAGES_4K_SPANNED(_address, size) \
|
||||
((u32)((((size_t)(_address) & (PAGE_SIZE_4K - 1)) + \
|
||||
(size) + (PAGE_SIZE_4K - 1)) >> PAGE_SHIFT_4K))
|
||||
|
||||
/* Byte offset into the page corresponding to given address */
|
||||
#define OFFSET_IN_PAGE(addr) \
|
||||
((size_t)(addr) & (PAGE_SIZE_4K-1))
|
||||
|
||||
/* Returns bit offset within a DWORD of a bitfield */
|
||||
#define AMAP_BIT_OFFSET(_struct, field) \
|
||||
(((size_t)&(((_struct *)0)->field))%32)
|
||||
|
||||
/* Returns the bit mask of the field that is NOT shifted into location. */
|
||||
static inline u32 amap_mask(u32 bitsize)
|
||||
{
|
||||
return (bitsize == 32 ? 0xFFFFFFFF : (1 << bitsize) - 1);
|
||||
}
|
||||
|
||||
static inline void
|
||||
amap_set(void *ptr, u32 dw_offset, u32 mask, u32 offset, u32 value)
|
||||
{
|
||||
u32 *dw = (u32 *) ptr + dw_offset;
|
||||
*dw &= ~(mask << offset);
|
||||
*dw |= (mask & value) << offset;
|
||||
}
|
||||
|
||||
#define AMAP_SET_BITS(_struct, field, ptr, val) \
|
||||
amap_set(ptr, \
|
||||
offsetof(_struct, field)/32, \
|
||||
amap_mask(sizeof(((_struct *)0)->field)), \
|
||||
AMAP_BIT_OFFSET(_struct, field), \
|
||||
val)
|
||||
|
||||
static inline u32 amap_get(void *ptr, u32 dw_offset, u32 mask, u32 offset)
|
||||
{
|
||||
u32 *dw = (u32 *) ptr;
|
||||
return mask & (*(dw + dw_offset) >> offset);
|
||||
}
|
||||
|
||||
#define AMAP_GET_BITS(_struct, field, ptr) \
|
||||
amap_get(ptr, \
|
||||
offsetof(_struct, field)/32, \
|
||||
amap_mask(sizeof(((_struct *)0)->field)), \
|
||||
AMAP_BIT_OFFSET(_struct, field))
|
||||
|
||||
#define be_dws_cpu_to_le(wrb, len) swap_dws(wrb, len)
|
||||
#define be_dws_le_to_cpu(wrb, len) swap_dws(wrb, len)
|
||||
static inline void swap_dws(void *wrb, int len)
|
||||
{
|
||||
#ifdef __BIG_ENDIAN
|
||||
u32 *dw = wrb;
|
||||
BUG_ON(len % 4);
|
||||
do {
|
||||
*dw = cpu_to_le32(*dw);
|
||||
dw++;
|
||||
len -= 4;
|
||||
} while (len);
|
||||
#endif /* __BIG_ENDIAN */
|
||||
}
|
||||
|
||||
static inline u8 is_tcp_pkt(struct sk_buff *skb)
|
||||
{
|
||||
u8 val = 0;
|
||||
|
||||
if (ip_hdr(skb)->version == 4)
|
||||
val = (ip_hdr(skb)->protocol == IPPROTO_TCP);
|
||||
else if (ip_hdr(skb)->version == 6)
|
||||
val = (ipv6_hdr(skb)->nexthdr == NEXTHDR_TCP);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline u8 is_udp_pkt(struct sk_buff *skb)
|
||||
{
|
||||
u8 val = 0;
|
||||
|
||||
if (ip_hdr(skb)->version == 4)
|
||||
val = (ip_hdr(skb)->protocol == IPPROTO_UDP);
|
||||
else if (ip_hdr(skb)->version == 6)
|
||||
val = (ipv6_hdr(skb)->nexthdr == NEXTHDR_UDP);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void be_check_sriov_fn_type(struct be_adapter *adapter)
|
||||
{
|
||||
u32 sli_intf;
|
||||
|
||||
pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf);
|
||||
adapter->is_virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0;
|
||||
}
|
||||
|
||||
static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac)
|
||||
{
|
||||
u32 addr;
|
||||
|
||||
addr = jhash(adapter->netdev->dev_addr, ETH_ALEN, 0);
|
||||
|
||||
mac[5] = (u8)(addr & 0xFF);
|
||||
mac[4] = (u8)((addr >> 8) & 0xFF);
|
||||
mac[3] = (u8)((addr >> 16) & 0xFF);
|
||||
/* Use the OUI from the current MAC address */
|
||||
memcpy(mac, adapter->netdev->dev_addr, 3);
|
||||
}
|
||||
|
||||
static inline bool be_multi_rxq(const struct be_adapter *adapter)
|
||||
{
|
||||
return adapter->num_rx_qs > 1;
|
||||
}
|
||||
|
||||
extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
|
||||
u16 num_popped);
|
||||
extern void be_link_status_update(struct be_adapter *adapter, u32 link_status);
|
||||
extern void be_parse_stats(struct be_adapter *adapter);
|
||||
extern int be_load_fw(struct be_adapter *adapter, u8 *func);
|
||||
#endif /* BE_H */
|
文件差异内容过多而无法显示
加载差异
文件差异内容过多而无法显示
加载差异
@@ -0,0 +1,714 @@
|
||||
/*
|
||||
* Copyright (C) 2005 - 2011 Emulex
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation. The full GNU General
|
||||
* Public License is included in this distribution in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* linux-drivers@emulex.com
|
||||
*
|
||||
* Emulex
|
||||
* 3333 Susan Street
|
||||
* Costa Mesa, CA 92626
|
||||
*/
|
||||
|
||||
#include "be.h"
|
||||
#include "be_cmds.h"
|
||||
#include <linux/ethtool.h>
|
||||
|
||||
struct be_ethtool_stat {
|
||||
char desc[ETH_GSTRING_LEN];
|
||||
int type;
|
||||
int size;
|
||||
int offset;
|
||||
};
|
||||
|
||||
enum {DRVSTAT_TX, DRVSTAT_RX, DRVSTAT};
|
||||
#define FIELDINFO(_struct, field) FIELD_SIZEOF(_struct, field), \
|
||||
offsetof(_struct, field)
|
||||
#define DRVSTAT_TX_INFO(field) #field, DRVSTAT_TX,\
|
||||
FIELDINFO(struct be_tx_stats, field)
|
||||
#define DRVSTAT_RX_INFO(field) #field, DRVSTAT_RX,\
|
||||
FIELDINFO(struct be_rx_stats, field)
|
||||
#define DRVSTAT_INFO(field) #field, DRVSTAT,\
|
||||
FIELDINFO(struct be_drv_stats, field)
|
||||
|
||||
static const struct be_ethtool_stat et_stats[] = {
|
||||
{DRVSTAT_INFO(tx_events)},
|
||||
{DRVSTAT_INFO(rx_crc_errors)},
|
||||
{DRVSTAT_INFO(rx_alignment_symbol_errors)},
|
||||
{DRVSTAT_INFO(rx_pause_frames)},
|
||||
{DRVSTAT_INFO(rx_control_frames)},
|
||||
{DRVSTAT_INFO(rx_in_range_errors)},
|
||||
{DRVSTAT_INFO(rx_out_range_errors)},
|
||||
{DRVSTAT_INFO(rx_frame_too_long)},
|
||||
{DRVSTAT_INFO(rx_address_match_errors)},
|
||||
{DRVSTAT_INFO(rx_dropped_too_small)},
|
||||
{DRVSTAT_INFO(rx_dropped_too_short)},
|
||||
{DRVSTAT_INFO(rx_dropped_header_too_small)},
|
||||
{DRVSTAT_INFO(rx_dropped_tcp_length)},
|
||||
{DRVSTAT_INFO(rx_dropped_runt)},
|
||||
{DRVSTAT_INFO(rxpp_fifo_overflow_drop)},
|
||||
{DRVSTAT_INFO(rx_input_fifo_overflow_drop)},
|
||||
{DRVSTAT_INFO(rx_ip_checksum_errs)},
|
||||
{DRVSTAT_INFO(rx_tcp_checksum_errs)},
|
||||
{DRVSTAT_INFO(rx_udp_checksum_errs)},
|
||||
{DRVSTAT_INFO(tx_pauseframes)},
|
||||
{DRVSTAT_INFO(tx_controlframes)},
|
||||
{DRVSTAT_INFO(rx_priority_pause_frames)},
|
||||
{DRVSTAT_INFO(pmem_fifo_overflow_drop)},
|
||||
{DRVSTAT_INFO(jabber_events)},
|
||||
{DRVSTAT_INFO(rx_drops_no_pbuf)},
|
||||
{DRVSTAT_INFO(rx_drops_no_txpb)},
|
||||
{DRVSTAT_INFO(rx_drops_no_erx_descr)},
|
||||
{DRVSTAT_INFO(rx_drops_no_tpre_descr)},
|
||||
{DRVSTAT_INFO(rx_drops_too_many_frags)},
|
||||
{DRVSTAT_INFO(rx_drops_invalid_ring)},
|
||||
{DRVSTAT_INFO(forwarded_packets)},
|
||||
{DRVSTAT_INFO(rx_drops_mtu)},
|
||||
{DRVSTAT_INFO(eth_red_drops)},
|
||||
{DRVSTAT_INFO(be_on_die_temperature)}
|
||||
};
|
||||
#define ETHTOOL_STATS_NUM ARRAY_SIZE(et_stats)
|
||||
|
||||
/* Stats related to multi RX queues: get_stats routine assumes bytes, pkts
|
||||
* are first and second members respectively.
|
||||
*/
|
||||
static const struct be_ethtool_stat et_rx_stats[] = {
|
||||
{DRVSTAT_RX_INFO(rx_bytes)},/* If moving this member see above note */
|
||||
{DRVSTAT_RX_INFO(rx_pkts)}, /* If moving this member see above note */
|
||||
{DRVSTAT_RX_INFO(rx_polls)},
|
||||
{DRVSTAT_RX_INFO(rx_events)},
|
||||
{DRVSTAT_RX_INFO(rx_compl)},
|
||||
{DRVSTAT_RX_INFO(rx_mcast_pkts)},
|
||||
{DRVSTAT_RX_INFO(rx_post_fail)},
|
||||
{DRVSTAT_RX_INFO(rx_drops_no_skbs)},
|
||||
{DRVSTAT_RX_INFO(rx_drops_no_frags)}
|
||||
};
|
||||
#define ETHTOOL_RXSTATS_NUM (ARRAY_SIZE(et_rx_stats))
|
||||
|
||||
/* Stats related to multi TX queues: get_stats routine assumes compl is the
|
||||
* first member
|
||||
*/
|
||||
static const struct be_ethtool_stat et_tx_stats[] = {
|
||||
{DRVSTAT_TX_INFO(tx_compl)}, /* If moving this member see above note */
|
||||
{DRVSTAT_TX_INFO(tx_bytes)},
|
||||
{DRVSTAT_TX_INFO(tx_pkts)},
|
||||
{DRVSTAT_TX_INFO(tx_reqs)},
|
||||
{DRVSTAT_TX_INFO(tx_wrbs)},
|
||||
{DRVSTAT_TX_INFO(tx_compl)},
|
||||
{DRVSTAT_TX_INFO(tx_stops)}
|
||||
};
|
||||
#define ETHTOOL_TXSTATS_NUM (ARRAY_SIZE(et_tx_stats))
|
||||
|
||||
static const char et_self_tests[][ETH_GSTRING_LEN] = {
|
||||
"MAC Loopback test",
|
||||
"PHY Loopback test",
|
||||
"External Loopback test",
|
||||
"DDR DMA test",
|
||||
"Link test"
|
||||
};
|
||||
|
||||
#define ETHTOOL_TESTS_NUM ARRAY_SIZE(et_self_tests)
|
||||
#define BE_MAC_LOOPBACK 0x0
|
||||
#define BE_PHY_LOOPBACK 0x1
|
||||
#define BE_ONE_PORT_EXT_LOOPBACK 0x2
|
||||
#define BE_NO_LOOPBACK 0xff
|
||||
|
||||
static void
|
||||
be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
|
||||
{
|
||||
struct be_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
strcpy(drvinfo->driver, DRV_NAME);
|
||||
strcpy(drvinfo->version, DRV_VER);
|
||||
strncpy(drvinfo->fw_version, adapter->fw_ver, FW_VER_LEN);
|
||||
strcpy(drvinfo->bus_info, pci_name(adapter->pdev));
|
||||
drvinfo->testinfo_len = 0;
|
||||
drvinfo->regdump_len = 0;
|
||||
drvinfo->eedump_len = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
be_get_reg_len(struct net_device *netdev)
|
||||
{
|
||||
struct be_adapter *adapter = netdev_priv(netdev);
|
||||
u32 log_size = 0;
|
||||
|
||||
if (be_physfn(adapter))
|
||||
be_cmd_get_reg_len(adapter, &log_size);
|
||||
|
||||
return log_size;
|
||||
}
|
||||
|
||||
static void
|
||||
be_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *buf)
|
||||
{
|
||||
struct be_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
if (be_physfn(adapter)) {
|
||||
memset(buf, 0, regs->len);
|
||||
be_cmd_get_regs(adapter, regs->len, buf);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
|
||||
{
|
||||
struct be_adapter *adapter = netdev_priv(netdev);
|
||||
struct be_eq_obj *rx_eq = &adapter->rx_obj[0].rx_eq;
|
||||
struct be_eq_obj *tx_eq = &adapter->tx_eq;
|
||||
|
||||
coalesce->rx_coalesce_usecs = rx_eq->cur_eqd;
|
||||
coalesce->rx_coalesce_usecs_high = rx_eq->max_eqd;
|
||||
coalesce->rx_coalesce_usecs_low = rx_eq->min_eqd;
|
||||
|
||||
coalesce->tx_coalesce_usecs = tx_eq->cur_eqd;
|
||||
coalesce->tx_coalesce_usecs_high = tx_eq->max_eqd;
|
||||
coalesce->tx_coalesce_usecs_low = tx_eq->min_eqd;
|
||||
|
||||
coalesce->use_adaptive_rx_coalesce = rx_eq->enable_aic;
|
||||
coalesce->use_adaptive_tx_coalesce = tx_eq->enable_aic;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine is used to set interrup coalescing delay
|
||||
*/
|
||||
static int
|
||||
be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
|
||||
{
|
||||
struct be_adapter *adapter = netdev_priv(netdev);
|
||||
struct be_rx_obj *rxo;
|
||||
struct be_eq_obj *rx_eq;
|
||||
struct be_eq_obj *tx_eq = &adapter->tx_eq;
|
||||
u32 rx_max, rx_min, rx_cur;
|
||||
int status = 0, i;
|
||||
u32 tx_cur;
|
||||
|
||||
if (coalesce->use_adaptive_tx_coalesce == 1)
|
||||
return -EINVAL;
|
||||
|
||||
for_all_rx_queues(adapter, rxo, i) {
|
||||
rx_eq = &rxo->rx_eq;
|
||||
|
||||
if (!rx_eq->enable_aic && coalesce->use_adaptive_rx_coalesce)
|
||||
rx_eq->cur_eqd = 0;
|
||||
rx_eq->enable_aic = coalesce->use_adaptive_rx_coalesce;
|
||||
|
||||
rx_max = coalesce->rx_coalesce_usecs_high;
|
||||
rx_min = coalesce->rx_coalesce_usecs_low;
|
||||
rx_cur = coalesce->rx_coalesce_usecs;
|
||||
|
||||
if (rx_eq->enable_aic) {
|
||||
if (rx_max > BE_MAX_EQD)
|
||||
rx_max = BE_MAX_EQD;
|
||||
if (rx_min > rx_max)
|
||||
rx_min = rx_max;
|
||||
rx_eq->max_eqd = rx_max;
|
||||
rx_eq->min_eqd = rx_min;
|
||||
if (rx_eq->cur_eqd > rx_max)
|
||||
rx_eq->cur_eqd = rx_max;
|
||||
if (rx_eq->cur_eqd < rx_min)
|
||||
rx_eq->cur_eqd = rx_min;
|
||||
} else {
|
||||
if (rx_cur > BE_MAX_EQD)
|
||||
rx_cur = BE_MAX_EQD;
|
||||
if (rx_eq->cur_eqd != rx_cur) {
|
||||
status = be_cmd_modify_eqd(adapter, rx_eq->q.id,
|
||||
rx_cur);
|
||||
if (!status)
|
||||
rx_eq->cur_eqd = rx_cur;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tx_cur = coalesce->tx_coalesce_usecs;
|
||||
|
||||
if (tx_cur > BE_MAX_EQD)
|
||||
tx_cur = BE_MAX_EQD;
|
||||
if (tx_eq->cur_eqd != tx_cur) {
|
||||
status = be_cmd_modify_eqd(adapter, tx_eq->q.id, tx_cur);
|
||||
if (!status)
|
||||
tx_eq->cur_eqd = tx_cur;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
be_get_ethtool_stats(struct net_device *netdev,
|
||||
struct ethtool_stats *stats, uint64_t *data)
|
||||
{
|
||||
struct be_adapter *adapter = netdev_priv(netdev);
|
||||
struct be_rx_obj *rxo;
|
||||
struct be_tx_obj *txo;
|
||||
void *p;
|
||||
unsigned int i, j, base = 0, start;
|
||||
|
||||
for (i = 0; i < ETHTOOL_STATS_NUM; i++) {
|
||||
p = (u8 *)&adapter->drv_stats + et_stats[i].offset;
|
||||
data[i] = *(u32 *)p;
|
||||
}
|
||||
base += ETHTOOL_STATS_NUM;
|
||||
|
||||
for_all_rx_queues(adapter, rxo, j) {
|
||||
struct be_rx_stats *stats = rx_stats(rxo);
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&stats->sync);
|
||||
data[base] = stats->rx_bytes;
|
||||
data[base + 1] = stats->rx_pkts;
|
||||
} while (u64_stats_fetch_retry_bh(&stats->sync, start));
|
||||
|
||||
for (i = 2; i < ETHTOOL_RXSTATS_NUM; i++) {
|
||||
p = (u8 *)stats + et_rx_stats[i].offset;
|
||||
data[base + i] = *(u32 *)p;
|
||||
}
|
||||
base += ETHTOOL_RXSTATS_NUM;
|
||||
}
|
||||
|
||||
for_all_tx_queues(adapter, txo, j) {
|
||||
struct be_tx_stats *stats = tx_stats(txo);
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&stats->sync_compl);
|
||||
data[base] = stats->tx_compl;
|
||||
} while (u64_stats_fetch_retry_bh(&stats->sync_compl, start));
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_bh(&stats->sync);
|
||||
for (i = 1; i < ETHTOOL_TXSTATS_NUM; i++) {
|
||||
p = (u8 *)stats + et_tx_stats[i].offset;
|
||||
data[base + i] =
|
||||
(et_tx_stats[i].size == sizeof(u64)) ?
|
||||
*(u64 *)p : *(u32 *)p;
|
||||
}
|
||||
} while (u64_stats_fetch_retry_bh(&stats->sync, start));
|
||||
base += ETHTOOL_TXSTATS_NUM;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
be_get_stat_strings(struct net_device *netdev, uint32_t stringset,
|
||||
uint8_t *data)
|
||||
{
|
||||
struct be_adapter *adapter = netdev_priv(netdev);
|
||||
int i, j;
|
||||
|
||||
switch (stringset) {
|
||||
case ETH_SS_STATS:
|
||||
for (i = 0; i < ETHTOOL_STATS_NUM; i++) {
|
||||
memcpy(data, et_stats[i].desc, ETH_GSTRING_LEN);
|
||||
data += ETH_GSTRING_LEN;
|
||||
}
|
||||
for (i = 0; i < adapter->num_rx_qs; i++) {
|
||||
for (j = 0; j < ETHTOOL_RXSTATS_NUM; j++) {
|
||||
sprintf(data, "rxq%d: %s", i,
|
||||
et_rx_stats[j].desc);
|
||||
data += ETH_GSTRING_LEN;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < adapter->num_tx_qs; i++) {
|
||||
for (j = 0; j < ETHTOOL_TXSTATS_NUM; j++) {
|
||||
sprintf(data, "txq%d: %s", i,
|
||||
et_tx_stats[j].desc);
|
||||
data += ETH_GSTRING_LEN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ETH_SS_TEST:
|
||||
for (i = 0; i < ETHTOOL_TESTS_NUM; i++) {
|
||||
memcpy(data, et_self_tests[i], ETH_GSTRING_LEN);
|
||||
data += ETH_GSTRING_LEN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int be_get_sset_count(struct net_device *netdev, int stringset)
|
||||
{
|
||||
struct be_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
switch (stringset) {
|
||||
case ETH_SS_TEST:
|
||||
return ETHTOOL_TESTS_NUM;
|
||||
case ETH_SS_STATS:
|
||||
return ETHTOOL_STATS_NUM +
|
||||
adapter->num_rx_qs * ETHTOOL_RXSTATS_NUM +
|
||||
adapter->num_tx_qs * ETHTOOL_TXSTATS_NUM;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
|
||||
{
|
||||
struct be_adapter *adapter = netdev_priv(netdev);
|
||||
struct be_phy_info phy_info;
|
||||
u8 mac_speed = 0;
|
||||
u16 link_speed = 0;
|
||||
int status;
|
||||
|
||||
if ((adapter->link_speed < 0) || (!(netdev->flags & IFF_UP))) {
|
||||
status = be_cmd_link_status_query(adapter, &mac_speed,
|
||||
&link_speed, 0);
|
||||
|
||||
/* link_speed is in units of 10 Mbps */
|
||||
if (link_speed) {
|
||||
ethtool_cmd_speed_set(ecmd, link_speed*10);
|
||||
} else {
|
||||
switch (mac_speed) {
|
||||
case PHY_LINK_SPEED_10MBPS:
|
||||
ethtool_cmd_speed_set(ecmd, SPEED_10);
|
||||
break;
|
||||
case PHY_LINK_SPEED_100MBPS:
|
||||
ethtool_cmd_speed_set(ecmd, SPEED_100);
|
||||
break;
|
||||
case PHY_LINK_SPEED_1GBPS:
|
||||
ethtool_cmd_speed_set(ecmd, SPEED_1000);
|
||||
break;
|
||||
case PHY_LINK_SPEED_10GBPS:
|
||||
ethtool_cmd_speed_set(ecmd, SPEED_10000);
|
||||
break;
|
||||
case PHY_LINK_SPEED_ZERO:
|
||||
ethtool_cmd_speed_set(ecmd, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
status = be_cmd_get_phy_info(adapter, &phy_info);
|
||||
if (!status) {
|
||||
switch (phy_info.interface_type) {
|
||||
case PHY_TYPE_XFP_10GB:
|
||||
case PHY_TYPE_SFP_1GB:
|
||||
case PHY_TYPE_SFP_PLUS_10GB:
|
||||
ecmd->port = PORT_FIBRE;
|
||||
break;
|
||||
default:
|
||||
ecmd->port = PORT_TP;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (phy_info.interface_type) {
|
||||
case PHY_TYPE_KR_10GB:
|
||||
case PHY_TYPE_KX4_10GB:
|
||||
ecmd->autoneg = AUTONEG_ENABLE;
|
||||
ecmd->transceiver = XCVR_INTERNAL;
|
||||
break;
|
||||
default:
|
||||
ecmd->autoneg = AUTONEG_DISABLE;
|
||||
ecmd->transceiver = XCVR_EXTERNAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Save for future use */
|
||||
adapter->link_speed = ethtool_cmd_speed(ecmd);
|
||||
adapter->port_type = ecmd->port;
|
||||
adapter->transceiver = ecmd->transceiver;
|
||||
adapter->autoneg = ecmd->autoneg;
|
||||
} else {
|
||||
ethtool_cmd_speed_set(ecmd, adapter->link_speed);
|
||||
ecmd->port = adapter->port_type;
|
||||
ecmd->transceiver = adapter->transceiver;
|
||||
ecmd->autoneg = adapter->autoneg;
|
||||
}
|
||||
|
||||
ecmd->duplex = DUPLEX_FULL;
|
||||
ecmd->phy_address = adapter->port_num;
|
||||
switch (ecmd->port) {
|
||||
case PORT_FIBRE:
|
||||
ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
|
||||
break;
|
||||
case PORT_TP:
|
||||
ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_TP);
|
||||
break;
|
||||
case PORT_AUI:
|
||||
ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_AUI);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ecmd->autoneg) {
|
||||
ecmd->supported |= SUPPORTED_1000baseT_Full;
|
||||
ecmd->supported |= SUPPORTED_Autoneg;
|
||||
ecmd->advertising |= (ADVERTISED_10000baseT_Full |
|
||||
ADVERTISED_1000baseT_Full);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
be_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
|
||||
{
|
||||
struct be_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
ring->rx_max_pending = adapter->rx_obj[0].q.len;
|
||||
ring->tx_max_pending = adapter->tx_obj[0].q.len;
|
||||
|
||||
ring->rx_pending = atomic_read(&adapter->rx_obj[0].q.used);
|
||||
ring->tx_pending = atomic_read(&adapter->tx_obj[0].q.used);
|
||||
}
|
||||
|
||||
static void
|
||||
be_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
|
||||
{
|
||||
struct be_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
be_cmd_get_flow_control(adapter, &ecmd->tx_pause, &ecmd->rx_pause);
|
||||
ecmd->autoneg = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
|
||||
{
|
||||
struct be_adapter *adapter = netdev_priv(netdev);
|
||||
int status;
|
||||
|
||||
if (ecmd->autoneg != 0)
|
||||
return -EINVAL;
|
||||
adapter->tx_fc = ecmd->tx_pause;
|
||||
adapter->rx_fc = ecmd->rx_pause;
|
||||
|
||||
status = be_cmd_set_flow_control(adapter,
|
||||
adapter->tx_fc, adapter->rx_fc);
|
||||
if (status)
|
||||
dev_warn(&adapter->pdev->dev, "Pause param set failed.\n");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int
|
||||
be_set_phys_id(struct net_device *netdev,
|
||||
enum ethtool_phys_id_state state)
|
||||
{
|
||||
struct be_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
switch (state) {
|
||||
case ETHTOOL_ID_ACTIVE:
|
||||
be_cmd_get_beacon_state(adapter, adapter->hba_port_num,
|
||||
&adapter->beacon_state);
|
||||
return 1; /* cycle on/off once per second */
|
||||
|
||||
case ETHTOOL_ID_ON:
|
||||
be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
|
||||
BEACON_STATE_ENABLED);
|
||||
break;
|
||||
|
||||
case ETHTOOL_ID_OFF:
|
||||
be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
|
||||
BEACON_STATE_DISABLED);
|
||||
break;
|
||||
|
||||
case ETHTOOL_ID_INACTIVE:
|
||||
be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
|
||||
adapter->beacon_state);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
be_is_wol_supported(struct be_adapter *adapter)
|
||||
{
|
||||
if (!be_physfn(adapter))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
|
||||
{
|
||||
struct be_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
if (be_is_wol_supported(adapter))
|
||||
wol->supported = WAKE_MAGIC;
|
||||
|
||||
if (adapter->wol)
|
||||
wol->wolopts = WAKE_MAGIC;
|
||||
else
|
||||
wol->wolopts = 0;
|
||||
memset(&wol->sopass, 0, sizeof(wol->sopass));
|
||||
}
|
||||
|
||||
static int
|
||||
be_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
|
||||
{
|
||||
struct be_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
if (wol->wolopts & ~WAKE_MAGIC)
|
||||
return -EINVAL;
|
||||
|
||||
if ((wol->wolopts & WAKE_MAGIC) && be_is_wol_supported(adapter))
|
||||
adapter->wol = true;
|
||||
else
|
||||
adapter->wol = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
be_test_ddr_dma(struct be_adapter *adapter)
|
||||
{
|
||||
int ret, i;
|
||||
struct be_dma_mem ddrdma_cmd;
|
||||
static const u64 pattern[2] = {
|
||||
0x5a5a5a5a5a5a5a5aULL, 0xa5a5a5a5a5a5a5a5ULL
|
||||
};
|
||||
|
||||
ddrdma_cmd.size = sizeof(struct be_cmd_req_ddrdma_test);
|
||||
ddrdma_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, ddrdma_cmd.size,
|
||||
&ddrdma_cmd.dma, GFP_KERNEL);
|
||||
if (!ddrdma_cmd.va) {
|
||||
dev_err(&adapter->pdev->dev, "Memory allocation failure\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
ret = be_cmd_ddr_dma_test(adapter, pattern[i],
|
||||
4096, &ddrdma_cmd);
|
||||
if (ret != 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
err:
|
||||
dma_free_coherent(&adapter->pdev->dev, ddrdma_cmd.size, ddrdma_cmd.va,
|
||||
ddrdma_cmd.dma);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u64 be_loopback_test(struct be_adapter *adapter, u8 loopback_type,
|
||||
u64 *status)
|
||||
{
|
||||
be_cmd_set_loopback(adapter, adapter->hba_port_num,
|
||||
loopback_type, 1);
|
||||
*status = be_cmd_loopback_test(adapter, adapter->hba_port_num,
|
||||
loopback_type, 1500,
|
||||
2, 0xabc);
|
||||
be_cmd_set_loopback(adapter, adapter->hba_port_num,
|
||||
BE_NO_LOOPBACK, 1);
|
||||
return *status;
|
||||
}
|
||||
|
||||
static void
|
||||
be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data)
|
||||
{
|
||||
struct be_adapter *adapter = netdev_priv(netdev);
|
||||
u8 mac_speed = 0;
|
||||
u16 qos_link_speed = 0;
|
||||
|
||||
memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM);
|
||||
|
||||
if (test->flags & ETH_TEST_FL_OFFLINE) {
|
||||
if (be_loopback_test(adapter, BE_MAC_LOOPBACK,
|
||||
&data[0]) != 0) {
|
||||
test->flags |= ETH_TEST_FL_FAILED;
|
||||
}
|
||||
if (be_loopback_test(adapter, BE_PHY_LOOPBACK,
|
||||
&data[1]) != 0) {
|
||||
test->flags |= ETH_TEST_FL_FAILED;
|
||||
}
|
||||
if (be_loopback_test(adapter, BE_ONE_PORT_EXT_LOOPBACK,
|
||||
&data[2]) != 0) {
|
||||
test->flags |= ETH_TEST_FL_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
if (be_test_ddr_dma(adapter) != 0) {
|
||||
data[3] = 1;
|
||||
test->flags |= ETH_TEST_FL_FAILED;
|
||||
}
|
||||
|
||||
if (be_cmd_link_status_query(adapter, &mac_speed,
|
||||
&qos_link_speed, 0) != 0) {
|
||||
test->flags |= ETH_TEST_FL_FAILED;
|
||||
data[4] = -1;
|
||||
} else if (!mac_speed) {
|
||||
test->flags |= ETH_TEST_FL_FAILED;
|
||||
data[4] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
be_do_flash(struct net_device *netdev, struct ethtool_flash *efl)
|
||||
{
|
||||
struct be_adapter *adapter = netdev_priv(netdev);
|
||||
char file_name[ETHTOOL_FLASH_MAX_FILENAME];
|
||||
|
||||
file_name[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0;
|
||||
strcpy(file_name, efl->data);
|
||||
|
||||
return be_load_fw(adapter, file_name);
|
||||
}
|
||||
|
||||
static int
|
||||
be_get_eeprom_len(struct net_device *netdev)
|
||||
{
|
||||
return BE_READ_SEEPROM_LEN;
|
||||
}
|
||||
|
||||
static int
|
||||
be_read_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
|
||||
uint8_t *data)
|
||||
{
|
||||
struct be_adapter *adapter = netdev_priv(netdev);
|
||||
struct be_dma_mem eeprom_cmd;
|
||||
struct be_cmd_resp_seeprom_read *resp;
|
||||
int status;
|
||||
|
||||
if (!eeprom->len)
|
||||
return -EINVAL;
|
||||
|
||||
eeprom->magic = BE_VENDOR_ID | (adapter->pdev->device<<16);
|
||||
|
||||
memset(&eeprom_cmd, 0, sizeof(struct be_dma_mem));
|
||||
eeprom_cmd.size = sizeof(struct be_cmd_req_seeprom_read);
|
||||
eeprom_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, eeprom_cmd.size,
|
||||
&eeprom_cmd.dma, GFP_KERNEL);
|
||||
|
||||
if (!eeprom_cmd.va) {
|
||||
dev_err(&adapter->pdev->dev,
|
||||
"Memory allocation failure. Could not read eeprom\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
status = be_cmd_get_seeprom_data(adapter, &eeprom_cmd);
|
||||
|
||||
if (!status) {
|
||||
resp = eeprom_cmd.va;
|
||||
memcpy(data, resp->seeprom_data + eeprom->offset, eeprom->len);
|
||||
}
|
||||
dma_free_coherent(&adapter->pdev->dev, eeprom_cmd.size, eeprom_cmd.va,
|
||||
eeprom_cmd.dma);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
const struct ethtool_ops be_ethtool_ops = {
|
||||
.get_settings = be_get_settings,
|
||||
.get_drvinfo = be_get_drvinfo,
|
||||
.get_wol = be_get_wol,
|
||||
.set_wol = be_set_wol,
|
||||
.get_link = ethtool_op_get_link,
|
||||
.get_eeprom_len = be_get_eeprom_len,
|
||||
.get_eeprom = be_read_eeprom,
|
||||
.get_coalesce = be_get_coalesce,
|
||||
.set_coalesce = be_set_coalesce,
|
||||
.get_ringparam = be_get_ringparam,
|
||||
.get_pauseparam = be_get_pauseparam,
|
||||
.set_pauseparam = be_set_pauseparam,
|
||||
.get_strings = be_get_stat_strings,
|
||||
.set_phys_id = be_set_phys_id,
|
||||
.get_sset_count = be_get_sset_count,
|
||||
.get_ethtool_stats = be_get_ethtool_stats,
|
||||
.get_regs_len = be_get_reg_len,
|
||||
.get_regs = be_get_regs,
|
||||
.flash_device = be_do_flash,
|
||||
.self_test = be_self_test,
|
||||
};
|
@@ -0,0 +1,510 @@
|
||||
/*
|
||||
* Copyright (C) 2005 - 2011 Emulex
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation. The full GNU General
|
||||
* Public License is included in this distribution in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* linux-drivers@emulex.com
|
||||
*
|
||||
* Emulex
|
||||
* 3333 Susan Street
|
||||
* Costa Mesa, CA 92626
|
||||
*/
|
||||
|
||||
/********* Mailbox door bell *************/
|
||||
/* Used for driver communication with the FW.
|
||||
* The software must write this register twice to post any command. First,
|
||||
* it writes the register with hi=1 and the upper bits of the physical address
|
||||
* for the MAILBOX structure. Software must poll the ready bit until this
|
||||
* is acknowledged. Then, sotware writes the register with hi=0 with the lower
|
||||
* bits in the address. It must poll the ready bit until the command is
|
||||
* complete. Upon completion, the MAILBOX will contain a valid completion
|
||||
* queue entry.
|
||||
*/
|
||||
#define MPU_MAILBOX_DB_OFFSET 0x160
|
||||
#define MPU_MAILBOX_DB_RDY_MASK 0x1 /* bit 0 */
|
||||
#define MPU_MAILBOX_DB_HI_MASK 0x2 /* bit 1 */
|
||||
|
||||
#define MPU_EP_CONTROL 0
|
||||
|
||||
/********** MPU semphore ******************/
|
||||
#define MPU_EP_SEMAPHORE_OFFSET 0xac
|
||||
#define MPU_EP_SEMAPHORE_IF_TYPE2_OFFSET 0x400
|
||||
#define EP_SEMAPHORE_POST_STAGE_MASK 0x0000FFFF
|
||||
#define EP_SEMAPHORE_POST_ERR_MASK 0x1
|
||||
#define EP_SEMAPHORE_POST_ERR_SHIFT 31
|
||||
|
||||
/* MPU semphore POST stage values */
|
||||
#define POST_STAGE_AWAITING_HOST_RDY 0x1 /* FW awaiting goahead from host */
|
||||
#define POST_STAGE_HOST_RDY 0x2 /* Host has given go-ahed to FW */
|
||||
#define POST_STAGE_BE_RESET 0x3 /* Host wants to reset chip */
|
||||
#define POST_STAGE_ARMFW_RDY 0xc000 /* FW is done with POST */
|
||||
|
||||
|
||||
/* Lancer SLIPORT_CONTROL SLIPORT_STATUS registers */
|
||||
#define SLIPORT_STATUS_OFFSET 0x404
|
||||
#define SLIPORT_CONTROL_OFFSET 0x408
|
||||
|
||||
#define SLIPORT_STATUS_ERR_MASK 0x80000000
|
||||
#define SLIPORT_STATUS_RN_MASK 0x01000000
|
||||
#define SLIPORT_STATUS_RDY_MASK 0x00800000
|
||||
|
||||
|
||||
#define SLI_PORT_CONTROL_IP_MASK 0x08000000
|
||||
|
||||
/********* Memory BAR register ************/
|
||||
#define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc
|
||||
/* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt
|
||||
* Disable" may still globally block interrupts in addition to individual
|
||||
* interrupt masks; a mechanism for the device driver to block all interrupts
|
||||
* atomically without having to arbitrate for the PCI Interrupt Disable bit
|
||||
* with the OS.
|
||||
*/
|
||||
#define MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK (1 << 29) /* bit 29 */
|
||||
|
||||
/********* Power management (WOL) **********/
|
||||
#define PCICFG_PM_CONTROL_OFFSET 0x44
|
||||
#define PCICFG_PM_CONTROL_MASK 0x108 /* bits 3 & 8 */
|
||||
|
||||
/********* Online Control Registers *******/
|
||||
#define PCICFG_ONLINE0 0xB0
|
||||
#define PCICFG_ONLINE1 0xB4
|
||||
|
||||
/********* UE Status and Mask Registers ***/
|
||||
#define PCICFG_UE_STATUS_LOW 0xA0
|
||||
#define PCICFG_UE_STATUS_HIGH 0xA4
|
||||
#define PCICFG_UE_STATUS_LOW_MASK 0xA8
|
||||
#define PCICFG_UE_STATUS_HI_MASK 0xAC
|
||||
|
||||
/******** SLI_INTF ***********************/
|
||||
#define SLI_INTF_REG_OFFSET 0x58
|
||||
#define SLI_INTF_VALID_MASK 0xE0000000
|
||||
#define SLI_INTF_VALID 0xC0000000
|
||||
#define SLI_INTF_HINT2_MASK 0x1F000000
|
||||
#define SLI_INTF_HINT2_SHIFT 24
|
||||
#define SLI_INTF_HINT1_MASK 0x00FF0000
|
||||
#define SLI_INTF_HINT1_SHIFT 16
|
||||
#define SLI_INTF_FAMILY_MASK 0x00000F00
|
||||
#define SLI_INTF_FAMILY_SHIFT 8
|
||||
#define SLI_INTF_IF_TYPE_MASK 0x0000F000
|
||||
#define SLI_INTF_IF_TYPE_SHIFT 12
|
||||
#define SLI_INTF_REV_MASK 0x000000F0
|
||||
#define SLI_INTF_REV_SHIFT 4
|
||||
#define SLI_INTF_FT_MASK 0x00000001
|
||||
|
||||
|
||||
/* SLI family */
|
||||
#define BE_SLI_FAMILY 0x0
|
||||
#define LANCER_A0_SLI_FAMILY 0xA
|
||||
|
||||
|
||||
/********* ISR0 Register offset **********/
|
||||
#define CEV_ISR0_OFFSET 0xC18
|
||||
#define CEV_ISR_SIZE 4
|
||||
|
||||
/********* Event Q door bell *************/
|
||||
#define DB_EQ_OFFSET DB_CQ_OFFSET
|
||||
#define DB_EQ_RING_ID_MASK 0x1FF /* bits 0 - 8 */
|
||||
#define DB_EQ_RING_ID_EXT_MASK 0x3e00 /* bits 9-13 */
|
||||
#define DB_EQ_RING_ID_EXT_MASK_SHIFT (2) /* qid bits 9-13 placing at 11-15 */
|
||||
|
||||
/* Clear the interrupt for this eq */
|
||||
#define DB_EQ_CLR_SHIFT (9) /* bit 9 */
|
||||
/* Must be 1 */
|
||||
#define DB_EQ_EVNT_SHIFT (10) /* bit 10 */
|
||||
/* Number of event entries processed */
|
||||
#define DB_EQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */
|
||||
/* Rearm bit */
|
||||
#define DB_EQ_REARM_SHIFT (29) /* bit 29 */
|
||||
|
||||
/********* Compl Q door bell *************/
|
||||
#define DB_CQ_OFFSET 0x120
|
||||
#define DB_CQ_RING_ID_MASK 0x3FF /* bits 0 - 9 */
|
||||
#define DB_CQ_RING_ID_EXT_MASK 0x7C00 /* bits 10-14 */
|
||||
#define DB_CQ_RING_ID_EXT_MASK_SHIFT (1) /* qid bits 10-14
|
||||
placing at 11-15 */
|
||||
|
||||
/* Number of event entries processed */
|
||||
#define DB_CQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */
|
||||
/* Rearm bit */
|
||||
#define DB_CQ_REARM_SHIFT (29) /* bit 29 */
|
||||
|
||||
/********** TX ULP door bell *************/
|
||||
#define DB_TXULP1_OFFSET 0x60
|
||||
#define DB_TXULP_RING_ID_MASK 0x7FF /* bits 0 - 10 */
|
||||
/* Number of tx entries posted */
|
||||
#define DB_TXULP_NUM_POSTED_SHIFT (16) /* bits 16 - 29 */
|
||||
#define DB_TXULP_NUM_POSTED_MASK 0x3FFF /* bits 16 - 29 */
|
||||
|
||||
/********** RQ(erx) door bell ************/
|
||||
#define DB_RQ_OFFSET 0x100
|
||||
#define DB_RQ_RING_ID_MASK 0x3FF /* bits 0 - 9 */
|
||||
/* Number of rx frags posted */
|
||||
#define DB_RQ_NUM_POSTED_SHIFT (24) /* bits 24 - 31 */
|
||||
|
||||
/********** MCC door bell ************/
|
||||
#define DB_MCCQ_OFFSET 0x140
|
||||
#define DB_MCCQ_RING_ID_MASK 0x7FF /* bits 0 - 10 */
|
||||
/* Number of entries posted */
|
||||
#define DB_MCCQ_NUM_POSTED_SHIFT (16) /* bits 16 - 29 */
|
||||
|
||||
/********** SRIOV VF PCICFG OFFSET ********/
|
||||
#define SRIOV_VF_PCICFG_OFFSET (4096)
|
||||
|
||||
/********** FAT TABLE ********/
|
||||
#define RETRIEVE_FAT 0
|
||||
#define QUERY_FAT 1
|
||||
|
||||
/* Flashrom related descriptors */
|
||||
#define IMAGE_TYPE_FIRMWARE 160
|
||||
#define IMAGE_TYPE_BOOTCODE 224
|
||||
#define IMAGE_TYPE_OPTIONROM 32
|
||||
|
||||
#define NUM_FLASHDIR_ENTRIES 32
|
||||
|
||||
#define IMG_TYPE_ISCSI_ACTIVE 0
|
||||
#define IMG_TYPE_REDBOOT 1
|
||||
#define IMG_TYPE_BIOS 2
|
||||
#define IMG_TYPE_PXE_BIOS 3
|
||||
#define IMG_TYPE_FCOE_BIOS 8
|
||||
#define IMG_TYPE_ISCSI_BACKUP 9
|
||||
#define IMG_TYPE_FCOE_FW_ACTIVE 10
|
||||
#define IMG_TYPE_FCOE_FW_BACKUP 11
|
||||
#define IMG_TYPE_NCSI_FW 13
|
||||
#define IMG_TYPE_PHY_FW 99
|
||||
#define TN_8022 13
|
||||
|
||||
#define ILLEGAL_IOCTL_REQ 2
|
||||
#define FLASHROM_OPER_PHY_FLASH 9
|
||||
#define FLASHROM_OPER_PHY_SAVE 10
|
||||
#define FLASHROM_OPER_FLASH 1
|
||||
#define FLASHROM_OPER_SAVE 2
|
||||
#define FLASHROM_OPER_REPORT 4
|
||||
|
||||
#define FLASH_IMAGE_MAX_SIZE_g2 (1310720) /* Max firmware image size */
|
||||
#define FLASH_BIOS_IMAGE_MAX_SIZE_g2 (262144) /* Max OPTION ROM image sz */
|
||||
#define FLASH_REDBOOT_IMAGE_MAX_SIZE_g2 (262144) /* Max Redboot image sz */
|
||||
#define FLASH_IMAGE_MAX_SIZE_g3 (2097152) /* Max firmware image size */
|
||||
#define FLASH_BIOS_IMAGE_MAX_SIZE_g3 (524288) /* Max OPTION ROM image sz */
|
||||
#define FLASH_REDBOOT_IMAGE_MAX_SIZE_g3 (1048576) /* Max Redboot image sz */
|
||||
#define FLASH_NCSI_IMAGE_MAX_SIZE_g3 (262144)
|
||||
#define FLASH_PHY_FW_IMAGE_MAX_SIZE_g3 262144
|
||||
|
||||
#define FLASH_NCSI_MAGIC (0x16032009)
|
||||
#define FLASH_NCSI_DISABLED (0)
|
||||
#define FLASH_NCSI_ENABLED (1)
|
||||
|
||||
#define FLASH_NCSI_BITFILE_HDR_OFFSET (0x600000)
|
||||
|
||||
/* Offsets for components on Flash. */
|
||||
#define FLASH_iSCSI_PRIMARY_IMAGE_START_g2 (1048576)
|
||||
#define FLASH_iSCSI_BACKUP_IMAGE_START_g2 (2359296)
|
||||
#define FLASH_FCoE_PRIMARY_IMAGE_START_g2 (3670016)
|
||||
#define FLASH_FCoE_BACKUP_IMAGE_START_g2 (4980736)
|
||||
#define FLASH_iSCSI_BIOS_START_g2 (7340032)
|
||||
#define FLASH_PXE_BIOS_START_g2 (7864320)
|
||||
#define FLASH_FCoE_BIOS_START_g2 (524288)
|
||||
#define FLASH_REDBOOT_START_g2 (0)
|
||||
|
||||
#define FLASH_NCSI_START_g3 (15990784)
|
||||
#define FLASH_iSCSI_PRIMARY_IMAGE_START_g3 (2097152)
|
||||
#define FLASH_iSCSI_BACKUP_IMAGE_START_g3 (4194304)
|
||||
#define FLASH_FCoE_PRIMARY_IMAGE_START_g3 (6291456)
|
||||
#define FLASH_FCoE_BACKUP_IMAGE_START_g3 (8388608)
|
||||
#define FLASH_iSCSI_BIOS_START_g3 (12582912)
|
||||
#define FLASH_PXE_BIOS_START_g3 (13107200)
|
||||
#define FLASH_FCoE_BIOS_START_g3 (13631488)
|
||||
#define FLASH_REDBOOT_START_g3 (262144)
|
||||
#define FLASH_PHY_FW_START_g3 1310720
|
||||
|
||||
/************* Rx Packet Type Encoding **************/
|
||||
#define BE_UNICAST_PACKET 0
|
||||
#define BE_MULTICAST_PACKET 1
|
||||
#define BE_BROADCAST_PACKET 2
|
||||
#define BE_RSVD_PACKET 3
|
||||
|
||||
/*
|
||||
* BE descriptors: host memory data structures whose formats
|
||||
* are hardwired in BE silicon.
|
||||
*/
|
||||
/* Event Queue Descriptor */
|
||||
#define EQ_ENTRY_VALID_MASK 0x1 /* bit 0 */
|
||||
#define EQ_ENTRY_RES_ID_MASK 0xFFFF /* bits 16 - 31 */
|
||||
#define EQ_ENTRY_RES_ID_SHIFT 16
|
||||
|
||||
struct be_eq_entry {
|
||||
u32 evt;
|
||||
};
|
||||
|
||||
/* TX Queue Descriptor */
|
||||
#define ETH_WRB_FRAG_LEN_MASK 0xFFFF
|
||||
struct be_eth_wrb {
|
||||
u32 frag_pa_hi; /* dword 0 */
|
||||
u32 frag_pa_lo; /* dword 1 */
|
||||
u32 rsvd0; /* dword 2 */
|
||||
u32 frag_len; /* dword 3: bits 0 - 15 */
|
||||
} __packed;
|
||||
|
||||
/* Pseudo amap definition for eth_hdr_wrb in which each bit of the
|
||||
* actual structure is defined as a byte : used to calculate
|
||||
* offset/shift/mask of each field */
|
||||
struct amap_eth_hdr_wrb {
|
||||
u8 rsvd0[32]; /* dword 0 */
|
||||
u8 rsvd1[32]; /* dword 1 */
|
||||
u8 complete; /* dword 2 */
|
||||
u8 event;
|
||||
u8 crc;
|
||||
u8 forward;
|
||||
u8 lso6;
|
||||
u8 mgmt;
|
||||
u8 ipcs;
|
||||
u8 udpcs;
|
||||
u8 tcpcs;
|
||||
u8 lso;
|
||||
u8 vlan;
|
||||
u8 gso[2];
|
||||
u8 num_wrb[5];
|
||||
u8 lso_mss[14];
|
||||
u8 len[16]; /* dword 3 */
|
||||
u8 vlan_tag[16];
|
||||
} __packed;
|
||||
|
||||
struct be_eth_hdr_wrb {
|
||||
u32 dw[4];
|
||||
};
|
||||
|
||||
/* TX Compl Queue Descriptor */
|
||||
|
||||
/* Pseudo amap definition for eth_tx_compl in which each bit of the
|
||||
* actual structure is defined as a byte: used to calculate
|
||||
* offset/shift/mask of each field */
|
||||
struct amap_eth_tx_compl {
|
||||
u8 wrb_index[16]; /* dword 0 */
|
||||
u8 ct[2]; /* dword 0 */
|
||||
u8 port[2]; /* dword 0 */
|
||||
u8 rsvd0[8]; /* dword 0 */
|
||||
u8 status[4]; /* dword 0 */
|
||||
u8 user_bytes[16]; /* dword 1 */
|
||||
u8 nwh_bytes[8]; /* dword 1 */
|
||||
u8 lso; /* dword 1 */
|
||||
u8 cast_enc[2]; /* dword 1 */
|
||||
u8 rsvd1[5]; /* dword 1 */
|
||||
u8 rsvd2[32]; /* dword 2 */
|
||||
u8 pkts[16]; /* dword 3 */
|
||||
u8 ringid[11]; /* dword 3 */
|
||||
u8 hash_val[4]; /* dword 3 */
|
||||
u8 valid; /* dword 3 */
|
||||
} __packed;
|
||||
|
||||
struct be_eth_tx_compl {
|
||||
u32 dw[4];
|
||||
};
|
||||
|
||||
/* RX Queue Descriptor */
|
||||
struct be_eth_rx_d {
|
||||
u32 fragpa_hi;
|
||||
u32 fragpa_lo;
|
||||
};
|
||||
|
||||
/* RX Compl Queue Descriptor */
|
||||
|
||||
/* Pseudo amap definition for BE2 and BE3 legacy mode eth_rx_compl in which
|
||||
* each bit of the actual structure is defined as a byte: used to calculate
|
||||
* offset/shift/mask of each field */
|
||||
struct amap_eth_rx_compl_v0 {
|
||||
u8 vlan_tag[16]; /* dword 0 */
|
||||
u8 pktsize[14]; /* dword 0 */
|
||||
u8 port; /* dword 0 */
|
||||
u8 ip_opt; /* dword 0 */
|
||||
u8 err; /* dword 1 */
|
||||
u8 rsshp; /* dword 1 */
|
||||
u8 ipf; /* dword 1 */
|
||||
u8 tcpf; /* dword 1 */
|
||||
u8 udpf; /* dword 1 */
|
||||
u8 ipcksm; /* dword 1 */
|
||||
u8 l4_cksm; /* dword 1 */
|
||||
u8 ip_version; /* dword 1 */
|
||||
u8 macdst[6]; /* dword 1 */
|
||||
u8 vtp; /* dword 1 */
|
||||
u8 rsvd0; /* dword 1 */
|
||||
u8 fragndx[10]; /* dword 1 */
|
||||
u8 ct[2]; /* dword 1 */
|
||||
u8 sw; /* dword 1 */
|
||||
u8 numfrags[3]; /* dword 1 */
|
||||
u8 rss_flush; /* dword 2 */
|
||||
u8 cast_enc[2]; /* dword 2 */
|
||||
u8 vtm; /* dword 2 */
|
||||
u8 rss_bank; /* dword 2 */
|
||||
u8 rsvd1[23]; /* dword 2 */
|
||||
u8 lro_pkt; /* dword 2 */
|
||||
u8 rsvd2[2]; /* dword 2 */
|
||||
u8 valid; /* dword 2 */
|
||||
u8 rsshash[32]; /* dword 3 */
|
||||
} __packed;
|
||||
|
||||
/* Pseudo amap definition for BE3 native mode eth_rx_compl in which
|
||||
* each bit of the actual structure is defined as a byte: used to calculate
|
||||
* offset/shift/mask of each field */
|
||||
struct amap_eth_rx_compl_v1 {
|
||||
u8 vlan_tag[16]; /* dword 0 */
|
||||
u8 pktsize[14]; /* dword 0 */
|
||||
u8 vtp; /* dword 0 */
|
||||
u8 ip_opt; /* dword 0 */
|
||||
u8 err; /* dword 1 */
|
||||
u8 rsshp; /* dword 1 */
|
||||
u8 ipf; /* dword 1 */
|
||||
u8 tcpf; /* dword 1 */
|
||||
u8 udpf; /* dword 1 */
|
||||
u8 ipcksm; /* dword 1 */
|
||||
u8 l4_cksm; /* dword 1 */
|
||||
u8 ip_version; /* dword 1 */
|
||||
u8 macdst[7]; /* dword 1 */
|
||||
u8 rsvd0; /* dword 1 */
|
||||
u8 fragndx[10]; /* dword 1 */
|
||||
u8 ct[2]; /* dword 1 */
|
||||
u8 sw; /* dword 1 */
|
||||
u8 numfrags[3]; /* dword 1 */
|
||||
u8 rss_flush; /* dword 2 */
|
||||
u8 cast_enc[2]; /* dword 2 */
|
||||
u8 vtm; /* dword 2 */
|
||||
u8 rss_bank; /* dword 2 */
|
||||
u8 port[2]; /* dword 2 */
|
||||
u8 vntagp; /* dword 2 */
|
||||
u8 header_len[8]; /* dword 2 */
|
||||
u8 header_split[2]; /* dword 2 */
|
||||
u8 rsvd1[13]; /* dword 2 */
|
||||
u8 valid; /* dword 2 */
|
||||
u8 rsshash[32]; /* dword 3 */
|
||||
} __packed;
|
||||
|
||||
struct be_eth_rx_compl {
|
||||
u32 dw[4];
|
||||
};
|
||||
|
||||
struct mgmt_hba_attribs {
|
||||
u8 flashrom_version_string[32];
|
||||
u8 manufacturer_name[32];
|
||||
u32 supported_modes;
|
||||
u32 rsvd0[3];
|
||||
u8 ncsi_ver_string[12];
|
||||
u32 default_extended_timeout;
|
||||
u8 controller_model_number[32];
|
||||
u8 controller_description[64];
|
||||
u8 controller_serial_number[32];
|
||||
u8 ip_version_string[32];
|
||||
u8 firmware_version_string[32];
|
||||
u8 bios_version_string[32];
|
||||
u8 redboot_version_string[32];
|
||||
u8 driver_version_string[32];
|
||||
u8 fw_on_flash_version_string[32];
|
||||
u32 functionalities_supported;
|
||||
u16 max_cdblength;
|
||||
u8 asic_revision;
|
||||
u8 generational_guid[16];
|
||||
u8 hba_port_count;
|
||||
u16 default_link_down_timeout;
|
||||
u8 iscsi_ver_min_max;
|
||||
u8 multifunction_device;
|
||||
u8 cache_valid;
|
||||
u8 hba_status;
|
||||
u8 max_domains_supported;
|
||||
u8 phy_port;
|
||||
u32 firmware_post_status;
|
||||
u32 hba_mtu[8];
|
||||
u32 rsvd1[4];
|
||||
};
|
||||
|
||||
struct mgmt_controller_attrib {
|
||||
struct mgmt_hba_attribs hba_attribs;
|
||||
u16 pci_vendor_id;
|
||||
u16 pci_device_id;
|
||||
u16 pci_sub_vendor_id;
|
||||
u16 pci_sub_system_id;
|
||||
u8 pci_bus_number;
|
||||
u8 pci_device_number;
|
||||
u8 pci_function_number;
|
||||
u8 interface_type;
|
||||
u64 unique_identifier;
|
||||
u32 rsvd0[5];
|
||||
};
|
||||
|
||||
struct controller_id {
|
||||
u32 vendor;
|
||||
u32 device;
|
||||
u32 subvendor;
|
||||
u32 subdevice;
|
||||
};
|
||||
|
||||
struct flash_comp {
|
||||
unsigned long offset;
|
||||
int optype;
|
||||
int size;
|
||||
};
|
||||
|
||||
struct image_hdr {
|
||||
u32 imageid;
|
||||
u32 imageoffset;
|
||||
u32 imagelength;
|
||||
u32 image_checksum;
|
||||
u8 image_version[32];
|
||||
};
|
||||
struct flash_file_hdr_g2 {
|
||||
u8 sign[32];
|
||||
u32 cksum;
|
||||
u32 antidote;
|
||||
struct controller_id cont_id;
|
||||
u32 file_len;
|
||||
u32 chunk_num;
|
||||
u32 total_chunks;
|
||||
u32 num_imgs;
|
||||
u8 build[24];
|
||||
};
|
||||
|
||||
struct flash_file_hdr_g3 {
|
||||
u8 sign[52];
|
||||
u8 ufi_version[4];
|
||||
u32 file_len;
|
||||
u32 cksum;
|
||||
u32 antidote;
|
||||
u32 num_imgs;
|
||||
u8 build[24];
|
||||
u8 rsvd[32];
|
||||
};
|
||||
|
||||
struct flash_section_hdr {
|
||||
u32 format_rev;
|
||||
u32 cksum;
|
||||
u32 antidote;
|
||||
u32 build_no;
|
||||
u8 id_string[64];
|
||||
u32 active_entry_mask;
|
||||
u32 valid_entry_mask;
|
||||
u32 org_content_mask;
|
||||
u32 rsvd0;
|
||||
u32 rsvd1;
|
||||
u32 rsvd2;
|
||||
u32 rsvd3;
|
||||
u32 rsvd4;
|
||||
};
|
||||
|
||||
struct flash_section_entry {
|
||||
u32 type;
|
||||
u32 offset;
|
||||
u32 pad_size;
|
||||
u32 image_size;
|
||||
u32 cksum;
|
||||
u32 entry_point;
|
||||
u32 rsvd0;
|
||||
u32 rsvd1;
|
||||
u8 ver_data[32];
|
||||
};
|
||||
|
||||
struct flash_section_info {
|
||||
u8 cookie[32];
|
||||
struct flash_section_hdr fsec_hdr;
|
||||
struct flash_section_entry fsec_entry[32];
|
||||
};
|
文件差异内容过多而无法显示
加载差异
在新工单中引用
屏蔽一个用户