Commit 219c5361 authored by David S. Miller's avatar David S. Miller

Merge branch 'be2net-next'

Sathya Perla says:

====================
be2net: patch set

v2 changes: add a new line after variable declaration in patch 12.

***
Patch 1 adds a few new log messages to help debugging in failure cases.

Patch 2 uses new macros for parsing RX/TX completions and TX wrbs to
help shorten the lines.

Patch 3 adds a description for the RX counter rx_input_fifo_overflow_drop.

Patch 4 adds TX completion error statistics reporting via ethtool.

Patch 5 adds a dma_mapping_error counter and its reporting via ethtool.

Patch 6 fixes up log messages in the Lancer FW download path.

Patch 7 replaces gotos with direct return statements.

Patch 8 cleans up be_change_mtu() code by using a new macro BE_MAX_MTU

Patch 9 makes be_cmd_get_regs() routine to return an integer status
similar to other FW cmd routines in be_cmds.c

Patch 10 gets rid of TX budget as enforcing a budget on TX completion
processing in NAPI is neither suggested nor it provides a performance benefit.

Patch 11 defines and uses a new macro for_all_tx_queues_on_eq() similar
to the RX processing code.

Patch 12 queries max_tx_qs from the FW for BE3 super-nic profiles.
For those profiles, the driver cannot assume a constant BE3_MAX_TX_QS value,
as the value may change for each function.

Please consider applying this patch set to the net-next tree. Thanks!
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 364a9e93 a28277dc
......@@ -86,6 +86,8 @@ static inline char *nic_name(struct pci_dev *pdev)
#define BE_MAX_JUMBO_FRAME_SIZE 9018
#define BE_MIN_MTU 256
#define BE_MAX_MTU (BE_MAX_JUMBO_FRAME_SIZE - \
(ETH_HLEN + ETH_FCS_LEN))
#define BE_NUM_VLANS_SUPPORTED 64
#define BE_MAX_EQD 128u
......@@ -112,7 +114,6 @@ static inline char *nic_name(struct pci_dev *pdev)
#define MAX_ROCE_EQS 5
#define MAX_MSIX_VECTORS 32
#define MIN_MSIX_VECTORS 1
#define BE_TX_BUDGET 256
#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)
......@@ -198,7 +199,6 @@ struct be_eq_obj {
u8 idx; /* array index */
u8 msix_idx;
u16 tx_budget;
u16 spurious_intr;
struct napi_struct napi;
struct be_adapter *adapter;
......@@ -248,6 +248,13 @@ struct be_tx_stats {
ulong tx_jiffies;
u32 tx_stops;
u32 tx_drv_drops; /* pkts dropped by driver */
/* the error counters are described in be_ethtool.c */
u32 tx_hdr_parse_err;
u32 tx_dma_err;
u32 tx_tso_err;
u32 tx_spoof_check_err;
u32 tx_qinq_err;
u32 tx_internal_parity_err;
struct u64_stats_sync sync;
struct u64_stats_sync sync_compl;
};
......@@ -316,6 +323,7 @@ struct be_rx_obj {
struct be_drv_stats {
u32 be_on_die_temperature;
u32 eth_red_drops;
u32 dma_map_errors;
u32 rx_drops_no_pbuf;
u32 rx_drops_no_txpb;
u32 rx_drops_no_erx_descr;
......@@ -613,6 +621,10 @@ extern const struct ethtool_ops be_ethtool_ops;
for (i = eqo->idx, rxo = &adapter->rx_obj[i]; i < adapter->num_rx_qs;\
i += adapter->num_evt_qs, rxo += adapter->num_evt_qs)
#define for_all_tx_queues_on_eq(adapter, eqo, txo, i) \
for (i = eqo->idx, txo = &adapter->tx_obj[i]; i < adapter->num_tx_qs;\
i += adapter->num_evt_qs, txo += adapter->num_evt_qs)
#define is_mcc_eqo(eqo) (eqo->idx == 0)
#define mcc_eqo(adapter) (&adapter->eq_obj[0])
......@@ -661,6 +673,18 @@ static inline u32 amap_get(void *ptr, u32 dw_offset, u32 mask, u32 offset)
amap_mask(sizeof(((_struct *)0)->field)), \
AMAP_BIT_OFFSET(_struct, field))
#define GET_RX_COMPL_V0_BITS(field, ptr) \
AMAP_GET_BITS(struct amap_eth_rx_compl_v0, field, ptr)
#define GET_RX_COMPL_V1_BITS(field, ptr) \
AMAP_GET_BITS(struct amap_eth_rx_compl_v1, field, ptr)
#define GET_TX_COMPL_BITS(field, ptr) \
AMAP_GET_BITS(struct amap_eth_tx_compl, field, ptr)
#define SET_TX_WRB_HDR_BITS(field, ptr, val) \
AMAP_SET_BITS(struct amap_eth_hdr_wrb, field, ptr, val)
#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)
......
......@@ -1681,17 +1681,17 @@ int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size)
return status;
}
void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf)
int be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf)
{
struct be_dma_mem get_fat_cmd;
struct be_mcc_wrb *wrb;
struct be_cmd_req_get_fat *req;
u32 offset = 0, total_size, buf_size,
log_offset = sizeof(u32), payload_len;
int status;
int status = 0;
if (buf_len == 0)
return;
return -EIO;
total_size = buf_len;
......@@ -1700,10 +1700,9 @@ void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf)
get_fat_cmd.size,
&get_fat_cmd.dma);
if (!get_fat_cmd.va) {
status = -ENOMEM;
dev_err(&adapter->pdev->dev,
"Memory allocation failure while retrieving FAT data\n");
return;
return -ENOMEM;
}
spin_lock_bh(&adapter->mcc_lock);
......@@ -1746,6 +1745,7 @@ void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf)
pci_free_consistent(adapter->pdev, get_fat_cmd.size,
get_fat_cmd.va, get_fat_cmd.dma);
spin_unlock_bh(&adapter->mcc_lock);
return status;
}
/* Uses synchronous mcc */
......@@ -1771,6 +1771,7 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter)
status = be_mcc_notify_wait(adapter);
if (!status) {
struct be_cmd_resp_get_fw_version *resp = embedded_payload(wrb);
strcpy(adapter->fw_ver, resp->firmware_version_string);
strcpy(adapter->fw_on_flash, resp->fw_on_flash_version_string);
}
......@@ -2018,6 +2019,9 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter)
adapter->function_mode = le32_to_cpu(resp->function_mode);
adapter->function_caps = le32_to_cpu(resp->function_caps);
adapter->asic_rev = le32_to_cpu(resp->asic_revision) & 0xFF;
dev_info(&adapter->pdev->dev,
"FW config: function_mode=0x%x, function_caps=0x%x\n",
adapter->function_mode, adapter->function_caps);
}
mutex_unlock(&adapter->mbox_lock);
......
......@@ -2101,7 +2101,7 @@ int be_cmd_get_die_temperature(struct be_adapter *adapter);
int be_cmd_get_cntl_attributes(struct be_adapter *adapter);
int be_cmd_req_native_mode(struct be_adapter *adapter);
int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size);
void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf);
int be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf);
int be_cmd_get_fn_privileges(struct be_adapter *adapter, u32 *privilege,
u32 domain);
int be_cmd_set_fn_privileges(struct be_adapter *adapter, u32 privileges,
......
......@@ -78,6 +78,11 @@ static const struct be_ethtool_stat et_stats[] = {
* fifo must never overflow.
*/
{DRVSTAT_INFO(rxpp_fifo_overflow_drop)},
/* Received packets dropped when the RX block runs out of space in
* one of its input FIFOs. This could happen due a long burst of
* minimum-sized (64b) frames in the receive path.
* This counter may also be erroneously incremented rarely.
*/
{DRVSTAT_INFO(rx_input_fifo_overflow_drop)},
{DRVSTAT_INFO(rx_ip_checksum_errs)},
{DRVSTAT_INFO(rx_tcp_checksum_errs)},
......@@ -114,6 +119,8 @@ static const struct be_ethtool_stat et_stats[] = {
* is more than 9018 bytes
*/
{DRVSTAT_INFO(rx_drops_mtu)},
/* Number of dma mapping errors */
{DRVSTAT_INFO(dma_map_errors)},
/* Number of packets dropped due to random early drop function */
{DRVSTAT_INFO(eth_red_drops)},
{DRVSTAT_INFO(be_on_die_temperature)},
......@@ -152,6 +159,34 @@ static const struct be_ethtool_stat et_rx_stats[] = {
*/
static const struct be_ethtool_stat et_tx_stats[] = {
{DRVSTAT_TX_INFO(tx_compl)}, /* If moving this member see above note */
/* This counter is incremented when the HW encounters an error while
* parsing the packet header of an outgoing TX request. This counter is
* applicable only for BE2, BE3 and Skyhawk based adapters.
*/
{DRVSTAT_TX_INFO(tx_hdr_parse_err)},
/* This counter is incremented when an error occurs in the DMA
* operation associated with the TX request from the host to the device.
*/
{DRVSTAT_TX_INFO(tx_dma_err)},
/* This counter is incremented when MAC or VLAN spoof checking is
* enabled on the interface and the TX request fails the spoof check
* in HW.
*/
{DRVSTAT_TX_INFO(tx_spoof_check_err)},
/* This counter is incremented when the HW encounters an error while
* performing TSO offload. This counter is applicable only for Lancer
* adapters.
*/
{DRVSTAT_TX_INFO(tx_tso_err)},
/* This counter is incremented when the HW detects Q-in-Q style VLAN
* tagging in a packet and such tagging is not expected on the outgoing
* interface. This counter is applicable only for Lancer adapters.
*/
{DRVSTAT_TX_INFO(tx_qinq_err)},
/* This counter is incremented when the HW detects parity errors in the
* packet data. This counter is applicable only for Lancer adapters.
*/
{DRVSTAT_TX_INFO(tx_internal_parity_err)},
{DRVSTAT_TX_INFO(tx_bytes)},
{DRVSTAT_TX_INFO(tx_pkts)},
/* Number of skbs queued for trasmission by the driver */
......
......@@ -315,6 +315,18 @@ struct be_eth_hdr_wrb {
u32 dw[4];
};
/********* Tx Compl Status Encoding *********/
#define BE_TX_COMP_HDR_PARSE_ERR 0x2
#define BE_TX_COMP_NDMA_ERR 0x3
#define BE_TX_COMP_ACL_ERR 0x5
#define LANCER_TX_COMP_LSO_ERR 0x1
#define LANCER_TX_COMP_HSW_DROP_MAC_ERR 0x3
#define LANCER_TX_COMP_HSW_DROP_VLAN_ERR 0x5
#define LANCER_TX_COMP_QINQ_ERR 0x7
#define LANCER_TX_COMP_PARITY_ERR 0xb
#define LANCER_TX_COMP_DMA_ERR 0xd
/* TX Compl Queue Descriptor */
/* Pseudo amap definition for eth_tx_compl in which each bit of the
......
......@@ -738,38 +738,37 @@ static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr,
memset(hdr, 0, sizeof(*hdr));
AMAP_SET_BITS(struct amap_eth_hdr_wrb, crc, hdr, 1);
SET_TX_WRB_HDR_BITS(crc, hdr, 1);
if (skb_is_gso(skb)) {
AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso, hdr, 1);
AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso_mss,
hdr, skb_shinfo(skb)->gso_size);
SET_TX_WRB_HDR_BITS(lso, hdr, 1);
SET_TX_WRB_HDR_BITS(lso_mss, hdr, skb_shinfo(skb)->gso_size);
if (skb_is_gso_v6(skb) && !lancer_chip(adapter))
AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso6, hdr, 1);
SET_TX_WRB_HDR_BITS(lso6, hdr, 1);
} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
if (skb->encapsulation) {
AMAP_SET_BITS(struct amap_eth_hdr_wrb, ipcs, hdr, 1);
SET_TX_WRB_HDR_BITS(ipcs, hdr, 1);
proto = skb_inner_ip_proto(skb);
} else {
proto = skb_ip_proto(skb);
}
if (proto == IPPROTO_TCP)
AMAP_SET_BITS(struct amap_eth_hdr_wrb, tcpcs, hdr, 1);
SET_TX_WRB_HDR_BITS(tcpcs, hdr, 1);
else if (proto == IPPROTO_UDP)
AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1);
SET_TX_WRB_HDR_BITS(udpcs, hdr, 1);
}
if (vlan_tx_tag_present(skb)) {
AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1);
SET_TX_WRB_HDR_BITS(vlan, hdr, 1);
vlan_tag = be_get_tx_vlan_tag(adapter, skb);
AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag, hdr, vlan_tag);
SET_TX_WRB_HDR_BITS(vlan_tag, hdr, vlan_tag);
}
/* To skip HW VLAN tagging: evt = 1, compl = 0 */
AMAP_SET_BITS(struct amap_eth_hdr_wrb, complete, hdr, !skip_hw_vlan);
AMAP_SET_BITS(struct amap_eth_hdr_wrb, event, hdr, 1);
AMAP_SET_BITS(struct amap_eth_hdr_wrb, num_wrb, hdr, wrb_cnt);
AMAP_SET_BITS(struct amap_eth_hdr_wrb, len, hdr, len);
SET_TX_WRB_HDR_BITS(complete, hdr, !skip_hw_vlan);
SET_TX_WRB_HDR_BITS(event, hdr, 1);
SET_TX_WRB_HDR_BITS(num_wrb, hdr, wrb_cnt);
SET_TX_WRB_HDR_BITS(len, hdr, len);
}
static void unmap_tx_frag(struct device *dev, struct be_eth_wrb *wrb,
......@@ -850,6 +849,7 @@ static int make_tx_wrbs(struct be_adapter *adapter, struct be_queue_info *txq,
unmap_tx_frag(dev, wrb, map_single);
map_single = false;
copied -= wrb->frag_len;
adapter->drv_stats.dma_map_errors++;
queue_head_inc(txq);
}
return 0;
......@@ -1073,15 +1073,15 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev)
static int be_change_mtu(struct net_device *netdev, int new_mtu)
{
struct be_adapter *adapter = netdev_priv(netdev);
if (new_mtu < BE_MIN_MTU ||
new_mtu > (BE_MAX_JUMBO_FRAME_SIZE - (ETH_HLEN + ETH_FCS_LEN))) {
dev_info(&adapter->pdev->dev,
"MTU must be between %d and %d bytes\n",
BE_MIN_MTU,
(BE_MAX_JUMBO_FRAME_SIZE - (ETH_HLEN + ETH_FCS_LEN)));
struct device *dev = &adapter->pdev->dev;
if (new_mtu < BE_MIN_MTU || new_mtu > BE_MAX_MTU) {
dev_info(dev, "MTU must be between %d and %d bytes\n",
BE_MIN_MTU, BE_MAX_MTU);
return -EINVAL;
}
dev_info(&adapter->pdev->dev, "MTU changed from %d to %d bytes\n",
dev_info(dev, "MTU changed from %d to %d bytes\n",
netdev->mtu, new_mtu);
netdev->mtu = new_mtu;
return 0;
......@@ -1753,65 +1753,46 @@ static void be_rx_compl_process_gro(struct be_rx_obj *rxo,
static void be_parse_rx_compl_v1(struct be_eth_rx_compl *compl,
struct be_rx_compl_info *rxcp)
{
rxcp->pkt_size =
AMAP_GET_BITS(struct amap_eth_rx_compl_v1, pktsize, compl);
rxcp->vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtp, compl);
rxcp->err = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, err, compl);
rxcp->tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, tcpf, compl);
rxcp->udpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, udpf, compl);
rxcp->ip_csum =
AMAP_GET_BITS(struct amap_eth_rx_compl_v1, ipcksm, compl);
rxcp->l4_csum =
AMAP_GET_BITS(struct amap_eth_rx_compl_v1, l4_cksm, compl);
rxcp->ipv6 =
AMAP_GET_BITS(struct amap_eth_rx_compl_v1, ip_version, compl);
rxcp->num_rcvd =
AMAP_GET_BITS(struct amap_eth_rx_compl_v1, numfrags, compl);
rxcp->pkt_type =
AMAP_GET_BITS(struct amap_eth_rx_compl_v1, cast_enc, compl);
rxcp->rss_hash =
AMAP_GET_BITS(struct amap_eth_rx_compl_v1, rsshash, compl);
rxcp->pkt_size = GET_RX_COMPL_V1_BITS(pktsize, compl);
rxcp->vlanf = GET_RX_COMPL_V1_BITS(vtp, compl);
rxcp->err = GET_RX_COMPL_V1_BITS(err, compl);
rxcp->tcpf = GET_RX_COMPL_V1_BITS(tcpf, compl);
rxcp->udpf = GET_RX_COMPL_V1_BITS(udpf, compl);
rxcp->ip_csum = GET_RX_COMPL_V1_BITS(ipcksm, compl);
rxcp->l4_csum = GET_RX_COMPL_V1_BITS(l4_cksm, compl);
rxcp->ipv6 = GET_RX_COMPL_V1_BITS(ip_version, compl);
rxcp->num_rcvd = GET_RX_COMPL_V1_BITS(numfrags, compl);
rxcp->pkt_type = GET_RX_COMPL_V1_BITS(cast_enc, compl);
rxcp->rss_hash = GET_RX_COMPL_V1_BITS(rsshash, compl);
if (rxcp->vlanf) {
rxcp->qnq = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, qnq,
compl);
rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v1,
vlan_tag, compl);
rxcp->qnq = GET_RX_COMPL_V1_BITS(qnq, compl);
rxcp->vlan_tag = GET_RX_COMPL_V1_BITS(vlan_tag, compl);
}
rxcp->port = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, port, compl);
rxcp->port = GET_RX_COMPL_V1_BITS(port, compl);
rxcp->tunneled =
AMAP_GET_BITS(struct amap_eth_rx_compl_v1, tunneled, compl);
GET_RX_COMPL_V1_BITS(tunneled, compl);
}
static void be_parse_rx_compl_v0(struct be_eth_rx_compl *compl,
struct be_rx_compl_info *rxcp)
{
rxcp->pkt_size =
AMAP_GET_BITS(struct amap_eth_rx_compl_v0, pktsize, compl);
rxcp->vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtp, compl);
rxcp->err = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, err, compl);
rxcp->tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, tcpf, compl);
rxcp->udpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, udpf, compl);
rxcp->ip_csum =
AMAP_GET_BITS(struct amap_eth_rx_compl_v0, ipcksm, compl);
rxcp->l4_csum =
AMAP_GET_BITS(struct amap_eth_rx_compl_v0, l4_cksm, compl);
rxcp->ipv6 =
AMAP_GET_BITS(struct amap_eth_rx_compl_v0, ip_version, compl);
rxcp->num_rcvd =
AMAP_GET_BITS(struct amap_eth_rx_compl_v0, numfrags, compl);
rxcp->pkt_type =
AMAP_GET_BITS(struct amap_eth_rx_compl_v0, cast_enc, compl);
rxcp->rss_hash =
AMAP_GET_BITS(struct amap_eth_rx_compl_v0, rsshash, compl);
rxcp->pkt_size = GET_RX_COMPL_V0_BITS(pktsize, compl);
rxcp->vlanf = GET_RX_COMPL_V0_BITS(vtp, compl);
rxcp->err = GET_RX_COMPL_V0_BITS(err, compl);
rxcp->tcpf = GET_RX_COMPL_V0_BITS(tcpf, compl);
rxcp->udpf = GET_RX_COMPL_V0_BITS(udpf, compl);
rxcp->ip_csum = GET_RX_COMPL_V0_BITS(ipcksm, compl);
rxcp->l4_csum = GET_RX_COMPL_V0_BITS(l4_cksm, compl);
rxcp->ipv6 = GET_RX_COMPL_V0_BITS(ip_version, compl);
rxcp->num_rcvd = GET_RX_COMPL_V0_BITS(numfrags, compl);
rxcp->pkt_type = GET_RX_COMPL_V0_BITS(cast_enc, compl);
rxcp->rss_hash = GET_RX_COMPL_V0_BITS(rsshash, compl);
if (rxcp->vlanf) {
rxcp->qnq = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, qnq,
compl);
rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0,
vlan_tag, compl);
rxcp->qnq = GET_RX_COMPL_V0_BITS(qnq, compl);
rxcp->vlan_tag = GET_RX_COMPL_V0_BITS(vlan_tag, compl);
}
rxcp->port = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, port, compl);
rxcp->ip_frag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0,
ip_frag, compl);
rxcp->port = GET_RX_COMPL_V0_BITS(port, compl);
rxcp->ip_frag = GET_RX_COMPL_V0_BITS(ip_frag, compl);
}
static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo)
......@@ -1897,7 +1878,7 @@ static void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp)
if (dma_mapping_error(dev, page_dmaaddr)) {
put_page(pagep);
pagep = NULL;
rx_stats(rxo)->rx_post_fail++;
adapter->drv_stats.dma_map_errors++;
break;
}
page_offset = 0;
......@@ -2091,9 +2072,7 @@ static void be_tx_compl_clean(struct be_adapter *adapter)
num_wrbs = 0;
txq = &txo->q;
while ((txcp = be_tx_compl_get(&txo->cq))) {
end_idx =
AMAP_GET_BITS(struct amap_eth_tx_compl,
wrb_index, txcp);
end_idx = GET_TX_COMPL_BITS(wrb_index, txcp);
num_wrbs += be_tx_compl_process(adapter, txo,
end_idx);
cmpl++;
......@@ -2164,7 +2143,6 @@ static int be_evt_queues_create(struct be_adapter *adapter)
napi_hash_add(&eqo->napi);
aic = &adapter->aic_obj[i];
eqo->adapter = adapter;
eqo->tx_budget = BE_TX_BUDGET;
eqo->idx = i;
aic->max_eqd = BE_MAX_EQD;
aic->enable = true;
......@@ -2443,20 +2421,63 @@ static int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi,
return work_done;
}
static bool be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo,
int budget, int idx)
static inline void be_update_tx_err(struct be_tx_obj *txo, u32 status)
{
struct be_eth_tx_compl *txcp;
int num_wrbs = 0, work_done;
switch (status) {
case BE_TX_COMP_HDR_PARSE_ERR:
tx_stats(txo)->tx_hdr_parse_err++;
break;
case BE_TX_COMP_NDMA_ERR:
tx_stats(txo)->tx_dma_err++;
break;
case BE_TX_COMP_ACL_ERR:
tx_stats(txo)->tx_spoof_check_err++;
break;
}
}
for (work_done = 0; work_done < budget; work_done++) {
txcp = be_tx_compl_get(&txo->cq);
if (!txcp)
static inline void lancer_update_tx_err(struct be_tx_obj *txo, u32 status)
{
switch (status) {
case LANCER_TX_COMP_LSO_ERR:
tx_stats(txo)->tx_tso_err++;
break;
case LANCER_TX_COMP_HSW_DROP_MAC_ERR:
case LANCER_TX_COMP_HSW_DROP_VLAN_ERR:
tx_stats(txo)->tx_spoof_check_err++;
break;
case LANCER_TX_COMP_QINQ_ERR:
tx_stats(txo)->tx_qinq_err++;
break;
case LANCER_TX_COMP_PARITY_ERR:
tx_stats(txo)->tx_internal_parity_err++;
break;
case LANCER_TX_COMP_DMA_ERR:
tx_stats(txo)->tx_dma_err++;
break;
num_wrbs += be_tx_compl_process(adapter, txo,
AMAP_GET_BITS(struct
amap_eth_tx_compl,
wrb_index, txcp));
}
}
static void be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo,
int idx)
{
struct be_eth_tx_compl *txcp;
int num_wrbs = 0, work_done = 0;
u32 compl_status;
u16 last_idx;
while ((txcp = be_tx_compl_get(&txo->cq))) {
last_idx = GET_TX_COMPL_BITS(wrb_index, txcp);
num_wrbs += be_tx_compl_process(adapter, txo, last_idx);
work_done++;
compl_status = GET_TX_COMPL_BITS(status, txcp);
if (compl_status) {
if (lancer_chip(adapter))
lancer_update_tx_err(txo, compl_status);
else
be_update_tx_err(txo, compl_status);
}
}
if (work_done) {
......@@ -2474,7 +2495,6 @@ static bool be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo,
tx_stats(txo)->tx_compl += work_done;
u64_stats_update_end(&tx_stats(txo)->sync_compl);
}
return (work_done < budget); /* Done */
}
int be_poll(struct napi_struct *napi, int budget)
......@@ -2483,17 +2503,12 @@ int be_poll(struct napi_struct *napi, int budget)
struct be_adapter *adapter = eqo->adapter;
int max_work = 0, work, i, num_evts;
struct be_rx_obj *rxo;
bool tx_done;
struct be_tx_obj *txo;
num_evts = events_get(eqo);
/* Process all TXQs serviced by this EQ */
for (i = eqo->idx; i < adapter->num_tx_qs; i += adapter->num_evt_qs) {
tx_done = be_process_tx(adapter, &adapter->tx_obj[i],
eqo->tx_budget, i);
if (!tx_done)
max_work = budget;
}
for_all_tx_queues_on_eq(adapter, eqo, txo, i)
be_process_tx(adapter, txo, i);
if (be_lock_napi(eqo)) {
/* This loop will iterate twice for EQ0 in which
......@@ -3309,10 +3324,20 @@ static void BEx_get_resources(struct be_adapter *adapter,
*/
if (BE2_chip(adapter) || use_sriov || (adapter->port_num > 1) ||
!be_physfn(adapter) || (be_is_mc(adapter) &&
!(adapter->function_caps & BE_FUNCTION_CAPS_RSS)))
!(adapter->function_caps & BE_FUNCTION_CAPS_RSS))) {
res->max_tx_qs = 1;
else
} else if (adapter->function_caps & BE_FUNCTION_CAPS_SUPER_NIC) {
struct be_resources super_nic_res = {0};
/* On a SuperNIC profile, the driver needs to use the
* GET_PROFILE_CONFIG cmd to query the per-function TXQ limits
*/
be_cmd_get_profile_config(adapter, &super_nic_res, 0);
/* Some old versions of BE3 FW don't report max_tx_qs value */
res->max_tx_qs = super_nic_res.max_tx_qs ? : BE3_MAX_TX_QS;
} else {
res->max_tx_qs = BE3_MAX_TX_QS;
}
if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
!use_sriov && be_physfn(adapter))
......@@ -3413,6 +3438,7 @@ static int be_get_resources(struct be_adapter *adapter)
if (be_roce_supported(adapter))
res.max_evt_qs /= 2;
adapter->res = res;
}
dev_info(dev, "Max: txqs %d, rxqs %d, rss %d, eqs %d, vfs %d\n",
be_max_txqs(adapter), be_max_rxqs(adapter),
......@@ -3421,7 +3447,6 @@ static int be_get_resources(struct be_adapter *adapter)
dev_info(dev, "Max: uc-macs %d, mc-macs %d, vlans %d\n",
be_max_uc(adapter), be_max_mc(adapter),
be_max_vlans(adapter));
}
return 0;
}
......@@ -3633,6 +3658,7 @@ static int be_setup(struct be_adapter *adapter)
goto err;
be_cmd_get_fw_ver(adapter);
dev_info(dev, "FW version is %s\n", adapter->fw_ver);
if (BE2_chip(adapter) && fw_major_num(adapter->fw_ver) < 4) {
dev_err(dev, "Firmware on card is old(%s), IRQs may not work.",
......@@ -4052,6 +4078,7 @@ static int lancer_fw_download(struct be_adapter *adapter,
{
#define LANCER_FW_DOWNLOAD_CHUNK (32 * 1024)
#define LANCER_FW_DOWNLOAD_LOCATION "/prg"
struct device *dev = &adapter->pdev->dev;
struct be_dma_mem flash_cmd;
const u8 *data_ptr = NULL;
u8 *dest_image_ptr = NULL;
......@@ -4064,21 +4091,16 @@ static int lancer_fw_download(struct be_adapter *adapter,
u8 change_status;
if (!IS_ALIGNED(fw->size, sizeof(u32))) {
dev_err(&adapter->pdev->dev,
"FW Image not properly aligned. "
"Length must be 4 byte aligned.\n");
status = -EINVAL;
goto lancer_fw_exit;
dev_err(dev, "FW image size should be multiple of 4\n");
return -EINVAL;
}
flash_cmd.size = sizeof(struct lancer_cmd_req_write_object)
+ LANCER_FW_DOWNLOAD_CHUNK;
flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size,
flash_cmd.va = dma_alloc_coherent(dev, flash_cmd.size,
&flash_cmd.dma, GFP_KERNEL);
if (!flash_cmd.va) {
status = -ENOMEM;
goto lancer_fw_exit;
}
if (!flash_cmd.va)
return -ENOMEM;
dest_image_ptr = flash_cmd.va +
sizeof(struct lancer_cmd_req_write_object);
......@@ -4113,35 +4135,27 @@ static int lancer_fw_download(struct be_adapter *adapter,
&add_status);
}
dma_free_coherent(&adapter->pdev->dev, flash_cmd.size, flash_cmd.va,
flash_cmd.dma);
dma_free_coherent(dev, flash_cmd.size, flash_cmd.va, flash_cmd.dma);
if (status) {
dev_err(&adapter->pdev->dev,
"Firmware load error. "
"Status code: 0x%x Additional Status: 0x%x\n",
status, add_status);
goto lancer_fw_exit;
dev_err(dev, "Firmware load error\n");
return be_cmd_status(status);
}
dev_info(dev, "Firmware flashed successfully\n");
if (change_status == LANCER_FW_RESET_NEEDED) {
dev_info(&adapter->pdev->dev,
"Resetting adapter to activate new FW\n");
dev_info(dev, "Resetting adapter to activate new FW\n");
status = lancer_physdev_ctrl(adapter,
PHYSDEV_CONTROL_FW_RESET_MASK);
if (status) {
dev_err(&adapter->pdev->dev,
"Adapter busy for FW reset.\n"
"New FW will not be active.\n");
goto lancer_fw_exit;
dev_err(dev, "Adapter busy, could not reset FW\n");
dev_err(dev, "Reboot server to activate new FW\n");
}
} else if (change_status != LANCER_NO_RESET_NEEDED) {
dev_err(&adapter->pdev->dev,
"System reboot required for new FW to be active\n");
dev_info(dev, "Reboot server to activate new FW\n");
}
dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n");
lancer_fw_exit:
return status;
return 0;
}
#define UFI_TYPE2 2
......@@ -4506,6 +4520,7 @@ static int be_map_pci_bars(struct be_adapter *adapter)
return 0;
pci_map_err:
dev_err(&adapter->pdev->dev, "Error in mapping PCI BARs\n");
be_unmap_pci_bars(adapter);
return -ENOMEM;
}
......@@ -4822,6 +4837,8 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id)
struct net_device *netdev;
char port_name;
dev_info(&pdev->dev, "%s version is %s\n", DRV_NAME, DRV_VER);
status = pci_enable_device(pdev);
if (status)
goto do_none;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment