Commit a5c66b57 authored by David S. Miller's avatar David S. Miller

Merge branch 'bnxt_en-Misc-updates-for-net-next'

Michael Chan says:

====================
bnxt_en: Misc. updates for net-next.

The 1st 2 patches add short firmware message support for new VF devices.
The 3rd patch adds a pci shutdown callback for the RDMA driver for proper
shutdown.  The next 3 patches improve the doorbell operations by
elimiating the double doorbell workaround on newer chips, and by adding
xmit_more support.  The last patch adds a parameter to bnxt_set_dflt_rings().
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e6cbef0c 702c221c
......@@ -175,6 +175,8 @@ static const struct pci_device_id bnxt_pci_tbl[] = {
{ PCI_VDEVICE(BROADCOM, 0x16f1), .driver_data = BCM57452 },
{ PCI_VDEVICE(BROADCOM, 0x1614), .driver_data = BCM57454 },
#ifdef CONFIG_BNXT_SRIOV
{ PCI_VDEVICE(BROADCOM, 0x1606), .driver_data = NETXTREME_E_VF },
{ PCI_VDEVICE(BROADCOM, 0x1609), .driver_data = NETXTREME_E_VF },
{ PCI_VDEVICE(BROADCOM, 0x16c1), .driver_data = NETXTREME_E_VF },
{ PCI_VDEVICE(BROADCOM, 0x16cb), .driver_data = NETXTREME_C_VF },
{ PCI_VDEVICE(BROADCOM, 0x16d3), .driver_data = NETXTREME_E_VF },
......@@ -461,14 +463,17 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
prod = NEXT_TX(prod);
txr->tx_prod = prod;
writel(DB_KEY_TX | prod, txr->tx_doorbell);
writel(DB_KEY_TX | prod, txr->tx_doorbell);
if (!skb->xmit_more)
bnxt_db_write(bp, txr->tx_doorbell, DB_KEY_TX | prod);
tx_done:
mmiowb();
if (unlikely(bnxt_tx_avail(bp, txr) <= MAX_SKB_FRAGS + 1)) {
if (skb->xmit_more && !tx_buf->is_push)
bnxt_db_write(bp, txr->tx_doorbell, DB_KEY_TX | prod);
netif_tx_stop_queue(txq);
/* netif_tx_stop_queue() must be done before checking
......@@ -1777,8 +1782,7 @@ static int bnxt_poll_work(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)
/* Sync BD data before updating doorbell */
wmb();
writel(DB_KEY_TX | prod, db);
writel(DB_KEY_TX | prod, db);
bnxt_db_write(bp, db, DB_KEY_TX | prod);
}
cpr->cp_raw_cons = raw_cons;
......@@ -1794,14 +1798,10 @@ static int bnxt_poll_work(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)
if (event & BNXT_RX_EVENT) {
struct bnxt_rx_ring_info *rxr = bnapi->rx_ring;
writel(DB_KEY_RX | rxr->rx_prod, rxr->rx_doorbell);
writel(DB_KEY_RX | rxr->rx_prod, rxr->rx_doorbell);
if (event & BNXT_AGG_EVENT) {
writel(DB_KEY_RX | rxr->rx_agg_prod,
rxr->rx_agg_doorbell);
writel(DB_KEY_RX | rxr->rx_agg_prod,
rxr->rx_agg_doorbell);
}
bnxt_db_write(bp, rxr->rx_doorbell, DB_KEY_RX | rxr->rx_prod);
if (event & BNXT_AGG_EVENT)
bnxt_db_write(bp, rxr->rx_agg_doorbell,
DB_KEY_RX | rxr->rx_agg_prod);
}
return rx_pkts;
}
......@@ -1861,13 +1861,11 @@ static int bnxt_poll_nitroa0(struct napi_struct *napi, int budget)
cpr->cp_raw_cons = raw_cons;
BNXT_CP_DB(cpr->cp_doorbell, cpr->cp_raw_cons);
writel(DB_KEY_RX | rxr->rx_prod, rxr->rx_doorbell);
writel(DB_KEY_RX | rxr->rx_prod, rxr->rx_doorbell);
bnxt_db_write(bp, rxr->rx_doorbell, DB_KEY_RX | rxr->rx_prod);
if (event & BNXT_AGG_EVENT) {
writel(DB_KEY_RX | rxr->rx_agg_prod, rxr->rx_agg_doorbell);
writel(DB_KEY_RX | rxr->rx_agg_prod, rxr->rx_agg_doorbell);
}
if (event & BNXT_AGG_EVENT)
bnxt_db_write(bp, rxr->rx_agg_doorbell,
DB_KEY_RX | rxr->rx_agg_prod);
if (!bnxt_has_work(bp, cpr) && rx_pkts < budget) {
napi_complete_done(napi, rx_pkts);
......@@ -2868,6 +2866,32 @@ static int bnxt_alloc_hwrm_resources(struct bnxt *bp)
return 0;
}
static void bnxt_free_hwrm_short_cmd_req(struct bnxt *bp)
{
if (bp->hwrm_short_cmd_req_addr) {
struct pci_dev *pdev = bp->pdev;
dma_free_coherent(&pdev->dev, BNXT_HWRM_MAX_REQ_LEN,
bp->hwrm_short_cmd_req_addr,
bp->hwrm_short_cmd_req_dma_addr);
bp->hwrm_short_cmd_req_addr = NULL;
}
}
static int bnxt_alloc_hwrm_short_cmd_req(struct bnxt *bp)
{
struct pci_dev *pdev = bp->pdev;
bp->hwrm_short_cmd_req_addr =
dma_alloc_coherent(&pdev->dev, BNXT_HWRM_MAX_REQ_LEN,
&bp->hwrm_short_cmd_req_dma_addr,
GFP_KERNEL);
if (!bp->hwrm_short_cmd_req_addr)
return -ENOMEM;
return 0;
}
static void bnxt_free_stats(struct bnxt *bp)
{
u32 size, i;
......@@ -3215,16 +3239,41 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
__le32 *resp_len, *valid;
u16 cp_ring_id, len = 0;
struct hwrm_err_output *resp = bp->hwrm_cmd_resp_addr;
u16 max_req_len = BNXT_HWRM_MAX_REQ_LEN;
req->seq_id = cpu_to_le16(bp->hwrm_cmd_seq++);
memset(resp, 0, PAGE_SIZE);
cp_ring_id = le16_to_cpu(req->cmpl_ring);
intr_process = (cp_ring_id == INVALID_HW_RING_ID) ? 0 : 1;
if (bp->flags & BNXT_FLAG_SHORT_CMD) {
void *short_cmd_req = bp->hwrm_short_cmd_req_addr;
struct hwrm_short_input short_input = {0};
memcpy(short_cmd_req, req, msg_len);
memset(short_cmd_req + msg_len, 0, BNXT_HWRM_MAX_REQ_LEN -
msg_len);
short_input.req_type = req->req_type;
short_input.signature =
cpu_to_le16(SHORT_REQ_SIGNATURE_SHORT_CMD);
short_input.size = cpu_to_le16(msg_len);
short_input.req_addr =
cpu_to_le64(bp->hwrm_short_cmd_req_dma_addr);
data = (u32 *)&short_input;
msg_len = sizeof(short_input);
/* Sync memory write before updating doorbell */
wmb();
max_req_len = BNXT_HWRM_SHORT_REQ_LEN;
}
/* Write request msg to hwrm channel */
__iowrite32_copy(bp->bar0, data, msg_len / 4);
for (i = msg_len; i < BNXT_HWRM_MAX_REQ_LEN; i += 4)
for (i = msg_len; i < max_req_len; i += 4)
writel(0, bp->bar0 + i);
/* currently supports only one outstanding message */
......@@ -4662,6 +4711,7 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp)
int rc;
struct hwrm_ver_get_input req = {0};
struct hwrm_ver_get_output *resp = bp->hwrm_cmd_resp_addr;
u32 dev_caps_cfg;
bp->hwrm_max_req_len = HWRM_MAX_REQ_LEN;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_VER_GET, -1, -1);
......@@ -4699,6 +4749,11 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp)
!resp->chip_metal)
bp->flags |= BNXT_FLAG_CHIP_NITRO_A0;
dev_caps_cfg = le32_to_cpu(resp->dev_caps_cfg);
if ((dev_caps_cfg & VER_GET_RESP_DEV_CAPS_CFG_SHORT_CMD_SUPPORTED) &&
(dev_caps_cfg & VER_GET_RESP_DEV_CAPS_CFG_SHORT_CMD_REQUIRED))
bp->flags |= BNXT_FLAG_SHORT_CMD;
hwrm_ver_get_exit:
mutex_unlock(&bp->hwrm_cmd_lock);
return rc;
......@@ -7357,6 +7412,7 @@ static void bnxt_remove_one(struct pci_dev *pdev)
bnxt_clear_int_mode(bp);
bnxt_hwrm_func_drv_unrgtr(bp);
bnxt_free_hwrm_resources(bp);
bnxt_free_hwrm_short_cmd_req(bp);
bnxt_ethtool_free(bp);
bnxt_dcb_free(bp);
kfree(bp->edev);
......@@ -7511,10 +7567,9 @@ static int bnxt_get_dflt_rings(struct bnxt *bp, int *max_rx, int *max_tx,
return rc;
}
static int bnxt_set_dflt_rings(struct bnxt *bp)
static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
{
int dflt_rings, max_rx_rings, max_tx_rings, rc;
bool sh = true;
if (sh)
bp->flags |= BNXT_FLAG_SHARED_RINGS;
......@@ -7607,6 +7662,12 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc)
goto init_err_pci_clean;
if (bp->flags & BNXT_FLAG_SHORT_CMD) {
rc = bnxt_alloc_hwrm_short_cmd_req(bp);
if (rc)
goto init_err_pci_clean;
}
rc = bnxt_hwrm_func_reset(bp);
if (rc)
goto init_err_pci_clean;
......@@ -7646,8 +7707,10 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
init_waitqueue_head(&bp->sriov_cfg_wait);
#endif
bp->gro_func = bnxt_gro_func_5730x;
if (BNXT_CHIP_NUM_57X1X(bp->chip_num))
if (BNXT_CHIP_P4_PLUS(bp))
bp->gro_func = bnxt_gro_func_5731x;
else
bp->flags |= BNXT_FLAG_DOUBLE_DB;
rc = bnxt_hwrm_func_drv_rgtr(bp);
if (rc)
......@@ -7685,7 +7748,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
bnxt_set_tpa_flags(bp);
bnxt_set_ring_params(bp);
bnxt_set_max_func_irqs(bp, max_irqs);
rc = bnxt_set_dflt_rings(bp);
rc = bnxt_set_dflt_rings(bp, true);
if (rc) {
netdev_err(bp->dev, "Not enough rings available.\n");
rc = -ENOMEM;
......@@ -7697,9 +7760,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV4 |
VNIC_RSS_CFG_REQ_HASH_TYPE_IPV6 |
VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV6;
if (!BNXT_CHIP_NUM_57X0X(bp->chip_num) &&
!BNXT_CHIP_TYPE_NITRO_A0(bp) &&
bp->hwrm_spec_code >= 0x10501) {
if (BNXT_CHIP_P4_PLUS(bp) && bp->hwrm_spec_code >= 0x10501) {
bp->flags |= BNXT_FLAG_UDP_RSS_CAP;
bp->rss_hash_cfg |= VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV4 |
VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV6;
......@@ -7771,6 +7832,7 @@ static void bnxt_shutdown(struct pci_dev *pdev)
dev_close(dev);
if (system_state == SYSTEM_POWER_OFF) {
bnxt_ulp_shutdown(bp);
bnxt_clear_int_mode(bp);
pci_wake_from_d3(pdev, bp->wol);
pci_set_power_state(pdev, PCI_D3hot);
......
......@@ -500,6 +500,7 @@ struct rx_tpa_end_cmp_ext {
#define NEXT_CMP(idx) RING_CMP(ADV_RAW_CMP(idx, 1))
#define BNXT_HWRM_MAX_REQ_LEN (bp->hwrm_max_req_len)
#define BNXT_HWRM_SHORT_REQ_LEN sizeof(struct hwrm_short_input)
#define DFLT_HWRM_CMD_TIMEOUT 500
#define HWRM_CMD_TIMEOUT (bp->hwrm_cmd_timeout)
#define HWRM_RESET_TIMEOUT ((HWRM_CMD_TIMEOUT) * 4)
......@@ -937,31 +938,45 @@ struct bnxt {
#define CHIP_NUM_57402 0x16d0
#define CHIP_NUM_57404 0x16d1
#define CHIP_NUM_57406 0x16d2
#define CHIP_NUM_57407 0x16d5
#define CHIP_NUM_57311 0x16ce
#define CHIP_NUM_57312 0x16cf
#define CHIP_NUM_57314 0x16df
#define CHIP_NUM_57317 0x16e0
#define CHIP_NUM_57412 0x16d6
#define CHIP_NUM_57414 0x16d7
#define CHIP_NUM_57416 0x16d8
#define CHIP_NUM_57417 0x16d9
#define CHIP_NUM_57412L 0x16da
#define CHIP_NUM_57414L 0x16db
#define CHIP_NUM_5745X 0xd730
#define BNXT_CHIP_NUM_5730X(chip_num) \
((chip_num) >= CHIP_NUM_57301 && \
(chip_num) <= CHIP_NUM_57304)
#define BNXT_CHIP_NUM_5740X(chip_num) \
((chip_num) >= CHIP_NUM_57402 && \
(chip_num) <= CHIP_NUM_57406)
(((chip_num) >= CHIP_NUM_57402 && \
(chip_num) <= CHIP_NUM_57406) || \
(chip_num) == CHIP_NUM_57407)
#define BNXT_CHIP_NUM_5731X(chip_num) \
((chip_num) == CHIP_NUM_57311 || \
(chip_num) == CHIP_NUM_57312 || \
(chip_num) == CHIP_NUM_57314)
(chip_num) == CHIP_NUM_57314 || \
(chip_num) == CHIP_NUM_57317)
#define BNXT_CHIP_NUM_5741X(chip_num) \
((chip_num) >= CHIP_NUM_57412 && \
(chip_num) <= CHIP_NUM_57417)
(chip_num) <= CHIP_NUM_57414L)
#define BNXT_CHIP_NUM_58700(chip_num) \
((chip_num) == CHIP_NUM_58700)
#define BNXT_CHIP_NUM_5745X(chip_num) \
((chip_num) == CHIP_NUM_5745X)
#define BNXT_CHIP_NUM_57X0X(chip_num) \
(BNXT_CHIP_NUM_5730X(chip_num) || BNXT_CHIP_NUM_5740X(chip_num))
......@@ -1006,6 +1021,8 @@ struct bnxt {
#define BNXT_FLAG_RX_PAGE_MODE 0x40000
#define BNXT_FLAG_FW_LLDP_AGENT 0x80000
#define BNXT_FLAG_MULTI_HOST 0x100000
#define BNXT_FLAG_SHORT_CMD 0x200000
#define BNXT_FLAG_DOUBLE_DB 0x400000
#define BNXT_FLAG_CHIP_NITRO_A0 0x1000000
#define BNXT_FLAG_ALL_CONFIG_FEATS (BNXT_FLAG_TPA | \
......@@ -1020,6 +1037,13 @@ struct bnxt {
#define BNXT_CHIP_TYPE_NITRO_A0(bp) ((bp)->flags & BNXT_FLAG_CHIP_NITRO_A0)
#define BNXT_RX_PAGE_MODE(bp) ((bp)->flags & BNXT_FLAG_RX_PAGE_MODE)
/* Chip class phase 4 and later */
#define BNXT_CHIP_P4_PLUS(bp) \
(BNXT_CHIP_NUM_57X1X((bp)->chip_num) || \
BNXT_CHIP_NUM_5745X((bp)->chip_num) || \
(BNXT_CHIP_NUM_58700((bp)->chip_num) && \
!BNXT_CHIP_TYPE_NITRO_A0(bp)))
struct bnxt_en_dev *edev;
struct bnxt_en_dev * (*ulp_probe)(struct net_device *);
......@@ -1106,6 +1130,8 @@ struct bnxt {
u32 hwrm_spec_code;
u16 hwrm_cmd_seq;
u32 hwrm_intr_seq_id;
void *hwrm_short_cmd_req_addr;
dma_addr_t hwrm_short_cmd_req_dma_addr;
void *hwrm_cmd_resp_addr;
dma_addr_t hwrm_cmd_resp_dma_addr;
void *hwrm_dbg_resp_addr;
......@@ -1229,6 +1255,14 @@ static inline u32 bnxt_tx_avail(struct bnxt *bp, struct bnxt_tx_ring_info *txr)
((txr->tx_prod - txr->tx_cons) & bp->tx_ring_mask);
}
/* For TX and RX ring doorbells */
static inline void bnxt_db_write(struct bnxt *bp, void __iomem *db, u32 val)
{
writel(val, db);
if (bp->flags & BNXT_FLAG_DOUBLE_DB)
writel(val, db);
}
extern const u16 bnxt_lhint_arr[];
int bnxt_alloc_rx_data(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
......
......@@ -2376,8 +2376,7 @@ static int bnxt_run_loopback(struct bnxt *bp)
/* Sync BD data before updating doorbell */
wmb();
writel(DB_KEY_TX | txr->tx_prod, txr->tx_doorbell);
writel(DB_KEY_TX | txr->tx_prod, txr->tx_doorbell);
bnxt_db_write(bp, txr->tx_doorbell, DB_KEY_TX | txr->tx_prod);
rc = bnxt_poll_loopback(bp, pkt_size);
dma_unmap_single(&bp->pdev->dev, map, pkt_size, PCI_DMA_TODEVICE);
......
......@@ -266,6 +266,25 @@ void bnxt_ulp_sriov_cfg(struct bnxt *bp, int num_vfs)
}
}
void bnxt_ulp_shutdown(struct bnxt *bp)
{
struct bnxt_en_dev *edev = bp->edev;
struct bnxt_ulp_ops *ops;
int i;
if (!edev)
return;
for (i = 0; i < BNXT_MAX_ULP; i++) {
struct bnxt_ulp *ulp = &edev->ulp_tbl[i];
ops = rtnl_dereference(ulp->ulp_ops);
if (!ops || !ops->ulp_shutdown)
continue;
ops->ulp_shutdown(ulp->handle);
}
}
void bnxt_ulp_async_events(struct bnxt *bp, struct hwrm_async_event_cmpl *cmpl)
{
u16 event_id = le16_to_cpu(cmpl->event_id);
......
......@@ -26,6 +26,7 @@ struct bnxt_ulp_ops {
void (*ulp_stop)(void *);
void (*ulp_start)(void *);
void (*ulp_sriov_config)(void *, int);
void (*ulp_shutdown)(void *);
};
struct bnxt_msix_entry {
......@@ -87,6 +88,7 @@ void bnxt_subtract_ulp_resources(struct bnxt *bp, int ulp_id);
void bnxt_ulp_stop(struct bnxt *bp);
void bnxt_ulp_start(struct bnxt *bp);
void bnxt_ulp_sriov_cfg(struct bnxt *bp, int num_vfs);
void bnxt_ulp_shutdown(struct bnxt *bp);
void bnxt_ulp_async_events(struct bnxt *bp, struct hwrm_async_event_cmpl *cmpl);
struct bnxt_en_dev *bnxt_ulp_probe(struct net_device *dev);
......
......@@ -63,7 +63,7 @@ void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts)
tx_buf = &txr->tx_buf_ring[last_tx_cons];
rx_prod = tx_buf->rx_prod;
}
writel(DB_KEY_RX | rx_prod, rxr->rx_doorbell);
bnxt_db_write(bp, rxr->rx_doorbell, DB_KEY_RX | rx_prod);
}
/* returns the following:
......
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