16b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla/*
2d2145cde58135dabe7c48a599de4b81c2fe3ea61Ajit Khaparde * Copyright (C) 2005 - 2011 Emulex
36b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla * All rights reserved.
46b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla *
56b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla * This program is free software; you can redistribute it and/or
66b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla * modify it under the terms of the GNU General Public License version 2
76b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla * as published by the Free Software Foundation.  The full GNU General
86b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla * Public License is included in this distribution in the file called COPYING.
96b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla *
106b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla * Contact Information:
11d2145cde58135dabe7c48a599de4b81c2fe3ea61Ajit Khaparde * linux-drivers@emulex.com
126b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla *
13d2145cde58135dabe7c48a599de4b81c2fe3ea61Ajit Khaparde * Emulex
14d2145cde58135dabe7c48a599de4b81c2fe3ea61Ajit Khaparde * 3333 Susan Street
15d2145cde58135dabe7c48a599de4b81c2fe3ea61Ajit Khaparde * Costa Mesa, CA 92626
166b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla */
176b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
1870c71606190e9115e5f8363bfcd164c582eb314aPaul Gortmaker#include <linux/prefetch.h>
199d9779e723a5d23b94abbe5bb7d1197921f6f3ddPaul Gortmaker#include <linux/module.h>
206b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla#include "be.h"
218788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla#include "be_cmds.h"
2265f71b8bd2651e6d6ca9b09fe53a8db2da22b85cStephen Hemminger#include <asm/div64.h>
236b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
246b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya PerlaMODULE_VERSION(DRV_VER);
256b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya PerlaMODULE_DEVICE_TABLE(pci, be_dev_ids);
266b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya PerlaMODULE_DESCRIPTION(DRV_DESC " " DRV_VER);
276b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya PerlaMODULE_AUTHOR("ServerEngines Corporation");
286b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya PerlaMODULE_LICENSE("GPL");
296b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
30ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandistatic unsigned int num_vfs;
31ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandimodule_param(num_vfs, uint, S_IRUGO);
32ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar BandiMODULE_PARM_DESC(num_vfs, "Number of PCI VFs to initialize");
336b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
3411ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perlastatic ushort rx_frag_size = 2048;
3511ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perlamodule_param(rx_frag_size, ushort, S_IRUGO);
3611ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya PerlaMODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data.");
3711ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla
386b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = {
39c4ca2374312b4de819dd700e72a68395eddb5fcbAjit Khaparde	{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
4059fd5d87a4243a992f3a3e69f3627cf4c509608eAjit Khaparde	{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) },
41c4ca2374312b4de819dd700e72a68395eddb5fcbAjit Khaparde	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) },
42c4ca2374312b4de819dd700e72a68395eddb5fcbAjit Khaparde	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) },
43fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	{ PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID3)},
4412f4d0a8770ab26639091d0b2509b19681daad69Mammatha Edhala	{ PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID4)},
45ecedb6ae908e3a8a19942da921a3ffb1c5a0d6abAjit Khaparde	{ PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID5)},
466b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	{ 0 }
476b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla};
486b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya PerlaMODULE_DEVICE_TABLE(pci, be_dev_ids);
497c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde/* UE Status Low CSR */
5042c8b11e284fe3186e27555d1adb7d4b77398e1bJoe Perchesstatic const char * const ue_status_low_desc[] = {
517c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"CEV",
527c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"CTX",
537c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"DBUF",
547c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"ERX",
557c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"Host",
567c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"MPU",
577c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"NDMA",
587c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"PTC ",
597c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"RDMA ",
607c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"RXF ",
617c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"RXIPS ",
627c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"RXULP0 ",
637c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"RXULP1 ",
647c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"RXULP2 ",
657c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"TIM ",
667c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"TPOST ",
677c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"TPRE ",
687c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"TXIPS ",
697c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"TXULP0 ",
707c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"TXULP1 ",
717c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"UC ",
727c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"WDMA ",
737c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"TXULP2 ",
747c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"HOST1 ",
757c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"P0_OB_LINK ",
767c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"P1_OB_LINK ",
777c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"HOST_GPIO ",
787c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"MBOX ",
797c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"AXGMAC0",
807c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"AXGMAC1",
817c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"JTAG",
827c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"MPU_INTPEND"
837c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde};
847c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde/* UE Status High CSR */
8542c8b11e284fe3186e27555d1adb7d4b77398e1bJoe Perchesstatic const char * const ue_status_hi_desc[] = {
867c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"LPCMEMHOST",
877c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"MGMT_MAC",
887c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"PCS0ONLINE",
897c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"MPU_IRAM",
907c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"PCS1ONLINE",
917c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"PCTL0",
927c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"PCTL1",
937c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"PMEM",
947c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"RR",
957c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"TXPB",
967c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"RXPP",
977c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"XAUI",
987c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"TXP",
997c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"ARM",
1007c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"IPC",
1017c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"HOST2",
1027c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"HOST3",
1037c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"HOST4",
1047c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"HOST5",
1057c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"HOST6",
1067c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"HOST7",
1077c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"HOST8",
1087c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"HOST9",
10942c8b11e284fe3186e27555d1adb7d4b77398e1bJoe Perches	"NETC",
1107c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"Unknown",
1117c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"Unknown",
1127c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"Unknown",
1137c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"Unknown",
1147c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"Unknown",
1157c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"Unknown",
1167c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"Unknown",
1177c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	"Unknown"
1187c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde};
1196b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
120752961a11e847e604aeaaa798cac438c1e671ba4Sathya Perla/* Is BE in a multi-channel mode */
121752961a11e847e604aeaaa798cac438c1e671ba4Sathya Perlastatic inline bool be_is_mc(struct be_adapter *adapter) {
122752961a11e847e604aeaaa798cac438c1e671ba4Sathya Perla	return (adapter->function_mode & FLEX10_MODE ||
123752961a11e847e604aeaaa798cac438c1e671ba4Sathya Perla		adapter->function_mode & VNIC_MODE ||
124752961a11e847e604aeaaa798cac438c1e671ba4Sathya Perla		adapter->function_mode & UMC_ENABLED);
125752961a11e847e604aeaaa798cac438c1e671ba4Sathya Perla}
126752961a11e847e604aeaaa798cac438c1e671ba4Sathya Perla
1276b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic void be_queue_free(struct be_adapter *adapter, struct be_queue_info *q)
1286b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
1296b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_dma_mem *mem = &q->dma_mem;
1301cfafab965198bc0d9cb794af5065d0797969727Sathya Perla	if (mem->va) {
1312b7bcebf958c74124220ee8103024def8597b36cIvan Vecera		dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va,
1322b7bcebf958c74124220ee8103024def8597b36cIvan Vecera				  mem->dma);
1331cfafab965198bc0d9cb794af5065d0797969727Sathya Perla		mem->va = NULL;
1341cfafab965198bc0d9cb794af5065d0797969727Sathya Perla	}
1356b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
1366b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
1376b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic int be_queue_alloc(struct be_adapter *adapter, struct be_queue_info *q,
1386b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		u16 len, u16 entry_size)
1396b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
1406b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_dma_mem *mem = &q->dma_mem;
1416b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
1426b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	memset(q, 0, sizeof(*q));
1436b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	q->len = len;
1446b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	q->entry_size = entry_size;
1456b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	mem->size = len * entry_size;
1462b7bcebf958c74124220ee8103024def8597b36cIvan Vecera	mem->va = dma_alloc_coherent(&adapter->pdev->dev, mem->size, &mem->dma,
1472b7bcebf958c74124220ee8103024def8597b36cIvan Vecera				     GFP_KERNEL);
1486b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (!mem->va)
14910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		return -ENOMEM;
1506b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	memset(mem->va, 0, mem->size);
1516b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return 0;
1526b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
1536b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
1548788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perlastatic void be_intr_set(struct be_adapter *adapter, bool enable)
1556b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
156db3ea7819d035ff01c8260fce364511adfae0eaaSathya Perla	u32 reg, enabled;
1575f0b849eb35d09cd2f332d5031051c1a8976c30bSathya Perla
158cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	if (adapter->eeh_err)
159cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla		return;
160cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
161db3ea7819d035ff01c8260fce364511adfae0eaaSathya Perla	pci_read_config_dword(adapter->pdev, PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET,
162db3ea7819d035ff01c8260fce364511adfae0eaaSathya Perla				&reg);
163db3ea7819d035ff01c8260fce364511adfae0eaaSathya Perla	enabled = reg & MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
164db3ea7819d035ff01c8260fce364511adfae0eaaSathya Perla
1655f0b849eb35d09cd2f332d5031051c1a8976c30bSathya Perla	if (!enabled && enable)
1666b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
1675f0b849eb35d09cd2f332d5031051c1a8976c30bSathya Perla	else if (enabled && !enable)
1686b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		reg &= ~MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
1695f0b849eb35d09cd2f332d5031051c1a8976c30bSathya Perla	else
1706b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		return;
1715f0b849eb35d09cd2f332d5031051c1a8976c30bSathya Perla
172db3ea7819d035ff01c8260fce364511adfae0eaaSathya Perla	pci_write_config_dword(adapter->pdev,
173db3ea7819d035ff01c8260fce364511adfae0eaaSathya Perla			PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET, reg);
1746b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
1756b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
1768788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perlastatic void be_rxq_notify(struct be_adapter *adapter, u16 qid, u16 posted)
1776b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
1786b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	u32 val = 0;
1796b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	val |= qid & DB_RQ_RING_ID_MASK;
1806b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	val |= posted << DB_RQ_NUM_POSTED_SHIFT;
181f3eb62d2cc7da7bea4b394dd06f6bc738aa284e7Sathya Perla
182f3eb62d2cc7da7bea4b394dd06f6bc738aa284e7Sathya Perla	wmb();
1838788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla	iowrite32(val, adapter->db + DB_RQ_OFFSET);
1846b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
1856b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
1868788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perlastatic void be_txq_notify(struct be_adapter *adapter, u16 qid, u16 posted)
1876b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
1886b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	u32 val = 0;
1896b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	val |= qid & DB_TXULP_RING_ID_MASK;
1906b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	val |= (posted & DB_TXULP_NUM_POSTED_MASK) << DB_TXULP_NUM_POSTED_SHIFT;
191f3eb62d2cc7da7bea4b394dd06f6bc738aa284e7Sathya Perla
192f3eb62d2cc7da7bea4b394dd06f6bc738aa284e7Sathya Perla	wmb();
1938788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla	iowrite32(val, adapter->db + DB_TXULP1_OFFSET);
1946b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
1956b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
1968788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perlastatic void be_eq_notify(struct be_adapter *adapter, u16 qid,
1976b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		bool arm, bool clear_int, u16 num_popped)
1986b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
1996b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	u32 val = 0;
2006b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	val |= qid & DB_EQ_RING_ID_MASK;
201fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	val |= ((qid & DB_EQ_RING_ID_EXT_MASK) <<
202fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla			DB_EQ_RING_ID_EXT_MASK_SHIFT);
203cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
204cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	if (adapter->eeh_err)
205cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla		return;
206cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
2076b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (arm)
2086b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		val |= 1 << DB_EQ_REARM_SHIFT;
2096b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (clear_int)
2106b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		val |= 1 << DB_EQ_CLR_SHIFT;
2116b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	val |= 1 << DB_EQ_EVNT_SHIFT;
2126b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	val |= num_popped << DB_EQ_NUM_POPPED_SHIFT;
2138788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla	iowrite32(val, adapter->db + DB_EQ_OFFSET);
2146b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
2156b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
2168788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perlavoid be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, u16 num_popped)
2176b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
2186b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	u32 val = 0;
2196b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	val |= qid & DB_CQ_RING_ID_MASK;
220fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	val |= ((qid & DB_CQ_RING_ID_EXT_MASK) <<
221fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla			DB_CQ_RING_ID_EXT_MASK_SHIFT);
222cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
223cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	if (adapter->eeh_err)
224cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla		return;
225cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
2266b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (arm)
2276b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		val |= 1 << DB_CQ_REARM_SHIFT;
2286b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	val |= num_popped << DB_CQ_NUM_POPPED_SHIFT;
2298788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla	iowrite32(val, adapter->db + DB_CQ_OFFSET);
2306b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
2316b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
2326b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic int be_mac_addr_set(struct net_device *netdev, void *p)
2336b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
2346b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_adapter *adapter = netdev_priv(netdev);
2356b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct sockaddr *addr = p;
2366b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	int status = 0;
237e3a7ae2c1819aa210a38f80f6bf13322652c8211Somnath Kotur	u8 current_mac[ETH_ALEN];
238fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde	u32 pmac_id = adapter->pmac_id[0];
2396b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
240ca9e4988ccbde3b11116679f1b023eb75df8017eAjit Khaparde	if (!is_valid_ether_addr(addr->sa_data))
241ca9e4988ccbde3b11116679f1b023eb75df8017eAjit Khaparde		return -EADDRNOTAVAIL;
242ca9e4988ccbde3b11116679f1b023eb75df8017eAjit Khaparde
243e3a7ae2c1819aa210a38f80f6bf13322652c8211Somnath Kotur	status = be_cmd_mac_addr_query(adapter, current_mac,
244590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar				MAC_ADDRESS_TYPE_NETWORK, false,
245590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar				adapter->if_handle, 0);
246a65027e4d80ece5a5a3bd4fc4808a83208430929Sathya Perla	if (status)
247e3a7ae2c1819aa210a38f80f6bf13322652c8211Somnath Kotur		goto err;
2486b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
249e3a7ae2c1819aa210a38f80f6bf13322652c8211Somnath Kotur	if (memcmp(addr->sa_data, current_mac, ETH_ALEN)) {
250e3a7ae2c1819aa210a38f80f6bf13322652c8211Somnath Kotur		status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data,
251fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde				adapter->if_handle, &adapter->pmac_id[0], 0);
252e3a7ae2c1819aa210a38f80f6bf13322652c8211Somnath Kotur		if (status)
253e3a7ae2c1819aa210a38f80f6bf13322652c8211Somnath Kotur			goto err;
2546b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
255e3a7ae2c1819aa210a38f80f6bf13322652c8211Somnath Kotur		be_cmd_pmac_del(adapter, adapter->if_handle, pmac_id, 0);
256e3a7ae2c1819aa210a38f80f6bf13322652c8211Somnath Kotur	}
257e3a7ae2c1819aa210a38f80f6bf13322652c8211Somnath Kotur	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
258e3a7ae2c1819aa210a38f80f6bf13322652c8211Somnath Kotur	return 0;
259e3a7ae2c1819aa210a38f80f6bf13322652c8211Somnath Koturerr:
260e3a7ae2c1819aa210a38f80f6bf13322652c8211Somnath Kotur	dev_err(&adapter->pdev->dev, "MAC %pM set Failed\n", addr->sa_data);
2616b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return status;
2626b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
2636b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
26489a88ab84b946a90839fb66ca3583a2504c11292Ajit Khapardestatic void populate_be2_stats(struct be_adapter *adapter)
26589a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde{
266ac124ff973e2780279774a30dd924affef758a51Sathya Perla	struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter);
267ac124ff973e2780279774a30dd924affef758a51Sathya Perla	struct be_pmem_stats *pmem_sts = &hw_stats->pmem;
268ac124ff973e2780279774a30dd924affef758a51Sathya Perla	struct be_rxf_stats_v0 *rxf_stats = &hw_stats->rxf;
26989a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	struct be_port_rxf_stats_v0 *port_stats =
270ac124ff973e2780279774a30dd924affef758a51Sathya Perla					&rxf_stats->port[adapter->port_num];
271ac124ff973e2780279774a30dd924affef758a51Sathya Perla	struct be_drv_stats *drvs = &adapter->drv_stats;
27289a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde
273ac124ff973e2780279774a30dd924affef758a51Sathya Perla	be_dws_le_to_cpu(hw_stats, sizeof(*hw_stats));
27489a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_pause_frames = port_stats->rx_pause_frames;
27589a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_crc_errors = port_stats->rx_crc_errors;
27689a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_control_frames = port_stats->rx_control_frames;
27789a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_in_range_errors = port_stats->rx_in_range_errors;
27889a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_frame_too_long = port_stats->rx_frame_too_long;
27989a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_dropped_runt = port_stats->rx_dropped_runt;
28089a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs;
28189a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs;
28289a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs;
28389a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rxpp_fifo_overflow_drop = port_stats->rx_fifo_overflow;
28489a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_dropped_tcp_length = port_stats->rx_dropped_tcp_length;
28589a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_dropped_too_small = port_stats->rx_dropped_too_small;
28689a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_dropped_too_short = port_stats->rx_dropped_too_short;
28789a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_out_range_errors = port_stats->rx_out_range_errors;
288ac124ff973e2780279774a30dd924affef758a51Sathya Perla	drvs->rx_input_fifo_overflow_drop = port_stats->rx_input_fifo_overflow;
28989a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_dropped_header_too_small =
29089a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde		port_stats->rx_dropped_header_too_small;
291d45b9d39a1aed7851948460d29b843ce70eb0a68Sathya Perla	drvs->rx_address_mismatch_drops =
292d45b9d39a1aed7851948460d29b843ce70eb0a68Sathya Perla					port_stats->rx_address_mismatch_drops +
293d45b9d39a1aed7851948460d29b843ce70eb0a68Sathya Perla					port_stats->rx_vlan_mismatch_drops;
29489a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_alignment_symbol_errors =
29589a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde		port_stats->rx_alignment_symbol_errors;
29689a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde
29789a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->tx_pauseframes = port_stats->tx_pauseframes;
29889a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->tx_controlframes = port_stats->tx_controlframes;
29989a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde
30089a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	if (adapter->port_num)
301ac124ff973e2780279774a30dd924affef758a51Sathya Perla		drvs->jabber_events = rxf_stats->port1_jabber_events;
30289a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	else
303ac124ff973e2780279774a30dd924affef758a51Sathya Perla		drvs->jabber_events = rxf_stats->port0_jabber_events;
30489a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf;
30589a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr;
30689a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->forwarded_packets = rxf_stats->forwarded_packets;
30789a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu;
308ac124ff973e2780279774a30dd924affef758a51Sathya Perla	drvs->rx_drops_no_tpre_descr = rxf_stats->rx_drops_no_tpre_descr;
309ac124ff973e2780279774a30dd924affef758a51Sathya Perla	drvs->rx_drops_too_many_frags = rxf_stats->rx_drops_too_many_frags;
31089a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops;
31189a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde}
31289a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde
31389a88ab84b946a90839fb66ca3583a2504c11292Ajit Khapardestatic void populate_be3_stats(struct be_adapter *adapter)
31489a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde{
315ac124ff973e2780279774a30dd924affef758a51Sathya Perla	struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter);
316ac124ff973e2780279774a30dd924affef758a51Sathya Perla	struct be_pmem_stats *pmem_sts = &hw_stats->pmem;
317ac124ff973e2780279774a30dd924affef758a51Sathya Perla	struct be_rxf_stats_v1 *rxf_stats = &hw_stats->rxf;
31889a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	struct be_port_rxf_stats_v1 *port_stats =
319ac124ff973e2780279774a30dd924affef758a51Sathya Perla					&rxf_stats->port[adapter->port_num];
320ac124ff973e2780279774a30dd924affef758a51Sathya Perla	struct be_drv_stats *drvs = &adapter->drv_stats;
32189a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde
322ac124ff973e2780279774a30dd924affef758a51Sathya Perla	be_dws_le_to_cpu(hw_stats, sizeof(*hw_stats));
32302fe7027961969a052fbbe453304f329d4e9735aAjit Khaparde	drvs->pmem_fifo_overflow_drop = port_stats->pmem_fifo_overflow_drop;
32402fe7027961969a052fbbe453304f329d4e9735aAjit Khaparde	drvs->rx_priority_pause_frames = port_stats->rx_priority_pause_frames;
32589a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_pause_frames = port_stats->rx_pause_frames;
32689a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_crc_errors = port_stats->rx_crc_errors;
32789a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_control_frames = port_stats->rx_control_frames;
32889a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_in_range_errors = port_stats->rx_in_range_errors;
32989a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_frame_too_long = port_stats->rx_frame_too_long;
33089a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_dropped_runt = port_stats->rx_dropped_runt;
33189a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs;
33289a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs;
33389a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs;
33489a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_dropped_tcp_length = port_stats->rx_dropped_tcp_length;
33589a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_dropped_too_small = port_stats->rx_dropped_too_small;
33689a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_dropped_too_short = port_stats->rx_dropped_too_short;
33789a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_out_range_errors = port_stats->rx_out_range_errors;
33889a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_dropped_header_too_small =
33989a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde		port_stats->rx_dropped_header_too_small;
34089a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_input_fifo_overflow_drop =
34189a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde		port_stats->rx_input_fifo_overflow_drop;
342d45b9d39a1aed7851948460d29b843ce70eb0a68Sathya Perla	drvs->rx_address_mismatch_drops = port_stats->rx_address_mismatch_drops;
34389a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_alignment_symbol_errors =
34489a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde		port_stats->rx_alignment_symbol_errors;
345ac124ff973e2780279774a30dd924affef758a51Sathya Perla	drvs->rxpp_fifo_overflow_drop = port_stats->rxpp_fifo_overflow_drop;
34689a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->tx_pauseframes = port_stats->tx_pauseframes;
34789a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->tx_controlframes = port_stats->tx_controlframes;
34889a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->jabber_events = port_stats->jabber_events;
34989a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf;
35089a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr;
35189a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->forwarded_packets = rxf_stats->forwarded_packets;
35289a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu;
353ac124ff973e2780279774a30dd924affef758a51Sathya Perla	drvs->rx_drops_no_tpre_descr = rxf_stats->rx_drops_no_tpre_descr;
354ac124ff973e2780279774a30dd924affef758a51Sathya Perla	drvs->rx_drops_too_many_frags = rxf_stats->rx_drops_too_many_frags;
35589a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops;
35689a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde}
35789a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde
358005d569600b404cae0b356e3c4085290ecc17775Selvin Xavierstatic void populate_lancer_stats(struct be_adapter *adapter)
359005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier{
36089a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde
361005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier	struct be_drv_stats *drvs = &adapter->drv_stats;
362ac124ff973e2780279774a30dd924affef758a51Sathya Perla	struct lancer_pport_stats *pport_stats =
363ac124ff973e2780279774a30dd924affef758a51Sathya Perla					pport_stats_from_cmd(adapter);
364ac124ff973e2780279774a30dd924affef758a51Sathya Perla
365ac124ff973e2780279774a30dd924affef758a51Sathya Perla	be_dws_le_to_cpu(pport_stats, sizeof(*pport_stats));
366ac124ff973e2780279774a30dd924affef758a51Sathya Perla	drvs->rx_pause_frames = pport_stats->rx_pause_frames_lo;
367ac124ff973e2780279774a30dd924affef758a51Sathya Perla	drvs->rx_crc_errors = pport_stats->rx_crc_errors_lo;
368ac124ff973e2780279774a30dd924affef758a51Sathya Perla	drvs->rx_control_frames = pport_stats->rx_control_frames_lo;
369005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier	drvs->rx_in_range_errors = pport_stats->rx_in_range_errors;
370ac124ff973e2780279774a30dd924affef758a51Sathya Perla	drvs->rx_frame_too_long = pport_stats->rx_frames_too_long_lo;
371005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier	drvs->rx_dropped_runt = pport_stats->rx_dropped_runt;
372005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier	drvs->rx_ip_checksum_errs = pport_stats->rx_ip_checksum_errors;
373005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier	drvs->rx_tcp_checksum_errs = pport_stats->rx_tcp_checksum_errors;
374005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier	drvs->rx_udp_checksum_errs = pport_stats->rx_udp_checksum_errors;
375005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier	drvs->rx_dropped_tcp_length =
376005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier				pport_stats->rx_dropped_invalid_tcp_length;
377005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier	drvs->rx_dropped_too_small = pport_stats->rx_dropped_too_small;
378005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier	drvs->rx_dropped_too_short = pport_stats->rx_dropped_too_short;
379005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier	drvs->rx_out_range_errors = pport_stats->rx_out_of_range_errors;
380005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier	drvs->rx_dropped_header_too_small =
381005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier				pport_stats->rx_dropped_header_too_small;
382005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier	drvs->rx_input_fifo_overflow_drop = pport_stats->rx_fifo_overflow;
383d45b9d39a1aed7851948460d29b843ce70eb0a68Sathya Perla	drvs->rx_address_mismatch_drops =
384d45b9d39a1aed7851948460d29b843ce70eb0a68Sathya Perla					pport_stats->rx_address_mismatch_drops +
385d45b9d39a1aed7851948460d29b843ce70eb0a68Sathya Perla					pport_stats->rx_vlan_mismatch_drops;
386ac124ff973e2780279774a30dd924affef758a51Sathya Perla	drvs->rx_alignment_symbol_errors = pport_stats->rx_symbol_errors_lo;
387005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier	drvs->rxpp_fifo_overflow_drop = pport_stats->rx_fifo_overflow;
388ac124ff973e2780279774a30dd924affef758a51Sathya Perla	drvs->tx_pauseframes = pport_stats->tx_pause_frames_lo;
389ac124ff973e2780279774a30dd924affef758a51Sathya Perla	drvs->tx_controlframes = pport_stats->tx_control_frames_lo;
390005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier	drvs->jabber_events = pport_stats->rx_jabbers;
391ac124ff973e2780279774a30dd924affef758a51Sathya Perla	drvs->forwarded_packets = pport_stats->num_forwards_lo;
392ac124ff973e2780279774a30dd924affef758a51Sathya Perla	drvs->rx_drops_mtu = pport_stats->rx_drops_mtu_lo;
393005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier	drvs->rx_drops_too_many_frags =
394ac124ff973e2780279774a30dd924affef758a51Sathya Perla				pport_stats->rx_drops_too_many_frags_lo;
395005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier}
39689a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde
39709c1c68f2239dcd99b76be2c44e84811fba273dbSathya Perlastatic void accumulate_16bit_val(u32 *acc, u16 val)
39809c1c68f2239dcd99b76be2c44e84811fba273dbSathya Perla{
39909c1c68f2239dcd99b76be2c44e84811fba273dbSathya Perla#define lo(x)			(x & 0xFFFF)
40009c1c68f2239dcd99b76be2c44e84811fba273dbSathya Perla#define hi(x)			(x & 0xFFFF0000)
40109c1c68f2239dcd99b76be2c44e84811fba273dbSathya Perla	bool wrapped = val < lo(*acc);
40209c1c68f2239dcd99b76be2c44e84811fba273dbSathya Perla	u32 newacc = hi(*acc) + val;
40309c1c68f2239dcd99b76be2c44e84811fba273dbSathya Perla
40409c1c68f2239dcd99b76be2c44e84811fba273dbSathya Perla	if (wrapped)
40509c1c68f2239dcd99b76be2c44e84811fba273dbSathya Perla		newacc += 65536;
40609c1c68f2239dcd99b76be2c44e84811fba273dbSathya Perla	ACCESS_ONCE(*acc) = newacc;
40709c1c68f2239dcd99b76be2c44e84811fba273dbSathya Perla}
40809c1c68f2239dcd99b76be2c44e84811fba273dbSathya Perla
40989a88ab84b946a90839fb66ca3583a2504c11292Ajit Khapardevoid be_parse_stats(struct be_adapter *adapter)
41089a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde{
411ac124ff973e2780279774a30dd924affef758a51Sathya Perla	struct be_erx_stats_v1 *erx = be_erx_stats_from_cmd(adapter);
412ac124ff973e2780279774a30dd924affef758a51Sathya Perla	struct be_rx_obj *rxo;
413ac124ff973e2780279774a30dd924affef758a51Sathya Perla	int i;
414ac124ff973e2780279774a30dd924affef758a51Sathya Perla
415005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier	if (adapter->generation == BE_GEN3) {
416005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier		if (lancer_chip(adapter))
417005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier			populate_lancer_stats(adapter);
418005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier		 else
419005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier			populate_be3_stats(adapter);
420005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier	} else {
42189a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde		populate_be2_stats(adapter);
422005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier	}
423ac124ff973e2780279774a30dd924affef758a51Sathya Perla
424ac124ff973e2780279774a30dd924affef758a51Sathya Perla	/* as erx_v1 is longer than v0, ok to use v1 defn for v0 access */
42509c1c68f2239dcd99b76be2c44e84811fba273dbSathya Perla	for_all_rx_queues(adapter, rxo, i) {
42609c1c68f2239dcd99b76be2c44e84811fba273dbSathya Perla		/* below erx HW counter can actually wrap around after
42709c1c68f2239dcd99b76be2c44e84811fba273dbSathya Perla		 * 65535. Driver accumulates a 32-bit value
42809c1c68f2239dcd99b76be2c44e84811fba273dbSathya Perla		 */
42909c1c68f2239dcd99b76be2c44e84811fba273dbSathya Perla		accumulate_16bit_val(&rx_stats(rxo)->rx_drops_no_frags,
43009c1c68f2239dcd99b76be2c44e84811fba273dbSathya Perla				(u16)erx->rx_drops_no_fragments[rxo->q.id]);
43109c1c68f2239dcd99b76be2c44e84811fba273dbSathya Perla	}
43289a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde}
43389a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde
434ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perlastatic struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev,
435ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla					struct rtnl_link_stats64 *stats)
4366b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
437ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla	struct be_adapter *adapter = netdev_priv(netdev);
43889a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde	struct be_drv_stats *drvs = &adapter->drv_stats;
4393abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	struct be_rx_obj *rxo;
4403c8def9776c3d4636291432522ea312f7a44be95Sathya Perla	struct be_tx_obj *txo;
441ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla	u64 pkts, bytes;
442ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla	unsigned int start;
4433abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	int i;
4446b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
4453abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	for_all_rx_queues(adapter, rxo, i) {
446ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla		const struct be_rx_stats *rx_stats = rx_stats(rxo);
447ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla		do {
448ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla			start = u64_stats_fetch_begin_bh(&rx_stats->sync);
449ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla			pkts = rx_stats(rxo)->rx_pkts;
450ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla			bytes = rx_stats(rxo)->rx_bytes;
451ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla		} while (u64_stats_fetch_retry_bh(&rx_stats->sync, start));
452ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla		stats->rx_packets += pkts;
453ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla		stats->rx_bytes += bytes;
454ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla		stats->multicast += rx_stats(rxo)->rx_mcast_pkts;
455ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla		stats->rx_dropped += rx_stats(rxo)->rx_drops_no_skbs +
456ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla					rx_stats(rxo)->rx_drops_no_frags;
4573abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	}
4583abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla
4593c8def9776c3d4636291432522ea312f7a44be95Sathya Perla	for_all_tx_queues(adapter, txo, i) {
460ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla		const struct be_tx_stats *tx_stats = tx_stats(txo);
461ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla		do {
462ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla			start = u64_stats_fetch_begin_bh(&tx_stats->sync);
463ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla			pkts = tx_stats(txo)->tx_pkts;
464ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla			bytes = tx_stats(txo)->tx_bytes;
465ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla		} while (u64_stats_fetch_retry_bh(&tx_stats->sync, start));
466ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla		stats->tx_packets += pkts;
467ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla		stats->tx_bytes += bytes;
4683c8def9776c3d4636291432522ea312f7a44be95Sathya Perla	}
4696b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
4706b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	/* bad pkts received */
471ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla	stats->rx_errors = drvs->rx_crc_errors +
47289a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde		drvs->rx_alignment_symbol_errors +
47389a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde		drvs->rx_in_range_errors +
47489a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde		drvs->rx_out_range_errors +
47589a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde		drvs->rx_frame_too_long +
47689a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde		drvs->rx_dropped_too_small +
47789a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde		drvs->rx_dropped_too_short +
47889a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde		drvs->rx_dropped_header_too_small +
47989a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde		drvs->rx_dropped_tcp_length +
480ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla		drvs->rx_dropped_runt;
4816811086899f2740c08d0ade26f8b9d705708e0ccSathya Perla
4826b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	/* detailed rx errors */
483ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla	stats->rx_length_errors = drvs->rx_in_range_errors +
48489a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde		drvs->rx_out_range_errors +
48589a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde		drvs->rx_frame_too_long;
4866811086899f2740c08d0ade26f8b9d705708e0ccSathya Perla
487ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla	stats->rx_crc_errors = drvs->rx_crc_errors;
4886b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
4896b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	/* frame alignment errors */
490ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla	stats->rx_frame_errors = drvs->rx_alignment_symbol_errors;
4916811086899f2740c08d0ade26f8b9d705708e0ccSathya Perla
4926b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	/* receiver fifo overrun */
4936b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	/* drops_no_pbuf is no per i/f, it's per BE card */
494ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla	stats->rx_fifo_errors = drvs->rxpp_fifo_overflow_drop +
49589a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde				drvs->rx_input_fifo_overflow_drop +
49689a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde				drvs->rx_drops_no_pbuf;
497ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla	return stats;
4986b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
4996b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
500b236916a68d923acff15787b5439d7d684c17ae5Ajit Khapardevoid be_link_status_update(struct be_adapter *adapter, u8 link_status)
5016b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
5026b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct net_device *netdev = adapter->netdev;
5036b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
504b236916a68d923acff15787b5439d7d684c17ae5Ajit Khaparde	if (!(adapter->flags & BE_FLAGS_LINK_STATUS_INIT)) {
505ea172a011d1435d9bd167265bf51cc64d026b4e7Sathya Perla		netif_carrier_off(netdev);
506b236916a68d923acff15787b5439d7d684c17ae5Ajit Khaparde		adapter->flags |= BE_FLAGS_LINK_STATUS_INIT;
5076b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
508b236916a68d923acff15787b5439d7d684c17ae5Ajit Khaparde
509b236916a68d923acff15787b5439d7d684c17ae5Ajit Khaparde	if ((link_status & LINK_STATUS_MASK) == LINK_UP)
510b236916a68d923acff15787b5439d7d684c17ae5Ajit Khaparde		netif_carrier_on(netdev);
511b236916a68d923acff15787b5439d7d684c17ae5Ajit Khaparde	else
512b236916a68d923acff15787b5439d7d684c17ae5Ajit Khaparde		netif_carrier_off(netdev);
5136b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
5146b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
5153c8def9776c3d4636291432522ea312f7a44be95Sathya Perlastatic void be_tx_stats_update(struct be_tx_obj *txo,
51691992e446cadbbde1a304de6954afd715af5121eAjit Khaparde			u32 wrb_cnt, u32 copied, u32 gso_segs, bool stopped)
5176b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
5183c8def9776c3d4636291432522ea312f7a44be95Sathya Perla	struct be_tx_stats *stats = tx_stats(txo);
5193c8def9776c3d4636291432522ea312f7a44be95Sathya Perla
520ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla	u64_stats_update_begin(&stats->sync);
521ac124ff973e2780279774a30dd924affef758a51Sathya Perla	stats->tx_reqs++;
522ac124ff973e2780279774a30dd924affef758a51Sathya Perla	stats->tx_wrbs += wrb_cnt;
523ac124ff973e2780279774a30dd924affef758a51Sathya Perla	stats->tx_bytes += copied;
524ac124ff973e2780279774a30dd924affef758a51Sathya Perla	stats->tx_pkts += (gso_segs ? gso_segs : 1);
5256b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (stopped)
526ac124ff973e2780279774a30dd924affef758a51Sathya Perla		stats->tx_stops++;
527ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla	u64_stats_update_end(&stats->sync);
5286b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
5296b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
5306b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla/* Determine number of WRB entries needed to xmit data in an skb */
531fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perlastatic u32 wrb_cnt_for_skb(struct be_adapter *adapter, struct sk_buff *skb,
532fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla								bool *dummy)
5336b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
534ebc8d2ab61dde6cf775ae7bb1ed9e38dfe12ca65David S. Miller	int cnt = (skb->len > skb->data_len);
535ebc8d2ab61dde6cf775ae7bb1ed9e38dfe12ca65David S. Miller
536ebc8d2ab61dde6cf775ae7bb1ed9e38dfe12ca65David S. Miller	cnt += skb_shinfo(skb)->nr_frags;
537ebc8d2ab61dde6cf775ae7bb1ed9e38dfe12ca65David S. Miller
5386b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	/* to account for hdr wrb */
5396b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	cnt++;
540fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	if (lancer_chip(adapter) || !(cnt & 1)) {
541fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		*dummy = false;
542fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	} else {
5436b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		/* add a dummy to make it an even num */
5446b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		cnt++;
5456b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		*dummy = true;
546fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	}
5476b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	BUG_ON(cnt > BE_MAX_TX_FRAG_COUNT);
5486b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return cnt;
5496b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
5506b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
5516b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic inline void wrb_fill(struct be_eth_wrb *wrb, u64 addr, int len)
5526b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
5536b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	wrb->frag_pa_hi = upper_32_bits(addr);
5546b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	wrb->frag_pa_lo = addr & 0xFFFFFFFF;
5556b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	wrb->frag_len = len & ETH_WRB_FRAG_LEN_MASK;
5566b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
5576b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
5581ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khapardestatic inline u16 be_get_tx_vlan_tag(struct be_adapter *adapter,
5591ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde					struct sk_buff *skb)
5601ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde{
5611ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde	u8 vlan_prio;
5621ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde	u16 vlan_tag;
5631ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde
5641ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde	vlan_tag = vlan_tx_tag_get(skb);
5651ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde	vlan_prio = (vlan_tag & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
5661ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde	/* If vlan priority provided by OS is NOT in available bmap */
5671ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde	if (!(adapter->vlan_prio_bmap & (1 << vlan_prio)))
5681ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde		vlan_tag = (vlan_tag & ~VLAN_PRIO_MASK) |
5691ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde				adapter->recommended_prio;
5701ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde
5711ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde	return vlan_tag;
5721ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde}
5731ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde
574cc4ce020935eab2d261b7b8d24a9843b56ad594cSomnath Koturstatic void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr,
575cc4ce020935eab2d261b7b8d24a9843b56ad594cSomnath Kotur		struct sk_buff *skb, u32 wrb_cnt, u32 len)
5766b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
5771ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde	u16 vlan_tag;
578cc4ce020935eab2d261b7b8d24a9843b56ad594cSomnath Kotur
5796b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	memset(hdr, 0, sizeof(*hdr));
5806b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
5816b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	AMAP_SET_BITS(struct amap_eth_hdr_wrb, crc, hdr, 1);
5826b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
58349e4b8476f89956ec64b8b9fb7074cb4309a1169Ajit Khaparde	if (skb_is_gso(skb)) {
5846b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso, hdr, 1);
5856b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso_mss,
5866b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			hdr, skb_shinfo(skb)->gso_size);
587fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		if (skb_is_gso_v6(skb) && !lancer_chip(adapter))
58849e4b8476f89956ec64b8b9fb7074cb4309a1169Ajit Khaparde			AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso6, hdr, 1);
589fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		if (lancer_chip(adapter) && adapter->sli_family  ==
590fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla							LANCER_A0_SLI_FAMILY) {
591fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla			AMAP_SET_BITS(struct amap_eth_hdr_wrb, ipcs, hdr, 1);
592fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla			if (is_tcp_pkt(skb))
593fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla				AMAP_SET_BITS(struct amap_eth_hdr_wrb,
594fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla								tcpcs, hdr, 1);
595fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla			else if (is_udp_pkt(skb))
596fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla				AMAP_SET_BITS(struct amap_eth_hdr_wrb,
597fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla								udpcs, hdr, 1);
598fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		}
5996b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
6006b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		if (is_tcp_pkt(skb))
6016b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			AMAP_SET_BITS(struct amap_eth_hdr_wrb, tcpcs, hdr, 1);
6026b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		else if (is_udp_pkt(skb))
6036b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1);
6046b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
6056b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
6064c5102f94c175d81790a3a288e85efd4a8a1649aAjit Khaparde	if (vlan_tx_tag_present(skb)) {
6076b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1);
6081ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde		vlan_tag = be_get_tx_vlan_tag(adapter, skb);
609cc4ce020935eab2d261b7b8d24a9843b56ad594cSomnath Kotur		AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag, hdr, vlan_tag);
6106b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
6116b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
6126b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	AMAP_SET_BITS(struct amap_eth_hdr_wrb, event, hdr, 1);
6136b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	AMAP_SET_BITS(struct amap_eth_hdr_wrb, complete, hdr, 1);
6146b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	AMAP_SET_BITS(struct amap_eth_hdr_wrb, num_wrb, hdr, wrb_cnt);
6156b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	AMAP_SET_BITS(struct amap_eth_hdr_wrb, len, hdr, len);
6166b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
6176b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
6182b7bcebf958c74124220ee8103024def8597b36cIvan Vecerastatic void unmap_tx_frag(struct device *dev, struct be_eth_wrb *wrb,
6197101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla		bool unmap_single)
6207101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla{
6217101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla	dma_addr_t dma;
6227101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla
6237101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla	be_dws_le_to_cpu(wrb, sizeof(*wrb));
6247101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla
6257101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla	dma = (u64)wrb->frag_pa_hi << 32 | (u64)wrb->frag_pa_lo;
626b681ee77f8ad248b0fdcec2e5e8c4df6e757eba3FUJITA Tomonori	if (wrb->frag_len) {
6277101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla		if (unmap_single)
6282b7bcebf958c74124220ee8103024def8597b36cIvan Vecera			dma_unmap_single(dev, dma, wrb->frag_len,
6292b7bcebf958c74124220ee8103024def8597b36cIvan Vecera					 DMA_TO_DEVICE);
6307101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla		else
6312b7bcebf958c74124220ee8103024def8597b36cIvan Vecera			dma_unmap_page(dev, dma, wrb->frag_len, DMA_TO_DEVICE);
6327101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla	}
6337101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla}
6346b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
6353c8def9776c3d4636291432522ea312f7a44be95Sathya Perlastatic int make_tx_wrbs(struct be_adapter *adapter, struct be_queue_info *txq,
6366b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		struct sk_buff *skb, u32 wrb_cnt, bool dummy_wrb)
6376b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
6387101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla	dma_addr_t busaddr;
6397101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla	int i, copied = 0;
6402b7bcebf958c74124220ee8103024def8597b36cIvan Vecera	struct device *dev = &adapter->pdev->dev;
6416b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct sk_buff *first_skb = skb;
6426b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_eth_wrb *wrb;
6436b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_eth_hdr_wrb *hdr;
6447101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla	bool map_single = false;
6457101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla	u16 map_head;
6466b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
6476b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	hdr = queue_head_node(txq);
6486b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	queue_head_inc(txq);
6497101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla	map_head = txq->head;
6506b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
651ebc8d2ab61dde6cf775ae7bb1ed9e38dfe12ca65David S. Miller	if (skb->len > skb->data_len) {
652e743d31312d00932391b123dfac3324d2b9e8c81Eric Dumazet		int len = skb_headlen(skb);
6532b7bcebf958c74124220ee8103024def8597b36cIvan Vecera		busaddr = dma_map_single(dev, skb->data, len, DMA_TO_DEVICE);
6542b7bcebf958c74124220ee8103024def8597b36cIvan Vecera		if (dma_mapping_error(dev, busaddr))
6557101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla			goto dma_err;
6567101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla		map_single = true;
657ebc8d2ab61dde6cf775ae7bb1ed9e38dfe12ca65David S. Miller		wrb = queue_head_node(txq);
658ebc8d2ab61dde6cf775ae7bb1ed9e38dfe12ca65David S. Miller		wrb_fill(wrb, busaddr, len);
659ebc8d2ab61dde6cf775ae7bb1ed9e38dfe12ca65David S. Miller		be_dws_cpu_to_le(wrb, sizeof(*wrb));
660ebc8d2ab61dde6cf775ae7bb1ed9e38dfe12ca65David S. Miller		queue_head_inc(txq);
661ebc8d2ab61dde6cf775ae7bb1ed9e38dfe12ca65David S. Miller		copied += len;
662ebc8d2ab61dde6cf775ae7bb1ed9e38dfe12ca65David S. Miller	}
6636b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
664ebc8d2ab61dde6cf775ae7bb1ed9e38dfe12ca65David S. Miller	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
6659e903e085262ffbf1fc44a17ac06058aca03524aEric Dumazet		const struct skb_frag_struct *frag =
666ebc8d2ab61dde6cf775ae7bb1ed9e38dfe12ca65David S. Miller			&skb_shinfo(skb)->frags[i];
667b061b39e3ae18ad75466258cf2116e18fa5bbd80Ian Campbell		busaddr = skb_frag_dma_map(dev, frag, 0,
6689e903e085262ffbf1fc44a17ac06058aca03524aEric Dumazet					   skb_frag_size(frag), DMA_TO_DEVICE);
6692b7bcebf958c74124220ee8103024def8597b36cIvan Vecera		if (dma_mapping_error(dev, busaddr))
6707101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla			goto dma_err;
671ebc8d2ab61dde6cf775ae7bb1ed9e38dfe12ca65David S. Miller		wrb = queue_head_node(txq);
6729e903e085262ffbf1fc44a17ac06058aca03524aEric Dumazet		wrb_fill(wrb, busaddr, skb_frag_size(frag));
673ebc8d2ab61dde6cf775ae7bb1ed9e38dfe12ca65David S. Miller		be_dws_cpu_to_le(wrb, sizeof(*wrb));
674ebc8d2ab61dde6cf775ae7bb1ed9e38dfe12ca65David S. Miller		queue_head_inc(txq);
6759e903e085262ffbf1fc44a17ac06058aca03524aEric Dumazet		copied += skb_frag_size(frag);
6766b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
6776b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
6786b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (dummy_wrb) {
6796b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		wrb = queue_head_node(txq);
6806b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		wrb_fill(wrb, 0, 0);
6816b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		be_dws_cpu_to_le(wrb, sizeof(*wrb));
6826b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		queue_head_inc(txq);
6836b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
6846b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
685cc4ce020935eab2d261b7b8d24a9843b56ad594cSomnath Kotur	wrb_fill_hdr(adapter, hdr, first_skb, wrb_cnt, copied);
6866b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	be_dws_cpu_to_le(hdr, sizeof(*hdr));
6876b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
6886b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return copied;
6897101e111217581a36e2eeae7c4a3815d60673cbcSathya Perladma_err:
6907101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla	txq->head = map_head;
6917101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla	while (copied) {
6927101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla		wrb = queue_head_node(txq);
6932b7bcebf958c74124220ee8103024def8597b36cIvan Vecera		unmap_tx_frag(dev, wrb, map_single);
6947101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla		map_single = false;
6957101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla		copied -= wrb->frag_len;
6967101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla		queue_head_inc(txq);
6977101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla	}
6987101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla	return 0;
6996b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
7006b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
70161357325f377889a1daffa14962d705dc814dd0eStephen Hemmingerstatic netdev_tx_t be_xmit(struct sk_buff *skb,
702b31c50a7f9e93a61d14740dedcbbf2c376998bc7Sathya Perla			struct net_device *netdev)
7036b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
7046b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_adapter *adapter = netdev_priv(netdev);
7053c8def9776c3d4636291432522ea312f7a44be95Sathya Perla	struct be_tx_obj *txo = &adapter->tx_obj[skb_get_queue_mapping(skb)];
7063c8def9776c3d4636291432522ea312f7a44be95Sathya Perla	struct be_queue_info *txq = &txo->q;
7076b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	u32 wrb_cnt = 0, copied = 0;
7086b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	u32 start = txq->head;
7096b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	bool dummy_wrb, stopped = false;
7106b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
7111ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde	/* For vlan tagged pkts, BE
7121ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde	 * 1) calculates checksum even when CSO is not requested
7131ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde	 * 2) calculates checksum wrongly for padded pkt less than
7141ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde	 * 60 bytes long.
7151ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde	 * As a workaround disable TX vlan offloading in such cases.
7161ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde	 */
7171ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde	if (unlikely(vlan_tx_tag_present(skb) &&
7181ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde		     (skb->ip_summed != CHECKSUM_PARTIAL || skb->len <= 60))) {
7191ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde		skb = skb_share_check(skb, GFP_ATOMIC);
7201ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde		if (unlikely(!skb))
7211ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde			goto tx_drop;
7221ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde
7231ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde		skb = __vlan_put_tag(skb, be_get_tx_vlan_tag(adapter, skb));
7241ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde		if (unlikely(!skb))
7251ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde			goto tx_drop;
7261ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde
7271ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde		skb->vlan_tci = 0;
7281ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde	}
7291ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khaparde
730fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	wrb_cnt = wrb_cnt_for_skb(adapter, skb, &dummy_wrb);
7316b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
7323c8def9776c3d4636291432522ea312f7a44be95Sathya Perla	copied = make_tx_wrbs(adapter, txq, skb, wrb_cnt, dummy_wrb);
733c190e3c8f6b22004b9cdc62ee5e7ba2fa5f74dc7Ajit Khaparde	if (copied) {
734a459fdd31c96993f6fcee4879eb20bc1e7bac2edEric Dumazet		int gso_segs = skb_shinfo(skb)->gso_segs;
735a459fdd31c96993f6fcee4879eb20bc1e7bac2edEric Dumazet
736c190e3c8f6b22004b9cdc62ee5e7ba2fa5f74dc7Ajit Khaparde		/* record the sent skb in the sent_skb table */
7373c8def9776c3d4636291432522ea312f7a44be95Sathya Perla		BUG_ON(txo->sent_skb_list[start]);
7383c8def9776c3d4636291432522ea312f7a44be95Sathya Perla		txo->sent_skb_list[start] = skb;
739c190e3c8f6b22004b9cdc62ee5e7ba2fa5f74dc7Ajit Khaparde
740c190e3c8f6b22004b9cdc62ee5e7ba2fa5f74dc7Ajit Khaparde		/* Ensure txq has space for the next skb; Else stop the queue
741c190e3c8f6b22004b9cdc62ee5e7ba2fa5f74dc7Ajit Khaparde		 * *BEFORE* ringing the tx doorbell, so that we serialze the
742c190e3c8f6b22004b9cdc62ee5e7ba2fa5f74dc7Ajit Khaparde		 * tx compls of the current transmit which'll wake up the queue
743c190e3c8f6b22004b9cdc62ee5e7ba2fa5f74dc7Ajit Khaparde		 */
7447101e111217581a36e2eeae7c4a3815d60673cbcSathya Perla		atomic_add(wrb_cnt, &txq->used);
745c190e3c8f6b22004b9cdc62ee5e7ba2fa5f74dc7Ajit Khaparde		if ((BE_MAX_TX_FRAG_COUNT + atomic_read(&txq->used)) >=
746c190e3c8f6b22004b9cdc62ee5e7ba2fa5f74dc7Ajit Khaparde								txq->len) {
7473c8def9776c3d4636291432522ea312f7a44be95Sathya Perla			netif_stop_subqueue(netdev, skb_get_queue_mapping(skb));
748c190e3c8f6b22004b9cdc62ee5e7ba2fa5f74dc7Ajit Khaparde			stopped = true;
749c190e3c8f6b22004b9cdc62ee5e7ba2fa5f74dc7Ajit Khaparde		}
7506b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
751c190e3c8f6b22004b9cdc62ee5e7ba2fa5f74dc7Ajit Khaparde		be_txq_notify(adapter, txq->id, wrb_cnt);
7526b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
753a459fdd31c96993f6fcee4879eb20bc1e7bac2edEric Dumazet		be_tx_stats_update(txo, wrb_cnt, copied, gso_segs, stopped);
754c190e3c8f6b22004b9cdc62ee5e7ba2fa5f74dc7Ajit Khaparde	} else {
755c190e3c8f6b22004b9cdc62ee5e7ba2fa5f74dc7Ajit Khaparde		txq->head = start;
756c190e3c8f6b22004b9cdc62ee5e7ba2fa5f74dc7Ajit Khaparde		dev_kfree_skb_any(skb);
7576b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
7581ded132d4c3442aa3a619c94c245d7b5e0eb9731Ajit Khapardetx_drop:
7596b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return NETDEV_TX_OK;
7606b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
7616b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
7626b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic int be_change_mtu(struct net_device *netdev, int new_mtu)
7636b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
7646b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_adapter *adapter = netdev_priv(netdev);
7656b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (new_mtu < BE_MIN_MTU ||
76634a89b8c75abe2873a95524552cc266fdd3b6a85Ajit Khaparde			new_mtu > (BE_MAX_JUMBO_FRAME_SIZE -
76734a89b8c75abe2873a95524552cc266fdd3b6a85Ajit Khaparde					(ETH_HLEN + ETH_FCS_LEN))) {
7686b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		dev_info(&adapter->pdev->dev,
7696b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			"MTU must be between %d and %d bytes\n",
77034a89b8c75abe2873a95524552cc266fdd3b6a85Ajit Khaparde			BE_MIN_MTU,
77134a89b8c75abe2873a95524552cc266fdd3b6a85Ajit Khaparde			(BE_MAX_JUMBO_FRAME_SIZE - (ETH_HLEN + ETH_FCS_LEN)));
7726b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		return -EINVAL;
7736b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
7746b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	dev_info(&adapter->pdev->dev, "MTU changed from %d to %d bytes\n",
7756b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			netdev->mtu, new_mtu);
7766b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	netdev->mtu = new_mtu;
7776b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return 0;
7786b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
7796b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
7806b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla/*
78182903e4bfca1578336a91c0c17839b484c12295dAjit Khaparde * A max of 64 (BE_NUM_VLANS_SUPPORTED) vlans can be configured in BE.
78282903e4bfca1578336a91c0c17839b484c12295dAjit Khaparde * If the user configures more, place BE in vlan promiscuous mode.
7836b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla */
7841da87b7fafebb7874622602f79a5fec0425aede7Ajit Khapardestatic int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num)
7856b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
78611ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	struct be_vf_cfg *vf_cfg = &adapter->vf_cfg[vf_num];
7876b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	u16 vtag[BE_NUM_VLANS_SUPPORTED];
7886b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	u16 ntags = 0, i;
78982903e4bfca1578336a91c0c17839b484c12295dAjit Khaparde	int status = 0;
7901da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde
7911da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde	if (vf) {
79211ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla		vtag[0] = cpu_to_le16(vf_cfg->vlan_tag);
79311ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla		status = be_cmd_vlan_config(adapter, vf_cfg->if_handle, vtag,
79411ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla					    1, 1, 0);
7951da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde	}
7966b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
797c0e64ef4899df4cedc872871e54e2c069d29e519Sathya Perla	/* No need to further configure vids if in promiscuous mode */
798c0e64ef4899df4cedc872871e54e2c069d29e519Sathya Perla	if (adapter->promiscuous)
799c0e64ef4899df4cedc872871e54e2c069d29e519Sathya Perla		return 0;
800c0e64ef4899df4cedc872871e54e2c069d29e519Sathya Perla
80182903e4bfca1578336a91c0c17839b484c12295dAjit Khaparde	if (adapter->vlans_added <= adapter->max_vlans)  {
8026b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		/* Construct VLAN Table to give to HW */
803b738127dfb469bb9f595cdace30e7f881e8146b2Jesse Gross		for (i = 0; i < VLAN_N_VID; i++) {
8046b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			if (adapter->vlan_tag[i]) {
8056b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla				vtag[ntags] = cpu_to_le16(i);
8066b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla				ntags++;
8076b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			}
8086b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		}
809b31c50a7f9e93a61d14740dedcbbf2c376998bc7Sathya Perla		status = be_cmd_vlan_config(adapter, adapter->if_handle,
810b31c50a7f9e93a61d14740dedcbbf2c376998bc7Sathya Perla					vtag, ntags, 1, 0);
8116b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	} else {
812b31c50a7f9e93a61d14740dedcbbf2c376998bc7Sathya Perla		status = be_cmd_vlan_config(adapter, adapter->if_handle,
813b31c50a7f9e93a61d14740dedcbbf2c376998bc7Sathya Perla					NULL, 0, 1, 1);
8146b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
8151da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde
816b31c50a7f9e93a61d14740dedcbbf2c376998bc7Sathya Perla	return status;
8176b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
8186b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
8198e586137e6b63af1e881b328466ab5ffbe562510Jiri Pirkostatic int be_vlan_add_vid(struct net_device *netdev, u16 vid)
8206b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
8216b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_adapter *adapter = netdev_priv(netdev);
82280817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde	int status = 0;
8236b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
82480817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde	if (!be_physfn(adapter)) {
82580817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde		status = -EINVAL;
82680817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde		goto ret;
82780817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde	}
828ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi
8296b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	adapter->vlan_tag[vid] = 1;
83082903e4bfca1578336a91c0c17839b484c12295dAjit Khaparde	if (adapter->vlans_added <= (adapter->max_vlans + 1))
83180817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde		status = be_vid_config(adapter, false, 0);
8328e586137e6b63af1e881b328466ab5ffbe562510Jiri Pirko
83380817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde	if (!status)
83480817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde		adapter->vlans_added++;
83580817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde	else
83680817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde		adapter->vlan_tag[vid] = 0;
83780817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparderet:
83880817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde	return status;
8396b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
8406b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
8418e586137e6b63af1e881b328466ab5ffbe562510Jiri Pirkostatic int be_vlan_rem_vid(struct net_device *netdev, u16 vid)
8426b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
8436b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_adapter *adapter = netdev_priv(netdev);
84480817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde	int status = 0;
8456b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
84680817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde	if (!be_physfn(adapter)) {
84780817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde		status = -EINVAL;
84880817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde		goto ret;
84980817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde	}
850ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi
8516b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	adapter->vlan_tag[vid] = 0;
85282903e4bfca1578336a91c0c17839b484c12295dAjit Khaparde	if (adapter->vlans_added <= adapter->max_vlans)
85380817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde		status = be_vid_config(adapter, false, 0);
8548e586137e6b63af1e881b328466ab5ffbe562510Jiri Pirko
85580817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde	if (!status)
85680817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde		adapter->vlans_added--;
85780817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde	else
85880817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde		adapter->vlan_tag[vid] = 1;
85980817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparderet:
86080817cbf5ac13da76f3ee2b9259f26c09b385e84Ajit Khaparde	return status;
8616b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
8626b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
863a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perlastatic void be_set_rx_mode(struct net_device *netdev)
8646b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
8656b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_adapter *adapter = netdev_priv(netdev);
8666b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
86724307eef74bd38e3fc6a6df8f8a1bfc48967f9f6Sathya Perla	if (netdev->flags & IFF_PROMISC) {
8685b8821b787495273ba4fb333a3561c6da382a9a7Sathya Perla		be_cmd_rx_filter(adapter, IFF_PROMISC, ON);
86924307eef74bd38e3fc6a6df8f8a1bfc48967f9f6Sathya Perla		adapter->promiscuous = true;
87024307eef74bd38e3fc6a6df8f8a1bfc48967f9f6Sathya Perla		goto done;
8716b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
8726b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
87325985edcedea6396277003854657b5f3cb31a628Lucas De Marchi	/* BE was previously in promiscuous mode; disable it */
87424307eef74bd38e3fc6a6df8f8a1bfc48967f9f6Sathya Perla	if (adapter->promiscuous) {
87524307eef74bd38e3fc6a6df8f8a1bfc48967f9f6Sathya Perla		adapter->promiscuous = false;
8765b8821b787495273ba4fb333a3561c6da382a9a7Sathya Perla		be_cmd_rx_filter(adapter, IFF_PROMISC, OFF);
877c0e64ef4899df4cedc872871e54e2c069d29e519Sathya Perla
878c0e64ef4899df4cedc872871e54e2c069d29e519Sathya Perla		if (adapter->vlans_added)
879c0e64ef4899df4cedc872871e54e2c069d29e519Sathya Perla			be_vid_config(adapter, false, 0);
8806b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
8816b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
882e7b909a68cfb83e4bafdadac39534969ce260518Sathya Perla	/* Enable multicast promisc if num configured exceeds what we support */
8834cd24eaf0c6ee7f0242e34ee77ec899f255e66b5Jiri Pirko	if (netdev->flags & IFF_ALLMULTI ||
8845b8821b787495273ba4fb333a3561c6da382a9a7Sathya Perla			netdev_mc_count(netdev) > BE_MAX_MC) {
8855b8821b787495273ba4fb333a3561c6da382a9a7Sathya Perla		be_cmd_rx_filter(adapter, IFF_ALLMULTI, ON);
88624307eef74bd38e3fc6a6df8f8a1bfc48967f9f6Sathya Perla		goto done;
8876b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
8886b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
889fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde	if (netdev_uc_count(netdev) != adapter->uc_macs) {
890fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde		struct netdev_hw_addr *ha;
891fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde		int i = 1; /* First slot is claimed by the Primary MAC */
892fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde
893fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde		for (; adapter->uc_macs > 0; adapter->uc_macs--, i++) {
894fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde			be_cmd_pmac_del(adapter, adapter->if_handle,
895fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde					adapter->pmac_id[i], 0);
896fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde		}
897fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde
898fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde		if (netdev_uc_count(netdev) > adapter->max_pmac_cnt) {
899fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde			be_cmd_rx_filter(adapter, IFF_PROMISC, ON);
900fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde			adapter->promiscuous = true;
901fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde			goto done;
902fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde		}
903fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde
904fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde		netdev_for_each_uc_addr(ha, adapter->netdev) {
905fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde			adapter->uc_macs++; /* First slot is for Primary MAC */
906fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde			be_cmd_pmac_add(adapter, (u8 *)ha->addr,
907fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde					adapter->if_handle,
908fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde					&adapter->pmac_id[adapter->uc_macs], 0);
909fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde		}
910fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde	}
911fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde
9125b8821b787495273ba4fb333a3561c6da382a9a7Sathya Perla	be_cmd_rx_filter(adapter, IFF_MULTICAST, ON);
91324307eef74bd38e3fc6a6df8f8a1bfc48967f9f6Sathya Perladone:
91424307eef74bd38e3fc6a6df8f8a1bfc48967f9f6Sathya Perla	return;
9156b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
9166b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
917ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandistatic int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
918ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi{
919ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi	struct be_adapter *adapter = netdev_priv(netdev);
92011ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	struct be_vf_cfg *vf_cfg = &adapter->vf_cfg[vf];
921ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi	int status;
922ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi
92311ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	if (!sriov_enabled(adapter))
924ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi		return -EPERM;
925ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi
92611ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	if (!is_valid_ether_addr(mac) || vf >= adapter->num_vfs)
927ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi		return -EINVAL;
928ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi
929590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar	if (lancer_chip(adapter)) {
930590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar		status = be_cmd_set_mac_list(adapter,  mac, 1, vf + 1);
931590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar	} else {
93211ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla		status = be_cmd_pmac_del(adapter, vf_cfg->if_handle,
93311ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla					 vf_cfg->pmac_id, vf + 1);
934ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi
93511ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla		status = be_cmd_pmac_add(adapter, mac, vf_cfg->if_handle,
93611ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla					 &vf_cfg->pmac_id, vf + 1);
937590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar	}
938590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar
93964600ea5f389858e183d3739776f4667265cc77fAjit Khaparde	if (status)
940ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi		dev_err(&adapter->pdev->dev, "MAC %pM set on VF %d Failed\n",
941ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi				mac, vf);
94264600ea5f389858e183d3739776f4667265cc77fAjit Khaparde	else
94311ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla		memcpy(vf_cfg->mac_addr, mac, ETH_ALEN);
94464600ea5f389858e183d3739776f4667265cc77fAjit Khaparde
945ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi	return status;
946ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi}
947ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi
94864600ea5f389858e183d3739776f4667265cc77fAjit Khapardestatic int be_get_vf_config(struct net_device *netdev, int vf,
94964600ea5f389858e183d3739776f4667265cc77fAjit Khaparde			struct ifla_vf_info *vi)
95064600ea5f389858e183d3739776f4667265cc77fAjit Khaparde{
95164600ea5f389858e183d3739776f4667265cc77fAjit Khaparde	struct be_adapter *adapter = netdev_priv(netdev);
95211ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	struct be_vf_cfg *vf_cfg = &adapter->vf_cfg[vf];
95364600ea5f389858e183d3739776f4667265cc77fAjit Khaparde
95411ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	if (!sriov_enabled(adapter))
95564600ea5f389858e183d3739776f4667265cc77fAjit Khaparde		return -EPERM;
95664600ea5f389858e183d3739776f4667265cc77fAjit Khaparde
95711ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	if (vf >= adapter->num_vfs)
95864600ea5f389858e183d3739776f4667265cc77fAjit Khaparde		return -EINVAL;
95964600ea5f389858e183d3739776f4667265cc77fAjit Khaparde
96064600ea5f389858e183d3739776f4667265cc77fAjit Khaparde	vi->vf = vf;
96111ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	vi->tx_rate = vf_cfg->tx_rate;
96211ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	vi->vlan = vf_cfg->vlan_tag;
96364600ea5f389858e183d3739776f4667265cc77fAjit Khaparde	vi->qos = 0;
96411ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	memcpy(&vi->mac, vf_cfg->mac_addr, ETH_ALEN);
96564600ea5f389858e183d3739776f4667265cc77fAjit Khaparde
96664600ea5f389858e183d3739776f4667265cc77fAjit Khaparde	return 0;
96764600ea5f389858e183d3739776f4667265cc77fAjit Khaparde}
96864600ea5f389858e183d3739776f4667265cc77fAjit Khaparde
9691da87b7fafebb7874622602f79a5fec0425aede7Ajit Khapardestatic int be_set_vf_vlan(struct net_device *netdev,
9701da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde			int vf, u16 vlan, u8 qos)
9711da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde{
9721da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde	struct be_adapter *adapter = netdev_priv(netdev);
9731da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde	int status = 0;
9741da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde
97511ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	if (!sriov_enabled(adapter))
9761da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde		return -EPERM;
9771da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde
97811ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	if (vf >= adapter->num_vfs || vlan > 4095)
9791da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde		return -EINVAL;
9801da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde
9811da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde	if (vlan) {
982f1f3ee1bcc996e21f122442fd8c34de51622c76aAjit Khaparde		if (adapter->vf_cfg[vf].vlan_tag != vlan) {
983f1f3ee1bcc996e21f122442fd8c34de51622c76aAjit Khaparde			/* If this is new value, program it. Else skip. */
984f1f3ee1bcc996e21f122442fd8c34de51622c76aAjit Khaparde			adapter->vf_cfg[vf].vlan_tag = vlan;
985f1f3ee1bcc996e21f122442fd8c34de51622c76aAjit Khaparde
986f1f3ee1bcc996e21f122442fd8c34de51622c76aAjit Khaparde			status = be_cmd_set_hsw_config(adapter, vlan,
987f1f3ee1bcc996e21f122442fd8c34de51622c76aAjit Khaparde				vf + 1, adapter->vf_cfg[vf].if_handle);
988f1f3ee1bcc996e21f122442fd8c34de51622c76aAjit Khaparde		}
9891da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde	} else {
990f1f3ee1bcc996e21f122442fd8c34de51622c76aAjit Khaparde		/* Reset Transparent Vlan Tagging. */
99111ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla		adapter->vf_cfg[vf].vlan_tag = 0;
992f1f3ee1bcc996e21f122442fd8c34de51622c76aAjit Khaparde		vlan = adapter->vf_cfg[vf].def_vid;
993f1f3ee1bcc996e21f122442fd8c34de51622c76aAjit Khaparde		status = be_cmd_set_hsw_config(adapter, vlan, vf + 1,
994f1f3ee1bcc996e21f122442fd8c34de51622c76aAjit Khaparde			adapter->vf_cfg[vf].if_handle);
9951da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde	}
9961da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde
9971da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde
9981da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde	if (status)
9991da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde		dev_info(&adapter->pdev->dev,
10001da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde				"VLAN %d config on VF %d failed\n", vlan, vf);
10011da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde	return status;
10021da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde}
10031da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde
1004e1d187353fc0597d24cf3169b1bbc1776058e883Ajit Khapardestatic int be_set_vf_tx_rate(struct net_device *netdev,
1005e1d187353fc0597d24cf3169b1bbc1776058e883Ajit Khaparde			int vf, int rate)
1006e1d187353fc0597d24cf3169b1bbc1776058e883Ajit Khaparde{
1007e1d187353fc0597d24cf3169b1bbc1776058e883Ajit Khaparde	struct be_adapter *adapter = netdev_priv(netdev);
1008e1d187353fc0597d24cf3169b1bbc1776058e883Ajit Khaparde	int status = 0;
1009e1d187353fc0597d24cf3169b1bbc1776058e883Ajit Khaparde
101011ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	if (!sriov_enabled(adapter))
1011e1d187353fc0597d24cf3169b1bbc1776058e883Ajit Khaparde		return -EPERM;
1012e1d187353fc0597d24cf3169b1bbc1776058e883Ajit Khaparde
101394f434c2055db5fe20f10d4e0ec50ab395e1f62bAjit Khaparde	if (vf >= adapter->num_vfs)
1014e1d187353fc0597d24cf3169b1bbc1776058e883Ajit Khaparde		return -EINVAL;
1015e1d187353fc0597d24cf3169b1bbc1776058e883Ajit Khaparde
101694f434c2055db5fe20f10d4e0ec50ab395e1f62bAjit Khaparde	if (rate < 100 || rate > 10000) {
101794f434c2055db5fe20f10d4e0ec50ab395e1f62bAjit Khaparde		dev_err(&adapter->pdev->dev,
101894f434c2055db5fe20f10d4e0ec50ab395e1f62bAjit Khaparde			"tx rate must be between 100 and 10000 Mbps\n");
101994f434c2055db5fe20f10d4e0ec50ab395e1f62bAjit Khaparde		return -EINVAL;
102094f434c2055db5fe20f10d4e0ec50ab395e1f62bAjit Khaparde	}
1021e1d187353fc0597d24cf3169b1bbc1776058e883Ajit Khaparde
1022856c40125acf63f93aab5bc18ff9e627beeb0a3dAjit Khaparde	status = be_cmd_set_qos(adapter, rate / 10, vf + 1);
1023e1d187353fc0597d24cf3169b1bbc1776058e883Ajit Khaparde
1024e1d187353fc0597d24cf3169b1bbc1776058e883Ajit Khaparde	if (status)
102594f434c2055db5fe20f10d4e0ec50ab395e1f62bAjit Khaparde		dev_err(&adapter->pdev->dev,
1026e1d187353fc0597d24cf3169b1bbc1776058e883Ajit Khaparde				"tx rate %d on VF %d failed\n", rate, vf);
102794f434c2055db5fe20f10d4e0ec50ab395e1f62bAjit Khaparde	else
102894f434c2055db5fe20f10d4e0ec50ab395e1f62bAjit Khaparde		adapter->vf_cfg[vf].tx_rate = rate;
1029e1d187353fc0597d24cf3169b1bbc1776058e883Ajit Khaparde	return status;
1030e1d187353fc0597d24cf3169b1bbc1776058e883Ajit Khaparde}
1031e1d187353fc0597d24cf3169b1bbc1776058e883Ajit Khaparde
103210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic void be_eqd_update(struct be_adapter *adapter, struct be_eq_obj *eqo)
10336b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
103410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_rx_stats *stats = rx_stats(&adapter->rx_obj[eqo->idx]);
10354097f663cbe9e58de7ebed222f8af33267f297a8Sathya Perla	ulong now = jiffies;
1036ac124ff973e2780279774a30dd924affef758a51Sathya Perla	ulong delta = now - stats->rx_jiffies;
1037ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla	u64 pkts;
1038ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla	unsigned int start, eqd;
1039ac124ff973e2780279774a30dd924affef758a51Sathya Perla
104010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	if (!eqo->enable_aic) {
104110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		eqd = eqo->eqd;
104210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		goto modify_eqd;
104310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	}
104410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
104510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	if (eqo->idx >= adapter->num_rx_qs)
1046ac124ff973e2780279774a30dd924affef758a51Sathya Perla		return;
10476b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
104810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	stats = rx_stats(&adapter->rx_obj[eqo->idx]);
104910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
10504097f663cbe9e58de7ebed222f8af33267f297a8Sathya Perla	/* Wrapped around */
10513abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	if (time_before(now, stats->rx_jiffies)) {
10523abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla		stats->rx_jiffies = now;
10534097f663cbe9e58de7ebed222f8af33267f297a8Sathya Perla		return;
10544097f663cbe9e58de7ebed222f8af33267f297a8Sathya Perla	}
10556b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
1056ac124ff973e2780279774a30dd924affef758a51Sathya Perla	/* Update once a second */
1057ac124ff973e2780279774a30dd924affef758a51Sathya Perla	if (delta < HZ)
10586b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		return;
10596b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
1060ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla	do {
1061ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla		start = u64_stats_fetch_begin_bh(&stats->sync);
1062ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla		pkts = stats->rx_pkts;
1063ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla	} while (u64_stats_fetch_retry_bh(&stats->sync, start));
1064ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla
106568c3e5a7b91513010d2536e4bcd7bdd54d0e6acfEric Dumazet	stats->rx_pps = (unsigned long)(pkts - stats->rx_pkts_prev) / (delta / HZ);
1066ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla	stats->rx_pkts_prev = pkts;
10673abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	stats->rx_jiffies = now;
106810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	eqd = (stats->rx_pps / 110000) << 3;
106910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	eqd = min(eqd, eqo->max_eqd);
107010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	eqd = max(eqd, eqo->min_eqd);
1071ac124ff973e2780279774a30dd924affef758a51Sathya Perla	if (eqd < 10)
1072ac124ff973e2780279774a30dd924affef758a51Sathya Perla		eqd = 0;
107310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
107410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlamodify_eqd:
107510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	if (eqd != eqo->cur_eqd) {
107610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		be_cmd_modify_eqd(adapter, eqo->q.id, eqd);
107710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		eqo->cur_eqd = eqd;
1078ac124ff973e2780279774a30dd924affef758a51Sathya Perla	}
10796b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
10806b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
10813abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perlastatic void be_rx_stats_update(struct be_rx_obj *rxo,
10822e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		struct be_rx_compl_info *rxcp)
10834097f663cbe9e58de7ebed222f8af33267f297a8Sathya Perla{
1084ac124ff973e2780279774a30dd924affef758a51Sathya Perla	struct be_rx_stats *stats = rx_stats(rxo);
10851ef78abec6b5e9e3062e3ae6660eabaf055a718dAjit Khaparde
1086ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla	u64_stats_update_begin(&stats->sync);
10873abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	stats->rx_compl++;
10882e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	stats->rx_bytes += rxcp->pkt_size;
10893abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	stats->rx_pkts++;
10902e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	if (rxcp->pkt_type == BE_MULTICAST_PACKET)
10913abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla		stats->rx_mcast_pkts++;
10922e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	if (rxcp->err)
1093ac124ff973e2780279774a30dd924affef758a51Sathya Perla		stats->rx_compl_err++;
1094ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla	u64_stats_update_end(&stats->sync);
10954097f663cbe9e58de7ebed222f8af33267f297a8Sathya Perla}
10964097f663cbe9e58de7ebed222f8af33267f297a8Sathya Perla
10972e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perlastatic inline bool csum_passed(struct be_rx_compl_info *rxcp)
1098728a9972d1f290608e730b9ccec2061aa81f6609Ajit Khaparde{
109919fad86f3b34f52eebc511f6cdb99e82f53aee94Padmanabh Ratnakar	/* L4 checksum is not reliable for non TCP/UDP packets.
110019fad86f3b34f52eebc511f6cdb99e82f53aee94Padmanabh Ratnakar	 * Also ignore ipcksm for ipv6 pkts */
11012e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	return (rxcp->tcpf || rxcp->udpf) && rxcp->l4_csum &&
11022e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla				(rxcp->ip_csum || rxcp->ipv6);
1103728a9972d1f290608e730b9ccec2061aa81f6609Ajit Khaparde}
1104728a9972d1f290608e730b9ccec2061aa81f6609Ajit Khaparde
110510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic struct be_rx_page_info *get_rx_page_info(struct be_rx_obj *rxo,
110610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla						u16 frag_idx)
11076b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
110810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_adapter *adapter = rxo->adapter;
11096b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_rx_page_info *rx_page_info;
11103abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	struct be_queue_info *rxq = &rxo->q;
11116b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
11123abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	rx_page_info = &rxo->page_info_tbl[frag_idx];
11136b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	BUG_ON(!rx_page_info->page);
11146b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
1115205859a2ff922d0587a819b08007398cbd0a6a30Ajit Khaparde	if (rx_page_info->last_page_user) {
11162b7bcebf958c74124220ee8103024def8597b36cIvan Vecera		dma_unmap_page(&adapter->pdev->dev,
11172b7bcebf958c74124220ee8103024def8597b36cIvan Vecera			       dma_unmap_addr(rx_page_info, bus),
11182b7bcebf958c74124220ee8103024def8597b36cIvan Vecera			       adapter->big_page_size, DMA_FROM_DEVICE);
1119205859a2ff922d0587a819b08007398cbd0a6a30Ajit Khaparde		rx_page_info->last_page_user = false;
1120205859a2ff922d0587a819b08007398cbd0a6a30Ajit Khaparde	}
11216b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
11226b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	atomic_dec(&rxq->used);
11236b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return rx_page_info;
11246b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
11256b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
11266b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla/* Throwaway the data in the Rx completion */
112710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic void be_rx_compl_discard(struct be_rx_obj *rxo,
112810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla				struct be_rx_compl_info *rxcp)
11296b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
11303abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	struct be_queue_info *rxq = &rxo->q;
11316b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_rx_page_info *page_info;
11322e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	u16 i, num_rcvd = rxcp->num_rcvd;
11336b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
1134e80d9da651b19a79a1500d6bb808fcbcb39a869dPadmanabh Ratnakar	for (i = 0; i < num_rcvd; i++) {
113510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		page_info = get_rx_page_info(rxo, rxcp->rxq_idx);
1136e80d9da651b19a79a1500d6bb808fcbcb39a869dPadmanabh Ratnakar		put_page(page_info->page);
1137e80d9da651b19a79a1500d6bb808fcbcb39a869dPadmanabh Ratnakar		memset(page_info, 0, sizeof(*page_info));
11382e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		index_inc(&rxcp->rxq_idx, rxq->len);
11396b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
11406b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
11416b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
11426b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla/*
11436b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla * skb_fill_rx_data forms a complete skb for an ether frame
11446b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla * indicated by rxcp.
11456b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla */
114610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic void skb_fill_rx_data(struct be_rx_obj *rxo, struct sk_buff *skb,
114710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			     struct be_rx_compl_info *rxcp)
11486b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
11493abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	struct be_queue_info *rxq = &rxo->q;
11506b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_rx_page_info *page_info;
11512e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	u16 i, j;
11522e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	u16 hdr_len, curr_frag_len, remaining;
11536b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	u8 *start;
11546b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
115510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	page_info = get_rx_page_info(rxo, rxcp->rxq_idx);
11566b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	start = page_address(page_info->page) + page_info->page_offset;
11576b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	prefetch(start);
11586b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
11596b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	/* Copy data in the first descriptor of this completion */
11602e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	curr_frag_len = min(rxcp->pkt_size, rx_frag_size);
11616b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
11626b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	/* Copy the header portion into skb_data */
11632e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	hdr_len = min(BE_HDR_LEN, curr_frag_len);
11646b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	memcpy(skb->data, start, hdr_len);
11656b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	skb->len = curr_frag_len;
11666b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (curr_frag_len <= BE_HDR_LEN) { /* tiny packet */
11676b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		/* Complete packet has now been moved to data */
11686b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		put_page(page_info->page);
11696b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		skb->data_len = 0;
11706b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		skb->tail += curr_frag_len;
11716b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	} else {
11726b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		skb_shinfo(skb)->nr_frags = 1;
1173b061b39e3ae18ad75466258cf2116e18fa5bbd80Ian Campbell		skb_frag_set_page(skb, 0, page_info->page);
11746b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		skb_shinfo(skb)->frags[0].page_offset =
11756b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla					page_info->page_offset + hdr_len;
11769e903e085262ffbf1fc44a17ac06058aca03524aEric Dumazet		skb_frag_size_set(&skb_shinfo(skb)->frags[0], curr_frag_len - hdr_len);
11776b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		skb->data_len = curr_frag_len - hdr_len;
1178bdb28a97f46b5307e6e9351de52a9dd03e711a2fEric Dumazet		skb->truesize += rx_frag_size;
11796b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		skb->tail += hdr_len;
11806b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
1181205859a2ff922d0587a819b08007398cbd0a6a30Ajit Khaparde	page_info->page = NULL;
11826b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
11832e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	if (rxcp->pkt_size <= rx_frag_size) {
11842e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		BUG_ON(rxcp->num_rcvd != 1);
11852e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		return;
11866b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
11876b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
11886b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	/* More frags present for this completion */
11892e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	index_inc(&rxcp->rxq_idx, rxq->len);
11902e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	remaining = rxcp->pkt_size - curr_frag_len;
11912e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	for (i = 1, j = 0; i < rxcp->num_rcvd; i++) {
119210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		page_info = get_rx_page_info(rxo, rxcp->rxq_idx);
11932e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		curr_frag_len = min(remaining, rx_frag_size);
11946b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
1195bd46cb6cf11867130a41ea9546dd65688b71f3c2Ajit Khaparde		/* Coalesce all frags from the same physical page in one slot */
1196bd46cb6cf11867130a41ea9546dd65688b71f3c2Ajit Khaparde		if (page_info->page_offset == 0) {
1197bd46cb6cf11867130a41ea9546dd65688b71f3c2Ajit Khaparde			/* Fresh page */
1198bd46cb6cf11867130a41ea9546dd65688b71f3c2Ajit Khaparde			j++;
1199b061b39e3ae18ad75466258cf2116e18fa5bbd80Ian Campbell			skb_frag_set_page(skb, j, page_info->page);
1200bd46cb6cf11867130a41ea9546dd65688b71f3c2Ajit Khaparde			skb_shinfo(skb)->frags[j].page_offset =
1201bd46cb6cf11867130a41ea9546dd65688b71f3c2Ajit Khaparde							page_info->page_offset;
12029e903e085262ffbf1fc44a17ac06058aca03524aEric Dumazet			skb_frag_size_set(&skb_shinfo(skb)->frags[j], 0);
1203bd46cb6cf11867130a41ea9546dd65688b71f3c2Ajit Khaparde			skb_shinfo(skb)->nr_frags++;
1204bd46cb6cf11867130a41ea9546dd65688b71f3c2Ajit Khaparde		} else {
1205bd46cb6cf11867130a41ea9546dd65688b71f3c2Ajit Khaparde			put_page(page_info->page);
1206bd46cb6cf11867130a41ea9546dd65688b71f3c2Ajit Khaparde		}
1207bd46cb6cf11867130a41ea9546dd65688b71f3c2Ajit Khaparde
12089e903e085262ffbf1fc44a17ac06058aca03524aEric Dumazet		skb_frag_size_add(&skb_shinfo(skb)->frags[j], curr_frag_len);
12096b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		skb->len += curr_frag_len;
12106b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		skb->data_len += curr_frag_len;
1211bdb28a97f46b5307e6e9351de52a9dd03e711a2fEric Dumazet		skb->truesize += rx_frag_size;
12122e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		remaining -= curr_frag_len;
12132e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		index_inc(&rxcp->rxq_idx, rxq->len);
1214205859a2ff922d0587a819b08007398cbd0a6a30Ajit Khaparde		page_info->page = NULL;
12156b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
1216bd46cb6cf11867130a41ea9546dd65688b71f3c2Ajit Khaparde	BUG_ON(j > MAX_SKB_FRAGS);
12176b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
12186b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
12195be93b9a865344cf69958777c8d7c6f758cba416Ajit Khaparde/* Process the RX completion indicated by rxcp when GRO is disabled */
122010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic void be_rx_compl_process(struct be_rx_obj *rxo,
122110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla				struct be_rx_compl_info *rxcp)
12226b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
122310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_adapter *adapter = rxo->adapter;
12246332c8d3a5e352fae854cbcac764622e083461e5Michał Mirosław	struct net_device *netdev = adapter->netdev;
12256b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct sk_buff *skb;
122689420424fce28769c338909393518087befe8b37Sathya Perla
1227bb349bb4b19b39830e0486aedfd7c7dca23b7bafEric Dumazet	skb = netdev_alloc_skb_ip_align(netdev, BE_RX_SKB_ALLOC_SIZE);
1228a058a632747dd0f1799b12f4ecd54e43f5b5f10dSathya Perla	if (unlikely(!skb)) {
1229ac124ff973e2780279774a30dd924affef758a51Sathya Perla		rx_stats(rxo)->rx_drops_no_skbs++;
123010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		be_rx_compl_discard(rxo, rxcp);
12316b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		return;
12326b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
12336b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
123410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	skb_fill_rx_data(rxo, skb, rxcp);
12356b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
12366332c8d3a5e352fae854cbcac764622e083461e5Michał Mirosław	if (likely((netdev->features & NETIF_F_RXCSUM) && csum_passed(rxcp)))
1237728a9972d1f290608e730b9ccec2061aa81f6609Ajit Khaparde		skb->ip_summed = CHECKSUM_UNNECESSARY;
1238c6ce2f4b270cb1d4d6b6f4f692a12ca2fea13f3fSomnath Kotur	else
1239c6ce2f4b270cb1d4d6b6f4f692a12ca2fea13f3fSomnath Kotur		skb_checksum_none_assert(skb);
12406b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
12416332c8d3a5e352fae854cbcac764622e083461e5Michał Mirosław	skb->protocol = eth_type_trans(skb, netdev);
124210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	if (netdev->features & NETIF_F_RXHASH)
12434b97291429bf59c09a969184a7d2ebde7287e7ebAjit Khaparde		skb->rxhash = rxcp->rss_hash;
12444b97291429bf59c09a969184a7d2ebde7287e7ebAjit Khaparde
12456b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
1246343e43c02850a3abcd22bd144e5bdbc92fdd273cJiri Pirko	if (rxcp->vlanf)
12474c5102f94c175d81790a3a288e85efd4a8a1649aAjit Khaparde		__vlan_hwaccel_put_tag(skb, rxcp->vlan_tag);
12484c5102f94c175d81790a3a288e85efd4a8a1649aAjit Khaparde
12494c5102f94c175d81790a3a288e85efd4a8a1649aAjit Khaparde	netif_receive_skb(skb);
12506b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
12516b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
12525be93b9a865344cf69958777c8d7c6f758cba416Ajit Khaparde/* Process the RX completion indicated by rxcp when GRO is enabled */
125310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlavoid be_rx_compl_process_gro(struct be_rx_obj *rxo, struct napi_struct *napi,
125410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			     struct be_rx_compl_info *rxcp)
12556b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
125610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_adapter *adapter = rxo->adapter;
12576b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_rx_page_info *page_info;
12585be93b9a865344cf69958777c8d7c6f758cba416Ajit Khaparde	struct sk_buff *skb = NULL;
12593abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	struct be_queue_info *rxq = &rxo->q;
12602e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	u16 remaining, curr_frag_len;
12612e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	u16 i, j;
12623968fa1e58896187ee5629db0720d93b9313ad9fAjit Khaparde
126310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	skb = napi_get_frags(napi);
12645be93b9a865344cf69958777c8d7c6f758cba416Ajit Khaparde	if (!skb) {
126510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		be_rx_compl_discard(rxo, rxcp);
12665be93b9a865344cf69958777c8d7c6f758cba416Ajit Khaparde		return;
12675be93b9a865344cf69958777c8d7c6f758cba416Ajit Khaparde	}
12685be93b9a865344cf69958777c8d7c6f758cba416Ajit Khaparde
12692e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	remaining = rxcp->pkt_size;
12702e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	for (i = 0, j = -1; i < rxcp->num_rcvd; i++) {
127110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		page_info = get_rx_page_info(rxo, rxcp->rxq_idx);
12726b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
12736b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		curr_frag_len = min(remaining, rx_frag_size);
12746b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
1275bd46cb6cf11867130a41ea9546dd65688b71f3c2Ajit Khaparde		/* Coalesce all frags from the same physical page in one slot */
1276bd46cb6cf11867130a41ea9546dd65688b71f3c2Ajit Khaparde		if (i == 0 || page_info->page_offset == 0) {
1277bd46cb6cf11867130a41ea9546dd65688b71f3c2Ajit Khaparde			/* First frag or Fresh page */
1278bd46cb6cf11867130a41ea9546dd65688b71f3c2Ajit Khaparde			j++;
1279b061b39e3ae18ad75466258cf2116e18fa5bbd80Ian Campbell			skb_frag_set_page(skb, j, page_info->page);
12805be93b9a865344cf69958777c8d7c6f758cba416Ajit Khaparde			skb_shinfo(skb)->frags[j].page_offset =
12815be93b9a865344cf69958777c8d7c6f758cba416Ajit Khaparde							page_info->page_offset;
12829e903e085262ffbf1fc44a17ac06058aca03524aEric Dumazet			skb_frag_size_set(&skb_shinfo(skb)->frags[j], 0);
1283bd46cb6cf11867130a41ea9546dd65688b71f3c2Ajit Khaparde		} else {
1284bd46cb6cf11867130a41ea9546dd65688b71f3c2Ajit Khaparde			put_page(page_info->page);
1285bd46cb6cf11867130a41ea9546dd65688b71f3c2Ajit Khaparde		}
12869e903e085262ffbf1fc44a17ac06058aca03524aEric Dumazet		skb_frag_size_add(&skb_shinfo(skb)->frags[j], curr_frag_len);
1287bdb28a97f46b5307e6e9351de52a9dd03e711a2fEric Dumazet		skb->truesize += rx_frag_size;
1288bd46cb6cf11867130a41ea9546dd65688b71f3c2Ajit Khaparde		remaining -= curr_frag_len;
12892e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		index_inc(&rxcp->rxq_idx, rxq->len);
12906b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		memset(page_info, 0, sizeof(*page_info));
12916b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
1292bd46cb6cf11867130a41ea9546dd65688b71f3c2Ajit Khaparde	BUG_ON(j > MAX_SKB_FRAGS);
12936b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
12945be93b9a865344cf69958777c8d7c6f758cba416Ajit Khaparde	skb_shinfo(skb)->nr_frags = j + 1;
12952e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	skb->len = rxcp->pkt_size;
12962e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	skb->data_len = rxcp->pkt_size;
12975be93b9a865344cf69958777c8d7c6f758cba416Ajit Khaparde	skb->ip_summed = CHECKSUM_UNNECESSARY;
12984b97291429bf59c09a969184a7d2ebde7287e7ebAjit Khaparde	if (adapter->netdev->features & NETIF_F_RXHASH)
12994b97291429bf59c09a969184a7d2ebde7287e7ebAjit Khaparde		skb->rxhash = rxcp->rss_hash;
13005be93b9a865344cf69958777c8d7c6f758cba416Ajit Khaparde
1301343e43c02850a3abcd22bd144e5bdbc92fdd273cJiri Pirko	if (rxcp->vlanf)
13024c5102f94c175d81790a3a288e85efd4a8a1649aAjit Khaparde		__vlan_hwaccel_put_tag(skb, rxcp->vlan_tag);
13034c5102f94c175d81790a3a288e85efd4a8a1649aAjit Khaparde
130410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	napi_gro_frags(napi);
13052e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla}
13062e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla
130710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic void be_parse_rx_compl_v1(struct be_eth_rx_compl *compl,
130810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla				 struct be_rx_compl_info *rxcp)
13092e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla{
13102e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	rxcp->pkt_size =
13112e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		AMAP_GET_BITS(struct amap_eth_rx_compl_v1, pktsize, compl);
13122e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	rxcp->vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtp, compl);
13132e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	rxcp->err = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, err, compl);
13142e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	rxcp->tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, tcpf, compl);
13159ecb42fda614c4e4f46e95712621510f8d746980Padmanabh Ratnakar	rxcp->udpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, udpf, compl);
13162e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	rxcp->ip_csum =
13172e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		AMAP_GET_BITS(struct amap_eth_rx_compl_v1, ipcksm, compl);
13182e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	rxcp->l4_csum =
13192e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		AMAP_GET_BITS(struct amap_eth_rx_compl_v1, l4_cksm, compl);
13202e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	rxcp->ipv6 =
13212e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		AMAP_GET_BITS(struct amap_eth_rx_compl_v1, ip_version, compl);
13222e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	rxcp->rxq_idx =
13232e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		AMAP_GET_BITS(struct amap_eth_rx_compl_v1, fragndx, compl);
13242e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	rxcp->num_rcvd =
13252e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		AMAP_GET_BITS(struct amap_eth_rx_compl_v1, numfrags, compl);
13262e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	rxcp->pkt_type =
13272e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		AMAP_GET_BITS(struct amap_eth_rx_compl_v1, cast_enc, compl);
13284b97291429bf59c09a969184a7d2ebde7287e7ebAjit Khaparde	rxcp->rss_hash =
13294b97291429bf59c09a969184a7d2ebde7287e7ebAjit Khaparde		AMAP_GET_BITS(struct amap_eth_rx_compl_v1, rsshash, rxcp);
133015d721847f56f32fe9fd43d34db1b32b13de78dcSathya Perla	if (rxcp->vlanf) {
133115d721847f56f32fe9fd43d34db1b32b13de78dcSathya Perla		rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtm,
13323c709f8fb43e07a0403bba4a8ca7ba00ab874994David S. Miller					  compl);
13333c709f8fb43e07a0403bba4a8ca7ba00ab874994David S. Miller		rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vlan_tag,
13343c709f8fb43e07a0403bba4a8ca7ba00ab874994David S. Miller					       compl);
133515d721847f56f32fe9fd43d34db1b32b13de78dcSathya Perla	}
133612004ae99c009a4ff3c8ea0843f1980aa5bcb4eaSathya Perla	rxcp->port = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, port, compl);
13372e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla}
13382e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla
133910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic void be_parse_rx_compl_v0(struct be_eth_rx_compl *compl,
134010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla				 struct be_rx_compl_info *rxcp)
13412e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla{
13422e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	rxcp->pkt_size =
13432e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		AMAP_GET_BITS(struct amap_eth_rx_compl_v0, pktsize, compl);
13442e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	rxcp->vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtp, compl);
13452e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	rxcp->err = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, err, compl);
13462e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	rxcp->tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, tcpf, compl);
13479ecb42fda614c4e4f46e95712621510f8d746980Padmanabh Ratnakar	rxcp->udpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, udpf, compl);
13482e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	rxcp->ip_csum =
13492e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		AMAP_GET_BITS(struct amap_eth_rx_compl_v0, ipcksm, compl);
13502e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	rxcp->l4_csum =
13512e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		AMAP_GET_BITS(struct amap_eth_rx_compl_v0, l4_cksm, compl);
13522e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	rxcp->ipv6 =
13532e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		AMAP_GET_BITS(struct amap_eth_rx_compl_v0, ip_version, compl);
13542e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	rxcp->rxq_idx =
13552e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		AMAP_GET_BITS(struct amap_eth_rx_compl_v0, fragndx, compl);
13562e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	rxcp->num_rcvd =
13572e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		AMAP_GET_BITS(struct amap_eth_rx_compl_v0, numfrags, compl);
13582e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	rxcp->pkt_type =
13592e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		AMAP_GET_BITS(struct amap_eth_rx_compl_v0, cast_enc, compl);
13604b97291429bf59c09a969184a7d2ebde7287e7ebAjit Khaparde	rxcp->rss_hash =
13614b97291429bf59c09a969184a7d2ebde7287e7ebAjit Khaparde		AMAP_GET_BITS(struct amap_eth_rx_compl_v0, rsshash, rxcp);
136215d721847f56f32fe9fd43d34db1b32b13de78dcSathya Perla	if (rxcp->vlanf) {
136315d721847f56f32fe9fd43d34db1b32b13de78dcSathya Perla		rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtm,
13643c709f8fb43e07a0403bba4a8ca7ba00ab874994David S. Miller					  compl);
13653c709f8fb43e07a0403bba4a8ca7ba00ab874994David S. Miller		rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vlan_tag,
13663c709f8fb43e07a0403bba4a8ca7ba00ab874994David S. Miller					       compl);
136715d721847f56f32fe9fd43d34db1b32b13de78dcSathya Perla	}
136812004ae99c009a4ff3c8ea0843f1980aa5bcb4eaSathya Perla	rxcp->port = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, port, compl);
13692e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla}
13702e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla
13712e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perlastatic struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo)
13722e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla{
13732e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	struct be_eth_rx_compl *compl = queue_tail_node(&rxo->cq);
13742e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	struct be_rx_compl_info *rxcp = &rxo->rxcp;
13752e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	struct be_adapter *adapter = rxo->adapter;
13766b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
13772e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	/* For checking the valid bit it is Ok to use either definition as the
13782e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	 * valid bit is at the same position in both v0 and v1 Rx compl */
13792e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	if (compl->dw[offsetof(struct amap_eth_rx_compl_v1, valid) / 32] == 0)
13802e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		return NULL;
13816b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
13822e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	rmb();
13832e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	be_dws_le_to_cpu(compl, sizeof(*compl));
13846b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
13852e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	if (adapter->be3_native)
138610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		be_parse_rx_compl_v1(compl, rxcp);
13872e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	else
138810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		be_parse_rx_compl_v0(compl, rxcp);
13896b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
139015d721847f56f32fe9fd43d34db1b32b13de78dcSathya Perla	if (rxcp->vlanf) {
139115d721847f56f32fe9fd43d34db1b32b13de78dcSathya Perla		/* vlanf could be wrongly set in some cards.
139215d721847f56f32fe9fd43d34db1b32b13de78dcSathya Perla		 * ignore if vtm is not set */
1393752961a11e847e604aeaaa798cac438c1e671ba4Sathya Perla		if ((adapter->function_mode & FLEX10_MODE) && !rxcp->vtm)
139415d721847f56f32fe9fd43d34db1b32b13de78dcSathya Perla			rxcp->vlanf = 0;
13956b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
139615d721847f56f32fe9fd43d34db1b32b13de78dcSathya Perla		if (!lancer_chip(adapter))
13973c709f8fb43e07a0403bba4a8ca7ba00ab874994David S. Miller			rxcp->vlan_tag = swab16(rxcp->vlan_tag);
13986b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
1399939cf3069d31a6e0e335eb5e08ef04895f2d013dSomnath Kotur		if (adapter->pvid == (rxcp->vlan_tag & VLAN_VID_MASK) &&
14003c709f8fb43e07a0403bba4a8ca7ba00ab874994David S. Miller		    !adapter->vlan_tag[rxcp->vlan_tag])
140115d721847f56f32fe9fd43d34db1b32b13de78dcSathya Perla			rxcp->vlanf = 0;
140215d721847f56f32fe9fd43d34db1b32b13de78dcSathya Perla	}
14032e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla
14042e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	/* As the compl has been parsed, reset it; we wont touch it again */
14052e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	compl->dw[offsetof(struct amap_eth_rx_compl_v1, valid) / 32] = 0;
14066b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
14073abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	queue_tail_inc(&rxo->cq);
14086b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return rxcp;
14096b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
14106b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
14111829b086d175ba07a01ff6934fd51a59bc9be4ceEric Dumazetstatic inline struct page *be_alloc_pages(u32 size, gfp_t gfp)
14126b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
14136b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	u32 order = get_order(size);
14141829b086d175ba07a01ff6934fd51a59bc9be4ceEric Dumazet
14156b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (order > 0)
14161829b086d175ba07a01ff6934fd51a59bc9be4ceEric Dumazet		gfp |= __GFP_COMP;
14171829b086d175ba07a01ff6934fd51a59bc9be4ceEric Dumazet	return  alloc_pages(gfp, order);
14186b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
14196b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
14206b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla/*
14216b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla * Allocate a page, split it to fragments of size rx_frag_size and post as
14226b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla * receive buffers to BE
14236b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla */
14241829b086d175ba07a01ff6934fd51a59bc9be4ceEric Dumazetstatic void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp)
14256b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
14263abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	struct be_adapter *adapter = rxo->adapter;
142726d92f9276a56d55511a427fb70bd70886af647aSathya Perla	struct be_rx_page_info *page_info = NULL, *prev_page_info = NULL;
14283abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	struct be_queue_info *rxq = &rxo->q;
14296b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct page *pagep = NULL;
14306b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_eth_rx_d *rxd;
14316b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	u64 page_dmaaddr = 0, frag_dmaaddr;
14326b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	u32 posted, page_offset = 0;
14336b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
14343abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	page_info = &rxo->page_info_tbl[rxq->head];
14356b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	for (posted = 0; posted < MAX_RX_POST && !page_info->page; posted++) {
14366b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		if (!pagep) {
14371829b086d175ba07a01ff6934fd51a59bc9be4ceEric Dumazet			pagep = be_alloc_pages(adapter->big_page_size, gfp);
14386b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			if (unlikely(!pagep)) {
1439ac124ff973e2780279774a30dd924affef758a51Sathya Perla				rx_stats(rxo)->rx_post_fail++;
14406b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla				break;
14416b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			}
14422b7bcebf958c74124220ee8103024def8597b36cIvan Vecera			page_dmaaddr = dma_map_page(&adapter->pdev->dev, pagep,
14432b7bcebf958c74124220ee8103024def8597b36cIvan Vecera						    0, adapter->big_page_size,
14442b7bcebf958c74124220ee8103024def8597b36cIvan Vecera						    DMA_FROM_DEVICE);
14456b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			page_info->page_offset = 0;
14466b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		} else {
14476b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			get_page(pagep);
14486b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			page_info->page_offset = page_offset + rx_frag_size;
14496b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		}
14506b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		page_offset = page_info->page_offset;
14516b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		page_info->page = pagep;
1452fac6da5b7a1b9779ba124ce92314d02378892855FUJITA Tomonori		dma_unmap_addr_set(page_info, bus, page_dmaaddr);
14536b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		frag_dmaaddr = page_dmaaddr + page_info->page_offset;
14546b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
14556b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		rxd = queue_head_node(rxq);
14566b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		rxd->fragpa_lo = cpu_to_le32(frag_dmaaddr & 0xFFFFFFFF);
14576b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		rxd->fragpa_hi = cpu_to_le32(upper_32_bits(frag_dmaaddr));
14586b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
14596b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		/* Any space left in the current big page for another frag? */
14606b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		if ((page_offset + rx_frag_size + rx_frag_size) >
14616b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla					adapter->big_page_size) {
14626b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			pagep = NULL;
14636b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			page_info->last_page_user = true;
14646b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		}
146526d92f9276a56d55511a427fb70bd70886af647aSathya Perla
146626d92f9276a56d55511a427fb70bd70886af647aSathya Perla		prev_page_info = page_info;
146726d92f9276a56d55511a427fb70bd70886af647aSathya Perla		queue_head_inc(rxq);
146810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		page_info = &rxo->page_info_tbl[rxq->head];
14696b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
14706b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (pagep)
147126d92f9276a56d55511a427fb70bd70886af647aSathya Perla		prev_page_info->last_page_user = true;
14726b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
14736b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (posted) {
14746b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		atomic_add(posted, &rxq->used);
14758788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla		be_rxq_notify(adapter, rxq->id, posted);
1476ea1dae11e0baca5d633207fe50fc3cd30a5d68eeSathya Perla	} else if (atomic_read(&rxq->used) == 0) {
1477ea1dae11e0baca5d633207fe50fc3cd30a5d68eeSathya Perla		/* Let be_worker replenish when memory is available */
14783abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla		rxo->rx_post_starved = true;
14796b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
14806b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
14816b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
14825fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perlastatic struct be_eth_tx_compl *be_tx_compl_get(struct be_queue_info *tx_cq)
14836b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
14846b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_eth_tx_compl *txcp = queue_tail_node(tx_cq);
14856b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
14866b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (txcp->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] == 0)
14876b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		return NULL;
14886b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
1489f3eb62d2cc7da7bea4b394dd06f6bc738aa284e7Sathya Perla	rmb();
14906b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	be_dws_le_to_cpu(txcp, sizeof(*txcp));
14916b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
14926b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	txcp->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] = 0;
14936b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
14946b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	queue_tail_inc(tx_cq);
14956b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return txcp;
14966b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
14976b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
14983c8def9776c3d4636291432522ea312f7a44be95Sathya Perlastatic u16 be_tx_compl_process(struct be_adapter *adapter,
14993c8def9776c3d4636291432522ea312f7a44be95Sathya Perla		struct be_tx_obj *txo, u16 last_index)
15006b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
15013c8def9776c3d4636291432522ea312f7a44be95Sathya Perla	struct be_queue_info *txq = &txo->q;
1502a73b796ed85483a2b999d74d197f31f887ffa82dAlexander Duyck	struct be_eth_wrb *wrb;
15033c8def9776c3d4636291432522ea312f7a44be95Sathya Perla	struct sk_buff **sent_skbs = txo->sent_skb_list;
15046b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct sk_buff *sent_skb;
1505ec43b1a64a132303a6800c781bc17c683aedc55bSathya Perla	u16 cur_index, num_wrbs = 1; /* account for hdr wrb */
1506ec43b1a64a132303a6800c781bc17c683aedc55bSathya Perla	bool unmap_skb_hdr = true;
15076b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
1508ec43b1a64a132303a6800c781bc17c683aedc55bSathya Perla	sent_skb = sent_skbs[txq->tail];
15096b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	BUG_ON(!sent_skb);
1510ec43b1a64a132303a6800c781bc17c683aedc55bSathya Perla	sent_skbs[txq->tail] = NULL;
1511ec43b1a64a132303a6800c781bc17c683aedc55bSathya Perla
1512ec43b1a64a132303a6800c781bc17c683aedc55bSathya Perla	/* skip header wrb */
1513a73b796ed85483a2b999d74d197f31f887ffa82dAlexander Duyck	queue_tail_inc(txq);
15146b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
1515ec43b1a64a132303a6800c781bc17c683aedc55bSathya Perla	do {
15166b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		cur_index = txq->tail;
1517a73b796ed85483a2b999d74d197f31f887ffa82dAlexander Duyck		wrb = queue_tail_node(txq);
15182b7bcebf958c74124220ee8103024def8597b36cIvan Vecera		unmap_tx_frag(&adapter->pdev->dev, wrb,
15192b7bcebf958c74124220ee8103024def8597b36cIvan Vecera			      (unmap_skb_hdr && skb_headlen(sent_skb)));
1520ec43b1a64a132303a6800c781bc17c683aedc55bSathya Perla		unmap_skb_hdr = false;
1521ec43b1a64a132303a6800c781bc17c683aedc55bSathya Perla
15226b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		num_wrbs++;
15236b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		queue_tail_inc(txq);
1524ec43b1a64a132303a6800c781bc17c683aedc55bSathya Perla	} while (cur_index != last_index);
15256b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
15266b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	kfree_skb(sent_skb);
15274d586b823acc46c55c889ae1798de236c9d403daPadmanabh Ratnakar	return num_wrbs;
15286b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
15296b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
153010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla/* Return the number of events in the event queue */
153110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic inline int events_get(struct be_eq_obj *eqo)
1532859b1e4ec86840b0d0980f82b626d687be682eb9Sathya Perla{
153310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_eq_entry *eqe;
153410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	int num = 0;
1535859b1e4ec86840b0d0980f82b626d687be682eb9Sathya Perla
153610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	do {
153710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		eqe = queue_tail_node(&eqo->q);
153810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		if (eqe->evt == 0)
153910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			break;
1540859b1e4ec86840b0d0980f82b626d687be682eb9Sathya Perla
154110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		rmb();
154210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		eqe->evt = 0;
154310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		num++;
154410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		queue_tail_inc(&eqo->q);
154510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	} while (true);
154610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
154710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	return num;
1548859b1e4ec86840b0d0980f82b626d687be682eb9Sathya Perla}
1549859b1e4ec86840b0d0980f82b626d687be682eb9Sathya Perla
155010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic int event_handle(struct be_eq_obj *eqo)
1551859b1e4ec86840b0d0980f82b626d687be682eb9Sathya Perla{
155210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	bool rearm = false;
155310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	int num = events_get(eqo);
1554859b1e4ec86840b0d0980f82b626d687be682eb9Sathya Perla
155510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	/* Deal with any spurious interrupts that come without events */
15563c8def9776c3d4636291432522ea312f7a44be95Sathya Perla	if (!num)
15573c8def9776c3d4636291432522ea312f7a44be95Sathya Perla		rearm = true;
15583c8def9776c3d4636291432522ea312f7a44be95Sathya Perla
155910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	be_eq_notify(eqo->adapter, eqo->q.id, rearm, true, num);
1560859b1e4ec86840b0d0980f82b626d687be682eb9Sathya Perla	if (num)
156110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		napi_schedule(&eqo->napi);
1562859b1e4ec86840b0d0980f82b626d687be682eb9Sathya Perla
1563859b1e4ec86840b0d0980f82b626d687be682eb9Sathya Perla	return num;
1564859b1e4ec86840b0d0980f82b626d687be682eb9Sathya Perla}
1565859b1e4ec86840b0d0980f82b626d687be682eb9Sathya Perla
156610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla/* Leaves the EQ is disarmed state */
156710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic void be_eq_clean(struct be_eq_obj *eqo)
1568859b1e4ec86840b0d0980f82b626d687be682eb9Sathya Perla{
156910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	int num = events_get(eqo);
1570859b1e4ec86840b0d0980f82b626d687be682eb9Sathya Perla
157110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	be_eq_notify(eqo->adapter, eqo->q.id, false, true, num);
1572859b1e4ec86840b0d0980f82b626d687be682eb9Sathya Perla}
1573859b1e4ec86840b0d0980f82b626d687be682eb9Sathya Perla
157410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic void be_rx_cq_clean(struct be_rx_obj *rxo)
15756b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
15766b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_rx_page_info *page_info;
15773abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	struct be_queue_info *rxq = &rxo->q;
15783abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	struct be_queue_info *rx_cq = &rxo->cq;
15792e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	struct be_rx_compl_info *rxcp;
15806b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	u16 tail;
15816b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
15826b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	/* First cleanup pending rx completions */
15833abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	while ((rxcp = be_rx_compl_get(rxo)) != NULL) {
158410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		be_rx_compl_discard(rxo, rxcp);
158510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		be_cq_notify(rxo->adapter, rx_cq->id, false, 1);
15866b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
15876b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
15886b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	/* Then free posted rx buffer that were not used */
15896b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	tail = (rxq->head + rxq->len - atomic_read(&rxq->used)) % rxq->len;
1590cdab23b7017693c00dd69fa28bcdf5b0434b3838Sathya Perla	for (; atomic_read(&rxq->used) > 0; index_inc(&tail, rxq->len)) {
159110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		page_info = get_rx_page_info(rxo, tail);
15926b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		put_page(page_info->page);
15936b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		memset(page_info, 0, sizeof(*page_info));
15946b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
15956b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	BUG_ON(atomic_read(&rxq->used));
1596482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla	rxq->tail = rxq->head = 0;
15976b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
15986b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
15990ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perlastatic void be_tx_compl_clean(struct be_adapter *adapter)
16006b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
16010ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla	struct be_tx_obj *txo;
16020ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla	struct be_queue_info *txq;
1603a8e9179a7de196d37410fd3e9528081f22c70a4eSathya Perla	struct be_eth_tx_compl *txcp;
16044d586b823acc46c55c889ae1798de236c9d403daPadmanabh Ratnakar	u16 end_idx, cmpl = 0, timeo = 0, num_wrbs = 0;
1605b03388d6389e8853ddd9ae19d2ba15a6dbbe5d21Sathya Perla	struct sk_buff *sent_skb;
1606b03388d6389e8853ddd9ae19d2ba15a6dbbe5d21Sathya Perla	bool dummy_wrb;
16070ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla	int i, pending_txqs;
1608a8e9179a7de196d37410fd3e9528081f22c70a4eSathya Perla
1609a8e9179a7de196d37410fd3e9528081f22c70a4eSathya Perla	/* Wait for a max of 200ms for all the tx-completions to arrive. */
1610a8e9179a7de196d37410fd3e9528081f22c70a4eSathya Perla	do {
16110ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla		pending_txqs = adapter->num_tx_qs;
16120ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla
16130ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla		for_all_tx_queues(adapter, txo, i) {
16140ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla			txq = &txo->q;
16150ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla			while ((txcp = be_tx_compl_get(&txo->cq))) {
16160ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla				end_idx =
16170ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla					AMAP_GET_BITS(struct amap_eth_tx_compl,
16180ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla						      wrb_index, txcp);
16190ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla				num_wrbs += be_tx_compl_process(adapter, txo,
16200ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla								end_idx);
16210ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla				cmpl++;
16220ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla			}
16230ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla			if (cmpl) {
16240ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla				be_cq_notify(adapter, txo->cq.id, false, cmpl);
16250ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla				atomic_sub(num_wrbs, &txq->used);
16260ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla				cmpl = 0;
16270ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla				num_wrbs = 0;
16280ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla			}
16290ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla			if (atomic_read(&txq->used) == 0)
16300ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla				pending_txqs--;
1631a8e9179a7de196d37410fd3e9528081f22c70a4eSathya Perla		}
1632a8e9179a7de196d37410fd3e9528081f22c70a4eSathya Perla
16330ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla		if (pending_txqs == 0 || ++timeo > 200)
1634a8e9179a7de196d37410fd3e9528081f22c70a4eSathya Perla			break;
1635a8e9179a7de196d37410fd3e9528081f22c70a4eSathya Perla
1636a8e9179a7de196d37410fd3e9528081f22c70a4eSathya Perla		mdelay(1);
1637a8e9179a7de196d37410fd3e9528081f22c70a4eSathya Perla	} while (true);
1638a8e9179a7de196d37410fd3e9528081f22c70a4eSathya Perla
16390ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla	for_all_tx_queues(adapter, txo, i) {
16400ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla		txq = &txo->q;
16410ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla		if (atomic_read(&txq->used))
16420ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla			dev_err(&adapter->pdev->dev, "%d pending tx-compls\n",
16430ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla				atomic_read(&txq->used));
16440ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla
16450ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla		/* free posted tx for which compls will never arrive */
16460ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla		while (atomic_read(&txq->used)) {
16470ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla			sent_skb = txo->sent_skb_list[txq->tail];
16480ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla			end_idx = txq->tail;
16490ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla			num_wrbs = wrb_cnt_for_skb(adapter, sent_skb,
16500ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla						   &dummy_wrb);
16510ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla			index_adv(&end_idx, num_wrbs - 1, txq->len);
16520ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla			num_wrbs = be_tx_compl_process(adapter, txo, end_idx);
16530ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla			atomic_sub(num_wrbs, &txq->used);
16540ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla		}
1655b03388d6389e8853ddd9ae19d2ba15a6dbbe5d21Sathya Perla	}
16566b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
16576b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
165810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic void be_evt_queues_destroy(struct be_adapter *adapter)
165910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla{
166010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_eq_obj *eqo;
166110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	int i;
166210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
166310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	for_all_evt_queues(adapter, eqo, i) {
166410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		be_eq_clean(eqo);
166510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		if (eqo->q.created)
166610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			be_cmd_q_destroy(adapter, &eqo->q, QTYPE_EQ);
166710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		be_queue_free(adapter, &eqo->q);
166810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	}
166910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla}
167010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
167110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic int be_evt_queues_create(struct be_adapter *adapter)
167210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla{
167310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_queue_info *eq;
167410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_eq_obj *eqo;
167510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	int i, rc;
167610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
167710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	adapter->num_evt_qs = num_irqs(adapter);
167810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
167910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	for_all_evt_queues(adapter, eqo, i) {
168010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		eqo->adapter = adapter;
168110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		eqo->tx_budget = BE_TX_BUDGET;
168210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		eqo->idx = i;
168310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		eqo->max_eqd = BE_MAX_EQD;
168410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		eqo->enable_aic = true;
168510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
168610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		eq = &eqo->q;
168710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		rc = be_queue_alloc(adapter, eq, EVNT_Q_LEN,
168810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla					sizeof(struct be_eq_entry));
168910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		if (rc)
169010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			return rc;
169110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
169210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		rc = be_cmd_eq_create(adapter, eq, eqo->cur_eqd);
169310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		if (rc)
169410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			return rc;
169510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	}
16961cfafab965198bc0d9cb794af5065d0797969727Sathya Perla	return 0;
169710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla}
169810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
16995fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perlastatic void be_mcc_queues_destroy(struct be_adapter *adapter)
17005fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla{
17015fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla	struct be_queue_info *q;
17025fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla
17038788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla	q = &adapter->mcc_obj.q;
17045fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla	if (q->created)
17058788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla		be_cmd_q_destroy(adapter, q, QTYPE_MCCQ);
17065fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla	be_queue_free(adapter, q);
17075fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla
17088788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla	q = &adapter->mcc_obj.cq;
17095fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla	if (q->created)
17108788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla		be_cmd_q_destroy(adapter, q, QTYPE_CQ);
17115fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla	be_queue_free(adapter, q);
17125fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla}
17135fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla
17145fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla/* Must be called only after TX qs are created as MCC shares TX EQ */
17155fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perlastatic int be_mcc_queues_create(struct be_adapter *adapter)
17165fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla{
17175fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla	struct be_queue_info *q, *cq;
17185fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla
17198788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla	cq = &adapter->mcc_obj.cq;
17205fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla	if (be_queue_alloc(adapter, cq, MCC_CQ_LEN,
1721efd2e40a8cc891e8f90e0bdde000006bd6201530Sathya Perla			sizeof(struct be_mcc_compl)))
17225fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla		goto err;
17235fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla
172410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	/* Use the default EQ for MCC completions */
172510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	if (be_cmd_cq_create(adapter, cq, &mcc_eqo(adapter)->q, true, 0))
17265fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla		goto mcc_cq_free;
17275fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla
17288788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla	q = &adapter->mcc_obj.q;
17295fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla	if (be_queue_alloc(adapter, q, MCC_Q_LEN, sizeof(struct be_mcc_wrb)))
17305fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla		goto mcc_cq_destroy;
17315fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla
17328788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla	if (be_cmd_mccq_create(adapter, q, cq))
17335fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla		goto mcc_q_free;
17345fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla
17355fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla	return 0;
17365fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla
17375fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perlamcc_q_free:
17385fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla	be_queue_free(adapter, q);
17395fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perlamcc_cq_destroy:
17408788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla	be_cmd_q_destroy(adapter, cq, QTYPE_CQ);
17415fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perlamcc_cq_free:
17425fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla	be_queue_free(adapter, cq);
17435fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perlaerr:
17445fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla	return -1;
17455fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla}
17465fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla
17476b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic void be_tx_queues_destroy(struct be_adapter *adapter)
17486b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
17496b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_queue_info *q;
17503c8def9776c3d4636291432522ea312f7a44be95Sathya Perla	struct be_tx_obj *txo;
17513c8def9776c3d4636291432522ea312f7a44be95Sathya Perla	u8 i;
17526b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
17533c8def9776c3d4636291432522ea312f7a44be95Sathya Perla	for_all_tx_queues(adapter, txo, i) {
17543c8def9776c3d4636291432522ea312f7a44be95Sathya Perla		q = &txo->q;
17553c8def9776c3d4636291432522ea312f7a44be95Sathya Perla		if (q->created)
17563c8def9776c3d4636291432522ea312f7a44be95Sathya Perla			be_cmd_q_destroy(adapter, q, QTYPE_TXQ);
17573c8def9776c3d4636291432522ea312f7a44be95Sathya Perla		be_queue_free(adapter, q);
17586b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
17593c8def9776c3d4636291432522ea312f7a44be95Sathya Perla		q = &txo->cq;
17603c8def9776c3d4636291432522ea312f7a44be95Sathya Perla		if (q->created)
17613c8def9776c3d4636291432522ea312f7a44be95Sathya Perla			be_cmd_q_destroy(adapter, q, QTYPE_CQ);
17623c8def9776c3d4636291432522ea312f7a44be95Sathya Perla		be_queue_free(adapter, q);
17633c8def9776c3d4636291432522ea312f7a44be95Sathya Perla	}
17646b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
17656b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
1766dafc0fe3afa565c88e44f1c243a49ce209f78ba7Sathya Perlastatic int be_num_txqs_want(struct be_adapter *adapter)
1767dafc0fe3afa565c88e44f1c243a49ce209f78ba7Sathya Perla{
176811ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	if (sriov_enabled(adapter) || be_is_mc(adapter) ||
1769dafc0fe3afa565c88e44f1c243a49ce209f78ba7Sathya Perla		lancer_chip(adapter) || !be_physfn(adapter) ||
1770dafc0fe3afa565c88e44f1c243a49ce209f78ba7Sathya Perla		adapter->generation == BE_GEN2)
1771dafc0fe3afa565c88e44f1c243a49ce209f78ba7Sathya Perla		return 1;
1772dafc0fe3afa565c88e44f1c243a49ce209f78ba7Sathya Perla	else
1773dafc0fe3afa565c88e44f1c243a49ce209f78ba7Sathya Perla		return MAX_TX_QS;
1774dafc0fe3afa565c88e44f1c243a49ce209f78ba7Sathya Perla}
1775dafc0fe3afa565c88e44f1c243a49ce209f78ba7Sathya Perla
177610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic int be_tx_cqs_create(struct be_adapter *adapter)
17776b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
177810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_queue_info *cq, *eq;
177910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	int status;
17803c8def9776c3d4636291432522ea312f7a44be95Sathya Perla	struct be_tx_obj *txo;
17813c8def9776c3d4636291432522ea312f7a44be95Sathya Perla	u8 i;
17826b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
1783dafc0fe3afa565c88e44f1c243a49ce209f78ba7Sathya Perla	adapter->num_tx_qs = be_num_txqs_want(adapter);
17843bb62f4f95ba004048bafb460179b5db33aff787Padmanabh Ratnakar	if (adapter->num_tx_qs != MAX_TX_QS) {
17853bb62f4f95ba004048bafb460179b5db33aff787Padmanabh Ratnakar		rtnl_lock();
1786dafc0fe3afa565c88e44f1c243a49ce209f78ba7Sathya Perla		netif_set_real_num_tx_queues(adapter->netdev,
1787dafc0fe3afa565c88e44f1c243a49ce209f78ba7Sathya Perla			adapter->num_tx_qs);
17883bb62f4f95ba004048bafb460179b5db33aff787Padmanabh Ratnakar		rtnl_unlock();
17893bb62f4f95ba004048bafb460179b5db33aff787Padmanabh Ratnakar	}
1790dafc0fe3afa565c88e44f1c243a49ce209f78ba7Sathya Perla
179110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	for_all_tx_queues(adapter, txo, i) {
179210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		cq = &txo->cq;
179310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		status = be_queue_alloc(adapter, cq, TX_CQ_LEN,
179410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla					sizeof(struct be_eth_tx_compl));
179510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		if (status)
179610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			return status;
17973c8def9776c3d4636291432522ea312f7a44be95Sathya Perla
179810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		/* If num_evt_qs is less than num_tx_qs, then more than
179910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		 * one txq share an eq
180010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		 */
180110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		eq = &adapter->eq_obj[i % adapter->num_evt_qs].q;
180210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		status = be_cmd_cq_create(adapter, cq, eq, false, 3);
180310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		if (status)
180410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			return status;
180510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	}
180610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	return 0;
180710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla}
18086b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
180910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic int be_tx_qs_create(struct be_adapter *adapter)
181010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla{
181110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_tx_obj *txo;
181210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	int i, status;
1813fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla
18143c8def9776c3d4636291432522ea312f7a44be95Sathya Perla	for_all_tx_queues(adapter, txo, i) {
181510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		status = be_queue_alloc(adapter, &txo->q, TX_Q_LEN,
181610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla					sizeof(struct be_eth_wrb));
181710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		if (status)
181810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			return status;
18196b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
182010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		status = be_cmd_txq_create(adapter, &txo->q, &txo->cq);
182110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		if (status)
182210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			return status;
18233c8def9776c3d4636291432522ea312f7a44be95Sathya Perla	}
18246b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
182510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	return 0;
18266b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
18276b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
182810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic void be_rx_cqs_destroy(struct be_adapter *adapter)
18296b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
18306b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_queue_info *q;
18313abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	struct be_rx_obj *rxo;
18323abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	int i;
18333abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla
18343abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	for_all_rx_queues(adapter, rxo, i) {
18353abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla		q = &rxo->cq;
18363abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla		if (q->created)
18373abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla			be_cmd_q_destroy(adapter, q, QTYPE_CQ);
18383abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla		be_queue_free(adapter, q);
1839ac6a0c4aab16070d7d55f49a52de33f716ae1d3dSathya Perla	}
1840ac6a0c4aab16070d7d55f49a52de33f716ae1d3dSathya Perla}
1841ac6a0c4aab16070d7d55f49a52de33f716ae1d3dSathya Perla
184210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic int be_rx_cqs_create(struct be_adapter *adapter)
18436b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
184410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_queue_info *eq, *cq;
18453abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	struct be_rx_obj *rxo;
18463abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	int rc, i;
18476b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
184810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	/* We'll create as many RSS rings as there are irqs.
184910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	 * But when there's only one irq there's no use creating RSS rings
185010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	 */
185110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	adapter->num_rx_qs = (num_irqs(adapter) > 1) ?
185210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla				num_irqs(adapter) + 1 : 1;
1853ac6a0c4aab16070d7d55f49a52de33f716ae1d3dSathya Perla
18546b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE;
18553abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	for_all_rx_queues(adapter, rxo, i) {
18563abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla		rxo->adapter = adapter;
18573abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla		cq = &rxo->cq;
18583abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla		rc = be_queue_alloc(adapter, cq, RX_CQ_LEN,
18593abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla				sizeof(struct be_eth_rx_compl));
18603abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla		if (rc)
186110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			return rc;
18623abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla
186310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		eq = &adapter->eq_obj[i % adapter->num_evt_qs].q;
186410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		rc = be_cmd_cq_create(adapter, cq, eq, false, 3);
18653abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla		if (rc)
186610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			return rc;
18673abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	}
18686b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
186910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	if (adapter->num_rx_qs != MAX_RX_QS)
187010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		dev_info(&adapter->pdev->dev,
187110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			"Created only %d receive queues", adapter->num_rx_qs);
18726b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
187310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	return 0;
1874b628bde2b5390776efc30837798d016ec1aa3ebeSathya Perla}
1875b628bde2b5390776efc30837798d016ec1aa3ebeSathya Perla
18766b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic irqreturn_t be_intx(int irq, void *dev)
18776b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
18786b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_adapter *adapter = dev;
187910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	int num_evts;
18806b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
188110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	/* With INTx only one EQ is used */
188210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	num_evts = event_handle(&adapter->eq_obj[0]);
188310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	if (num_evts)
188410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		return IRQ_HANDLED;
188510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	else
188610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		return IRQ_NONE;
18876b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
18886b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
188910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic irqreturn_t be_msix(int irq, void *dev)
18906b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
189110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_eq_obj *eqo = dev;
18926b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
189310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	event_handle(eqo);
18946b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return IRQ_HANDLED;
18956b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
18966b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
18972e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perlastatic inline bool do_gro(struct be_rx_compl_info *rxcp)
18986b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
18992e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	return (rxcp->tcpf && !rxcp->err) ? true : false;
19006b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
19016b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
190210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi,
190310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			int budget)
19046b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
19053abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	struct be_adapter *adapter = rxo->adapter;
19063abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	struct be_queue_info *rx_cq = &rxo->cq;
19072e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla	struct be_rx_compl_info *rxcp;
19086b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	u32 work_done;
19096b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
19106b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	for (work_done = 0; work_done < budget; work_done++) {
19113abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla		rxcp = be_rx_compl_get(rxo);
19126b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		if (!rxcp)
19136b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			break;
19146b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
191512004ae99c009a4ff3c8ea0843f1980aa5bcb4eaSathya Perla		/* Is it a flush compl that has no data */
191612004ae99c009a4ff3c8ea0843f1980aa5bcb4eaSathya Perla		if (unlikely(rxcp->num_rcvd == 0))
191712004ae99c009a4ff3c8ea0843f1980aa5bcb4eaSathya Perla			goto loop_continue;
191812004ae99c009a4ff3c8ea0843f1980aa5bcb4eaSathya Perla
191912004ae99c009a4ff3c8ea0843f1980aa5bcb4eaSathya Perla		/* Discard compl with partial DMA Lancer B0 */
192012004ae99c009a4ff3c8ea0843f1980aa5bcb4eaSathya Perla		if (unlikely(!rxcp->pkt_size)) {
192110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			be_rx_compl_discard(rxo, rxcp);
192212004ae99c009a4ff3c8ea0843f1980aa5bcb4eaSathya Perla			goto loop_continue;
192312004ae99c009a4ff3c8ea0843f1980aa5bcb4eaSathya Perla		}
192412004ae99c009a4ff3c8ea0843f1980aa5bcb4eaSathya Perla
192512004ae99c009a4ff3c8ea0843f1980aa5bcb4eaSathya Perla		/* On BE drop pkts that arrive due to imperfect filtering in
192612004ae99c009a4ff3c8ea0843f1980aa5bcb4eaSathya Perla		 * promiscuous mode on some skews
192712004ae99c009a4ff3c8ea0843f1980aa5bcb4eaSathya Perla		 */
192812004ae99c009a4ff3c8ea0843f1980aa5bcb4eaSathya Perla		if (unlikely(rxcp->port != adapter->port_num &&
192912004ae99c009a4ff3c8ea0843f1980aa5bcb4eaSathya Perla				!lancer_chip(adapter))) {
193010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			be_rx_compl_discard(rxo, rxcp);
193112004ae99c009a4ff3c8ea0843f1980aa5bcb4eaSathya Perla			goto loop_continue;
19326464281161e46254ac39505ad41d21dbe7d1738fSathya Perla		}
1933009dd872d753f854cf13c8334e0055092f539b38Padmanabh Ratnakar
193412004ae99c009a4ff3c8ea0843f1980aa5bcb4eaSathya Perla		if (do_gro(rxcp))
193510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			be_rx_compl_process_gro(rxo, napi, rxcp);
193612004ae99c009a4ff3c8ea0843f1980aa5bcb4eaSathya Perla		else
193710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			be_rx_compl_process(rxo, rxcp);
193812004ae99c009a4ff3c8ea0843f1980aa5bcb4eaSathya Perlaloop_continue:
19392e588f84f254cca0fc3b9f01297d06799b8c85d3Sathya Perla		be_rx_stats_update(rxo, rxcp);
19406b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
19416b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
194210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	if (work_done) {
194310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		be_cq_notify(adapter, rx_cq->id, true, work_done);
19449372cacb300df3ee0a8be8a25bea15d16a95c583Padmanabh Ratnakar
194510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		if (atomic_read(&rxo->q.used) < RX_FRAGS_REFILL_WM)
194610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			be_post_rx_frags(rxo, GFP_ATOMIC);
19476b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
194810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
19496b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return work_done;
19506b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
19516b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
195210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic bool be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo,
195310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			  int budget, int idx)
19546b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
19556b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_eth_tx_compl *txcp;
195610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	int num_wrbs = 0, work_done;
19573c8def9776c3d4636291432522ea312f7a44be95Sathya Perla
195810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	for (work_done = 0; work_done < budget; work_done++) {
195910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		txcp = be_tx_compl_get(&txo->cq);
196010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		if (!txcp)
196110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			break;
196210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		num_wrbs += be_tx_compl_process(adapter, txo,
19633c8def9776c3d4636291432522ea312f7a44be95Sathya Perla				AMAP_GET_BITS(struct amap_eth_tx_compl,
19643c8def9776c3d4636291432522ea312f7a44be95Sathya Perla					wrb_index, txcp));
196510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	}
19666b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
196710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	if (work_done) {
196810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		be_cq_notify(adapter, txo->cq.id, true, work_done);
196910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		atomic_sub(num_wrbs, &txo->q.used);
19703c8def9776c3d4636291432522ea312f7a44be95Sathya Perla
197110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		/* As Tx wrbs have been freed up, wake up netdev queue
197210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		 * if it was stopped due to lack of tx wrbs.  */
197310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		if (__netif_subqueue_stopped(adapter->netdev, idx) &&
197410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			atomic_read(&txo->q.used) < txo->q.len / 2) {
197510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			netif_wake_subqueue(adapter->netdev, idx);
19763c8def9776c3d4636291432522ea312f7a44be95Sathya Perla		}
197710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
197810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		u64_stats_update_begin(&tx_stats(txo)->sync_compl);
197910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		tx_stats(txo)->tx_compl += work_done;
198010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		u64_stats_update_end(&tx_stats(txo)->sync_compl);
19816b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
198210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	return (work_done < budget); /* Done */
198310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla}
19846b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
198510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlaint be_poll(struct napi_struct *napi, int budget)
198610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla{
198710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_eq_obj *eqo = container_of(napi, struct be_eq_obj, napi);
198810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_adapter *adapter = eqo->adapter;
198910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	int max_work = 0, work, i;
199010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	bool tx_done;
1991f31e50a802baae939c49819b8acd8f077019d398Sathya Perla
199210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	/* Process all TXQs serviced by this EQ */
199310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	for (i = eqo->idx; i < adapter->num_tx_qs; i += adapter->num_evt_qs) {
199410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		tx_done = be_process_tx(adapter, &adapter->tx_obj[i],
199510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla					eqo->tx_budget, i);
199610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		if (!tx_done)
199710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			max_work = budget;
1998f31e50a802baae939c49819b8acd8f077019d398Sathya Perla	}
1999f31e50a802baae939c49819b8acd8f077019d398Sathya Perla
200010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	/* This loop will iterate twice for EQ0 in which
200110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	 * completions of the last RXQ (default one) are also processed
200210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	 * For other EQs the loop iterates only once
200310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	 */
200410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	for (i = eqo->idx; i < adapter->num_rx_qs; i += adapter->num_evt_qs) {
200510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		work = be_process_rx(&adapter->rx_obj[i], napi, budget);
200610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		max_work = max(work, max_work);
200710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	}
20086b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
200910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	if (is_mcc_eqo(eqo))
201010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		be_process_mcc(adapter);
201193c86700c0ae3a1407b979073f423e62e29372c1Padmanabh Ratnakar
201210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	if (max_work < budget) {
201310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		napi_complete(napi);
201410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		be_eq_notify(adapter, eqo->q.id, true, false, 0);
201510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	} else {
201610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		/* As we'll continue in polling mode, count and clear events */
201710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		be_eq_notify(adapter, eqo->q.id, false, false, events_get(eqo));
201893c86700c0ae3a1407b979073f423e62e29372c1Padmanabh Ratnakar	}
201910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	return max_work;
20206b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
20216b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
2022d053de911bff69ba7cdda36d3107c1da0fba7ccdAjit Khapardevoid be_detect_dump_ue(struct be_adapter *adapter)
20237c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde{
2024e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar	u32 ue_lo = 0, ue_hi = 0, ue_lo_mask = 0, ue_hi_mask = 0;
2025e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar	u32 sliport_status = 0, sliport_err1 = 0, sliport_err2 = 0;
20267c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	u32 i;
20277c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde
202872f02485626b3e71955e54d227ede1b54021d571Sathya Perla	if (adapter->eeh_err || adapter->ue_detected)
202972f02485626b3e71955e54d227ede1b54021d571Sathya Perla		return;
203072f02485626b3e71955e54d227ede1b54021d571Sathya Perla
2031e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar	if (lancer_chip(adapter)) {
2032e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar		sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
2033e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar		if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
2034e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar			sliport_err1 = ioread32(adapter->db +
2035e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar					SLIPORT_ERROR1_OFFSET);
2036e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar			sliport_err2 = ioread32(adapter->db +
2037e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar					SLIPORT_ERROR2_OFFSET);
2038e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar		}
2039e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar	} else {
2040e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar		pci_read_config_dword(adapter->pdev,
2041e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar				PCICFG_UE_STATUS_LOW, &ue_lo);
2042e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar		pci_read_config_dword(adapter->pdev,
2043e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar				PCICFG_UE_STATUS_HIGH, &ue_hi);
2044e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar		pci_read_config_dword(adapter->pdev,
2045e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar				PCICFG_UE_STATUS_LOW_MASK, &ue_lo_mask);
2046e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar		pci_read_config_dword(adapter->pdev,
2047e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar				PCICFG_UE_STATUS_HI_MASK, &ue_hi_mask);
2048e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar
2049e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar		ue_lo = (ue_lo & (~ue_lo_mask));
2050e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar		ue_hi = (ue_hi & (~ue_hi_mask));
2051e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar	}
20527c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde
2053e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar	if (ue_lo || ue_hi ||
2054e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar		sliport_status & SLIPORT_STATUS_ERR_MASK) {
2055d053de911bff69ba7cdda36d3107c1da0fba7ccdAjit Khaparde		adapter->ue_detected = true;
20567acc2087fa204461871eccfdc913eef15ffd5c8fAjit Khaparde		adapter->eeh_err = true;
2057434b3648e9a58600cea5f3a1a0a7a89048e4df61Sathya Perla		dev_err(&adapter->pdev->dev,
2058434b3648e9a58600cea5f3a1a0a7a89048e4df61Sathya Perla			"Unrecoverable error in the card\n");
2059d053de911bff69ba7cdda36d3107c1da0fba7ccdAjit Khaparde	}
2060d053de911bff69ba7cdda36d3107c1da0fba7ccdAjit Khaparde
2061e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar	if (ue_lo) {
2062e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar		for (i = 0; ue_lo; ue_lo >>= 1, i++) {
2063e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar			if (ue_lo & 1)
20647c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde				dev_err(&adapter->pdev->dev,
20657c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde				"UE: %s bit set\n", ue_status_low_desc[i]);
20667c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde		}
20677c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	}
2068e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar	if (ue_hi) {
2069e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar		for (i = 0; ue_hi; ue_hi >>= 1, i++) {
2070e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar			if (ue_hi & 1)
20717c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde				dev_err(&adapter->pdev->dev,
20727c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde				"UE: %s bit set\n", ue_status_hi_desc[i]);
20737c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde		}
20747c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde	}
20757c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde
2076e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar	if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
2077e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar		dev_err(&adapter->pdev->dev,
2078e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar			"sliport status 0x%x\n", sliport_status);
2079e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar		dev_err(&adapter->pdev->dev,
2080e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar			"sliport error1 0x%x\n", sliport_err1);
2081e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar		dev_err(&adapter->pdev->dev,
2082e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar			"sliport error2 0x%x\n", sliport_err2);
2083e1cfb67acd5e890bbad695000d2c997bfb7f1756Padmanabh Ratnakar	}
20847c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde}
20857c185276e8d820fa50a678c61abd611ee599920eAjit Khaparde
20868d56ff11708e5809c644a6d687a5dff4551043b4Sathya Perlastatic void be_msix_disable(struct be_adapter *adapter)
20878d56ff11708e5809c644a6d687a5dff4551043b4Sathya Perla{
2088ac6a0c4aab16070d7d55f49a52de33f716ae1d3dSathya Perla	if (msix_enabled(adapter)) {
20898d56ff11708e5809c644a6d687a5dff4551043b4Sathya Perla		pci_disable_msix(adapter->pdev);
2090ac6a0c4aab16070d7d55f49a52de33f716ae1d3dSathya Perla		adapter->num_msix_vec = 0;
20913abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	}
20923abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla}
20933abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla
209410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic uint be_num_rss_want(struct be_adapter *adapter)
209510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla{
209610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
209710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	     adapter->num_vfs == 0 && be_physfn(adapter) &&
209810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	     !be_is_mc(adapter))
209910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		return (adapter->be3_native) ? BE3_MAX_RSS_QS : BE2_MAX_RSS_QS;
210010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	else
210110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		return 0;
210210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla}
210310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
21046b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic void be_msix_enable(struct be_adapter *adapter)
21056b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
210610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla#define BE_MIN_MSIX_VECTORS		1
2107ac6a0c4aab16070d7d55f49a52de33f716ae1d3dSathya Perla	int i, status, num_vec;
21086b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
210910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	/* If RSS queues are not used, need a vec for default RX Q */
211010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	num_vec = min(be_num_rss_want(adapter), num_online_cpus());
211110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	num_vec = max(num_vec, BE_MIN_MSIX_VECTORS);
21123abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla
2113ac6a0c4aab16070d7d55f49a52de33f716ae1d3dSathya Perla	for (i = 0; i < num_vec; i++)
21146b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		adapter->msix_entries[i].entry = i;
21156b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
2116ac6a0c4aab16070d7d55f49a52de33f716ae1d3dSathya Perla	status = pci_enable_msix(adapter->pdev, adapter->msix_entries, num_vec);
21173abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	if (status == 0) {
21183abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla		goto done;
21193abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	} else if (status >= BE_MIN_MSIX_VECTORS) {
2120ac6a0c4aab16070d7d55f49a52de33f716ae1d3dSathya Perla		num_vec = status;
21213abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla		if (pci_enable_msix(adapter->pdev, adapter->msix_entries,
2122ac6a0c4aab16070d7d55f49a52de33f716ae1d3dSathya Perla				num_vec) == 0)
21233abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla			goto done;
21243abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	}
21253abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	return;
21263abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perladone:
2127ac6a0c4aab16070d7d55f49a52de33f716ae1d3dSathya Perla	adapter->num_msix_vec = num_vec;
2128ac6a0c4aab16070d7d55f49a52de33f716ae1d3dSathya Perla	return;
21296b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
21306b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
2131f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perlastatic int be_sriov_enable(struct be_adapter *adapter)
2132ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi{
2133344dbf1073d1cea179ed0831547cab2b7ea4ea27Sarveshwar Bandi	be_check_sriov_fn_type(adapter);
213411ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla
21356dedec818ac2a3783581a761b0680e713f78afdeAjit Khaparde#ifdef CONFIG_PCI_IOV
2136ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi	if (be_physfn(adapter) && num_vfs) {
213781be8f0ab47db1171dac0eb8b062291603b57dd4Ajit Khaparde		int status, pos;
213811ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla		u16 dev_vfs;
213981be8f0ab47db1171dac0eb8b062291603b57dd4Ajit Khaparde
214081be8f0ab47db1171dac0eb8b062291603b57dd4Ajit Khaparde		pos = pci_find_ext_capability(adapter->pdev,
214181be8f0ab47db1171dac0eb8b062291603b57dd4Ajit Khaparde						PCI_EXT_CAP_ID_SRIOV);
214281be8f0ab47db1171dac0eb8b062291603b57dd4Ajit Khaparde		pci_read_config_word(adapter->pdev,
214311ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla				     pos + PCI_SRIOV_TOTAL_VF, &dev_vfs);
214481be8f0ab47db1171dac0eb8b062291603b57dd4Ajit Khaparde
214511ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla		adapter->num_vfs = min_t(u16, num_vfs, dev_vfs);
214611ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla		if (adapter->num_vfs != num_vfs)
214781be8f0ab47db1171dac0eb8b062291603b57dd4Ajit Khaparde			dev_info(&adapter->pdev->dev,
214811ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla				 "Device supports %d VFs and not %d\n",
214911ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla				 adapter->num_vfs, num_vfs);
21506dedec818ac2a3783581a761b0680e713f78afdeAjit Khaparde
215111ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla		status = pci_enable_sriov(adapter->pdev, adapter->num_vfs);
215211ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla		if (status)
215311ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla			adapter->num_vfs = 0;
2154f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla
215511ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla		if (adapter->num_vfs) {
2156f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla			adapter->vf_cfg = kcalloc(num_vfs,
2157f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla						sizeof(struct be_vf_cfg),
2158f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla						GFP_KERNEL);
2159f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla			if (!adapter->vf_cfg)
2160f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla				return -ENOMEM;
2161f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla		}
2162ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi	}
2163ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi#endif
2164f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	return 0;
2165ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi}
2166ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi
2167ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandistatic void be_sriov_disable(struct be_adapter *adapter)
2168ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi{
2169ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi#ifdef CONFIG_PCI_IOV
217011ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	if (sriov_enabled(adapter)) {
2171ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi		pci_disable_sriov(adapter->pdev);
2172f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla		kfree(adapter->vf_cfg);
217311ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla		adapter->num_vfs = 0;
2174ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi	}
2175ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi#endif
2176ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi}
2177ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi
2178fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perlastatic inline int be_msix_vec_get(struct be_adapter *adapter,
217910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla				struct be_eq_obj *eqo)
2180b628bde2b5390776efc30837798d016ec1aa3ebeSathya Perla{
218110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	return adapter->msix_entries[eqo->idx].vector;
2182b628bde2b5390776efc30837798d016ec1aa3ebeSathya Perla}
21836b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
2184b628bde2b5390776efc30837798d016ec1aa3ebeSathya Perlastatic int be_msix_register(struct be_adapter *adapter)
2185b628bde2b5390776efc30837798d016ec1aa3ebeSathya Perla{
218610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct net_device *netdev = adapter->netdev;
218710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_eq_obj *eqo;
218810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	int status, i, vec;
21896b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
219010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	for_all_evt_queues(adapter, eqo, i) {
219110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		sprintf(eqo->desc, "%s-q%d", netdev->name, i);
219210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		vec = be_msix_vec_get(adapter, eqo);
219310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		status = request_irq(vec, be_msix, 0, eqo->desc, eqo);
21943abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla		if (status)
21953abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla			goto err_msix;
21963abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	}
2197b628bde2b5390776efc30837798d016ec1aa3ebeSathya Perla
21986b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return 0;
21993abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perlaerr_msix:
220010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	for (i--, eqo = &adapter->eq_obj[i]; i >= 0; i--, eqo--)
220110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		free_irq(be_msix_vec_get(adapter, eqo), eqo);
220210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	dev_warn(&adapter->pdev->dev, "MSIX Request IRQ failed - err %d\n",
220310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		status);
2204ac6a0c4aab16070d7d55f49a52de33f716ae1d3dSathya Perla	be_msix_disable(adapter);
22056b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return status;
22066b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
22076b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
22086b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic int be_irq_register(struct be_adapter *adapter)
22096b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
22106b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct net_device *netdev = adapter->netdev;
22116b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	int status;
22126b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
2213ac6a0c4aab16070d7d55f49a52de33f716ae1d3dSathya Perla	if (msix_enabled(adapter)) {
22146b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		status = be_msix_register(adapter);
22156b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		if (status == 0)
22166b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			goto done;
2217ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi		/* INTx is not supported for VF */
2218ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi		if (!be_physfn(adapter))
2219ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi			return status;
22206b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
22216b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
22226b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	/* INTx */
22236b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	netdev->irq = adapter->pdev->irq;
22246b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	status = request_irq(netdev->irq, be_intx, IRQF_SHARED, netdev->name,
22256b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			adapter);
22266b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (status) {
22276b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		dev_err(&adapter->pdev->dev,
22286b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			"INTx request IRQ failed - err %d\n", status);
22296b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		return status;
22306b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
22316b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perladone:
22326b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	adapter->isr_registered = true;
22336b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return 0;
22346b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
22356b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
22366b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic void be_irq_unregister(struct be_adapter *adapter)
22376b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
22386b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct net_device *netdev = adapter->netdev;
223910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_eq_obj *eqo;
22403abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	int i;
22416b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
22426b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (!adapter->isr_registered)
22436b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		return;
22446b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
22456b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	/* INTx */
2246ac6a0c4aab16070d7d55f49a52de33f716ae1d3dSathya Perla	if (!msix_enabled(adapter)) {
22476b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		free_irq(netdev->irq, adapter);
22486b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		goto done;
22496b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
22506b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
22516b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	/* MSIx */
225210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	for_all_evt_queues(adapter, eqo, i)
225310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		free_irq(be_msix_vec_get(adapter, eqo), eqo);
22543abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla
22556b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perladone:
22566b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	adapter->isr_registered = false;
22576b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
22586b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
225910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic void be_rx_qs_destroy(struct be_adapter *adapter)
2260482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla{
2261482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla	struct be_queue_info *q;
2262482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla	struct be_rx_obj *rxo;
2263482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla	int i;
2264482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla
2265482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla	for_all_rx_queues(adapter, rxo, i) {
2266482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla		q = &rxo->q;
2267482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla		if (q->created) {
2268482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla			be_cmd_rxq_destroy(adapter, q);
2269482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla			/* After the rxq is invalidated, wait for a grace time
2270482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla			 * of 1ms for all dma to end and the flush compl to
2271482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla			 * arrive
2272482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla			 */
2273482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla			mdelay(1);
227410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			be_rx_cq_clean(rxo);
2275482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla		}
227610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		be_queue_free(adapter, q);
2277482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla	}
2278482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla}
2279482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla
2280889cd4b2e529db4988525b0b3e6fb2c095760848Sathya Perlastatic int be_close(struct net_device *netdev)
2281889cd4b2e529db4988525b0b3e6fb2c095760848Sathya Perla{
2282889cd4b2e529db4988525b0b3e6fb2c095760848Sathya Perla	struct be_adapter *adapter = netdev_priv(netdev);
228310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_eq_obj *eqo;
228410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	int i;
2285889cd4b2e529db4988525b0b3e6fb2c095760848Sathya Perla
2286889cd4b2e529db4988525b0b3e6fb2c095760848Sathya Perla	be_async_mcc_disable(adapter);
2287889cd4b2e529db4988525b0b3e6fb2c095760848Sathya Perla
2288fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	if (!lancer_chip(adapter))
2289fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		be_intr_set(adapter, false);
2290889cd4b2e529db4988525b0b3e6fb2c095760848Sathya Perla
229110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	for_all_evt_queues(adapter, eqo, i) {
229210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		napi_disable(&eqo->napi);
229310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		if (msix_enabled(adapter))
229410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			synchronize_irq(be_msix_vec_get(adapter, eqo));
229510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		else
229610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			synchronize_irq(netdev->irq);
229710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		be_eq_clean(eqo);
229863fcb27fdce614ac1b7cc6251bfcb7077f3002b3Padmanabh Ratnakar	}
229963fcb27fdce614ac1b7cc6251bfcb7077f3002b3Padmanabh Ratnakar
2300889cd4b2e529db4988525b0b3e6fb2c095760848Sathya Perla	be_irq_unregister(adapter);
2301889cd4b2e529db4988525b0b3e6fb2c095760848Sathya Perla
2302889cd4b2e529db4988525b0b3e6fb2c095760848Sathya Perla	/* Wait for all pending tx completions to arrive so that
2303889cd4b2e529db4988525b0b3e6fb2c095760848Sathya Perla	 * all tx skbs are freed.
2304889cd4b2e529db4988525b0b3e6fb2c095760848Sathya Perla	 */
23050ae57bb3df562e57ac89ad7bc524b6f2e83235f9Sathya Perla	be_tx_compl_clean(adapter);
2306889cd4b2e529db4988525b0b3e6fb2c095760848Sathya Perla
230710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	be_rx_qs_destroy(adapter);
2308482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla	return 0;
2309482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla}
2310482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla
231110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perlastatic int be_rx_qs_create(struct be_adapter *adapter)
2312482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla{
2313482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla	struct be_rx_obj *rxo;
2314e9008ee99c77207b2f6aee67e5f849b1e1400a11Padmanabh Ratnakar	int rc, i, j;
2315e9008ee99c77207b2f6aee67e5f849b1e1400a11Padmanabh Ratnakar	u8 rsstable[128];
2316482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla
2317482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla	for_all_rx_queues(adapter, rxo, i) {
231810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		rc = be_queue_alloc(adapter, &rxo->q, RX_Q_LEN,
231910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla				    sizeof(struct be_eth_rx_d));
232010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		if (rc)
232110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			return rc;
232210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	}
232310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
232410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	/* The FW would like the default RXQ to be created first */
232510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	rxo = default_rxo(adapter);
232610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	rc = be_cmd_rxq_create(adapter, &rxo->q, rxo->cq.id, rx_frag_size,
232710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla			       adapter->if_handle, false, &rxo->rss_id);
232810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	if (rc)
232910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		return rc;
233010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
233110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	for_all_rss_queues(adapter, rxo, i) {
2332482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla		rc = be_cmd_rxq_create(adapter, &rxo->q, rxo->cq.id,
233310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla				       rx_frag_size, adapter->if_handle,
233410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla				       true, &rxo->rss_id);
2335482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla		if (rc)
2336482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla			return rc;
2337482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla	}
2338482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla
2339482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla	if (be_multi_rxq(adapter)) {
2340e9008ee99c77207b2f6aee67e5f849b1e1400a11Padmanabh Ratnakar		for (j = 0; j < 128; j += adapter->num_rx_qs - 1) {
2341e9008ee99c77207b2f6aee67e5f849b1e1400a11Padmanabh Ratnakar			for_all_rss_queues(adapter, rxo, i) {
2342e9008ee99c77207b2f6aee67e5f849b1e1400a11Padmanabh Ratnakar				if ((j + i) >= 128)
2343e9008ee99c77207b2f6aee67e5f849b1e1400a11Padmanabh Ratnakar					break;
2344e9008ee99c77207b2f6aee67e5f849b1e1400a11Padmanabh Ratnakar				rsstable[j + i] = rxo->rss_id;
2345e9008ee99c77207b2f6aee67e5f849b1e1400a11Padmanabh Ratnakar			}
2346e9008ee99c77207b2f6aee67e5f849b1e1400a11Padmanabh Ratnakar		}
2347e9008ee99c77207b2f6aee67e5f849b1e1400a11Padmanabh Ratnakar		rc = be_cmd_rss_config(adapter, rsstable, 128);
2348482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla		if (rc)
2349482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla			return rc;
2350482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla	}
2351482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla
2352482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla	/* First time posting */
235310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	for_all_rx_queues(adapter, rxo, i)
2354482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla		be_post_rx_frags(rxo, GFP_KERNEL);
2355889cd4b2e529db4988525b0b3e6fb2c095760848Sathya Perla	return 0;
2356889cd4b2e529db4988525b0b3e6fb2c095760848Sathya Perla}
2357889cd4b2e529db4988525b0b3e6fb2c095760848Sathya Perla
23586b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic int be_open(struct net_device *netdev)
23596b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
23606b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_adapter *adapter = netdev_priv(netdev);
236110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_eq_obj *eqo;
23623abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	struct be_rx_obj *rxo;
236310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_tx_obj *txo;
2364b236916a68d923acff15787b5439d7d684c17ae5Ajit Khaparde	u8 link_status;
23653abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	int status, i;
23665fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla
236710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	status = be_rx_qs_create(adapter);
2368482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla	if (status)
2369482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla		goto err;
2370482c9e798738dea847a5e5e0d20692fe80d48a76Sathya Perla
23715fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla	be_irq_register(adapter);
23725fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla
2373fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	if (!lancer_chip(adapter))
2374fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		be_intr_set(adapter, true);
23755fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla
237610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	for_all_rx_queues(adapter, rxo, i)
23773abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla		be_cq_notify(adapter, rxo->cq.id, true, 0);
23785fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla
237910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	for_all_tx_queues(adapter, txo, i)
238010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		be_cq_notify(adapter, txo->cq.id, true, 0);
238110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
23827a1e9b2059d147461cff3dfbabbfb43f296a1eefSathya Perla	be_async_mcc_enable(adapter);
23837a1e9b2059d147461cff3dfbabbfb43f296a1eefSathya Perla
238410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	for_all_evt_queues(adapter, eqo, i) {
238510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		napi_enable(&eqo->napi);
238610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		be_eq_notify(adapter, eqo->q.id, true, false, 0);
238710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	}
238810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
2389b236916a68d923acff15787b5439d7d684c17ae5Ajit Khaparde	status = be_cmd_link_status_query(adapter, NULL, NULL,
2390b236916a68d923acff15787b5439d7d684c17ae5Ajit Khaparde					  &link_status, 0);
2391b236916a68d923acff15787b5439d7d684c17ae5Ajit Khaparde	if (!status)
2392b236916a68d923acff15787b5439d7d684c17ae5Ajit Khaparde		be_link_status_update(adapter, link_status);
2393b236916a68d923acff15787b5439d7d684c17ae5Ajit Khaparde
2394889cd4b2e529db4988525b0b3e6fb2c095760848Sathya Perla	return 0;
2395889cd4b2e529db4988525b0b3e6fb2c095760848Sathya Perlaerr:
2396889cd4b2e529db4988525b0b3e6fb2c095760848Sathya Perla	be_close(adapter->netdev);
2397889cd4b2e529db4988525b0b3e6fb2c095760848Sathya Perla	return -EIO;
23985fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla}
23995fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla
240071d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khapardestatic int be_setup_wol(struct be_adapter *adapter, bool enable)
240171d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde{
240271d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde	struct be_dma_mem cmd;
240371d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde	int status = 0;
240471d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde	u8 mac[ETH_ALEN];
240571d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde
240671d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde	memset(mac, 0, ETH_ALEN);
240771d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde
240871d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde	cmd.size = sizeof(struct be_cmd_req_acpi_wol_magic_config);
24092b7bcebf958c74124220ee8103024def8597b36cIvan Vecera	cmd.va = dma_alloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
24102b7bcebf958c74124220ee8103024def8597b36cIvan Vecera				    GFP_KERNEL);
241171d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde	if (cmd.va == NULL)
241271d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde		return -1;
241371d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde	memset(cmd.va, 0, cmd.size);
241471d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde
241571d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde	if (enable) {
241671d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde		status = pci_write_config_dword(adapter->pdev,
241771d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde			PCICFG_PM_CONTROL_OFFSET, PCICFG_PM_CONTROL_MASK);
241871d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde		if (status) {
241971d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde			dev_err(&adapter->pdev->dev,
24202381a55c88453d3f29fe62d235579a05fc20b7b3Frans Pop				"Could not enable Wake-on-lan\n");
24212b7bcebf958c74124220ee8103024def8597b36cIvan Vecera			dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va,
24222b7bcebf958c74124220ee8103024def8597b36cIvan Vecera					  cmd.dma);
242371d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde			return status;
242471d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde		}
242571d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde		status = be_cmd_enable_magic_wol(adapter,
242671d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde				adapter->netdev->dev_addr, &cmd);
242771d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde		pci_enable_wake(adapter->pdev, PCI_D3hot, 1);
242871d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde		pci_enable_wake(adapter->pdev, PCI_D3cold, 1);
242971d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde	} else {
243071d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde		status = be_cmd_enable_magic_wol(adapter, mac, &cmd);
243171d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde		pci_enable_wake(adapter->pdev, PCI_D3hot, 0);
243271d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde		pci_enable_wake(adapter->pdev, PCI_D3cold, 0);
243371d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde	}
243471d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde
24352b7bcebf958c74124220ee8103024def8597b36cIvan Vecera	dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma);
243671d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde	return status;
243771d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde}
243871d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde
24396d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde/*
24406d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde * Generate a seed MAC address from the PF MAC Address using jhash.
24416d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde * MAC Address for VFs are assigned incrementally starting from the seed.
24426d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde * These addresses are programmed in the ASIC by the PF and the VF driver
24436d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde * queries for the MAC address during its probe.
24446d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde */
24456d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khapardestatic inline int be_vf_eth_addr_config(struct be_adapter *adapter)
24466d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde{
2447f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	u32 vf;
24483abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	int status = 0;
24496d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde	u8 mac[ETH_ALEN];
245011ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	struct be_vf_cfg *vf_cfg;
24516d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde
24526d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde	be_vf_eth_addr_generate(adapter, mac);
24536d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde
245411ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	for_all_vfs(adapter, vf_cfg, vf) {
2455590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar		if (lancer_chip(adapter)) {
2456590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar			status = be_cmd_set_mac_list(adapter,  mac, 1, vf + 1);
2457590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar		} else {
2458590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar			status = be_cmd_pmac_add(adapter, mac,
245911ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla						 vf_cfg->if_handle,
246011ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla						 &vf_cfg->pmac_id, vf + 1);
2461590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar		}
2462590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar
24636d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde		if (status)
24646d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde			dev_err(&adapter->pdev->dev,
2465590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar			"Mac address assignment failed for VF %d\n", vf);
24666d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde		else
246711ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla			memcpy(vf_cfg->mac_addr, mac, ETH_ALEN);
24686d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde
24696d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde		mac[5] += 1;
24706d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde	}
24716d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde	return status;
24726d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde}
24736d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde
2474f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perlastatic void be_vf_clear(struct be_adapter *adapter)
24756d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde{
247611ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	struct be_vf_cfg *vf_cfg;
24776d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde	u32 vf;
24786d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde
247911ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	for_all_vfs(adapter, vf_cfg, vf) {
2480590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar		if (lancer_chip(adapter))
2481590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar			be_cmd_set_mac_list(adapter, NULL, 0, vf + 1);
2482590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar		else
248311ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla			be_cmd_pmac_del(adapter, vf_cfg->if_handle,
248411ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla					vf_cfg->pmac_id, vf + 1);
2485f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla
248611ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla		be_cmd_if_destroy(adapter, vf_cfg->if_handle, vf + 1);
248711ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	}
24886d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde}
24896d87f5c3ac5856bf1309700e2f15e2e7fcd3c578Ajit Khaparde
2490a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perlastatic int be_clear(struct be_adapter *adapter)
2491a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla{
2492fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde	int i = 1;
2493fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde
2494191eb7563164529bc7d6a693742fe5bed33cf004Sathya Perla	if (adapter->flags & BE_FLAGS_WORKER_SCHEDULED) {
2495191eb7563164529bc7d6a693742fe5bed33cf004Sathya Perla		cancel_delayed_work_sync(&adapter->work);
2496191eb7563164529bc7d6a693742fe5bed33cf004Sathya Perla		adapter->flags &= ~BE_FLAGS_WORKER_SCHEDULED;
2497191eb7563164529bc7d6a693742fe5bed33cf004Sathya Perla	}
2498191eb7563164529bc7d6a693742fe5bed33cf004Sathya Perla
249911ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	if (sriov_enabled(adapter))
2500f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla		be_vf_clear(adapter);
2501f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla
2502fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde	for (; adapter->uc_macs > 0; adapter->uc_macs--, i++)
2503fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde		be_cmd_pmac_del(adapter, adapter->if_handle,
2504fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde			adapter->pmac_id[i], 0);
2505fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde
2506f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	be_cmd_if_destroy(adapter, adapter->if_handle,  0);
2507a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla
2508a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla	be_mcc_queues_destroy(adapter);
250910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	be_rx_cqs_destroy(adapter);
2510a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla	be_tx_queues_destroy(adapter);
251110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	be_evt_queues_destroy(adapter);
2512a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla
2513a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla	/* tell fw we're done with firing cmds */
2514a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla	be_cmd_fw_clean(adapter);
251510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
251610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	be_msix_disable(adapter);
2517fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde	kfree(adapter->pmac_id);
2518a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla	return 0;
2519a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla}
2520a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla
252130128031d71741ef7d0e32c345e3bf02aa8a0704Sathya Perlastatic void be_vf_setup_init(struct be_adapter *adapter)
252230128031d71741ef7d0e32c345e3bf02aa8a0704Sathya Perla{
252311ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	struct be_vf_cfg *vf_cfg;
252430128031d71741ef7d0e32c345e3bf02aa8a0704Sathya Perla	int vf;
252530128031d71741ef7d0e32c345e3bf02aa8a0704Sathya Perla
252611ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	for_all_vfs(adapter, vf_cfg, vf) {
252711ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla		vf_cfg->if_handle = -1;
252811ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla		vf_cfg->pmac_id = -1;
252930128031d71741ef7d0e32c345e3bf02aa8a0704Sathya Perla	}
253030128031d71741ef7d0e32c345e3bf02aa8a0704Sathya Perla}
253130128031d71741ef7d0e32c345e3bf02aa8a0704Sathya Perla
2532f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perlastatic int be_vf_setup(struct be_adapter *adapter)
2533f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla{
253411ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	struct be_vf_cfg *vf_cfg;
2535f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	u32 cap_flags, en_flags, vf;
2536f1f3ee1bcc996e21f122442fd8c34de51622c76aAjit Khaparde	u16 def_vlan, lnk_speed;
2537f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	int status;
2538f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla
253930128031d71741ef7d0e32c345e3bf02aa8a0704Sathya Perla	be_vf_setup_init(adapter);
254030128031d71741ef7d0e32c345e3bf02aa8a0704Sathya Perla
2541590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar	cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
2542590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar				BE_IF_FLAGS_MULTICAST;
254311ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	for_all_vfs(adapter, vf_cfg, vf) {
2544f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla		status = be_cmd_if_create(adapter, cap_flags, en_flags, NULL,
254511ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla					  &vf_cfg->if_handle, NULL, vf + 1);
2546f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla		if (status)
2547f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla			goto err;
2548f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	}
2549f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla
2550590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar	status = be_vf_eth_addr_config(adapter);
2551590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar	if (status)
2552590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar		goto err;
2553f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla
255411ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	for_all_vfs(adapter, vf_cfg, vf) {
2555f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla		status = be_cmd_link_status_query(adapter, NULL, &lnk_speed,
2556b236916a68d923acff15787b5439d7d684c17ae5Ajit Khaparde						  NULL, vf + 1);
2557f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla		if (status)
2558f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla			goto err;
255911ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla		vf_cfg->tx_rate = lnk_speed * 10;
2560f1f3ee1bcc996e21f122442fd8c34de51622c76aAjit Khaparde
2561f1f3ee1bcc996e21f122442fd8c34de51622c76aAjit Khaparde		status = be_cmd_get_hsw_config(adapter, &def_vlan,
2562f1f3ee1bcc996e21f122442fd8c34de51622c76aAjit Khaparde				vf + 1, vf_cfg->if_handle);
2563f1f3ee1bcc996e21f122442fd8c34de51622c76aAjit Khaparde		if (status)
2564f1f3ee1bcc996e21f122442fd8c34de51622c76aAjit Khaparde			goto err;
2565f1f3ee1bcc996e21f122442fd8c34de51622c76aAjit Khaparde		vf_cfg->def_vid = def_vlan;
2566f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	}
2567f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	return 0;
2568f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perlaerr:
2569f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	return status;
2570f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla}
2571f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla
257230128031d71741ef7d0e32c345e3bf02aa8a0704Sathya Perlastatic void be_setup_init(struct be_adapter *adapter)
257330128031d71741ef7d0e32c345e3bf02aa8a0704Sathya Perla{
257430128031d71741ef7d0e32c345e3bf02aa8a0704Sathya Perla	adapter->vlan_prio_bmap = 0xff;
257530128031d71741ef7d0e32c345e3bf02aa8a0704Sathya Perla	adapter->link_speed = -1;
257630128031d71741ef7d0e32c345e3bf02aa8a0704Sathya Perla	adapter->if_handle = -1;
257730128031d71741ef7d0e32c345e3bf02aa8a0704Sathya Perla	adapter->be3_native = false;
257830128031d71741ef7d0e32c345e3bf02aa8a0704Sathya Perla	adapter->promiscuous = false;
257930128031d71741ef7d0e32c345e3bf02aa8a0704Sathya Perla	adapter->eq_next_idx = 0;
258030128031d71741ef7d0e32c345e3bf02aa8a0704Sathya Perla}
258130128031d71741ef7d0e32c345e3bf02aa8a0704Sathya Perla
2582e5e1ee89461543043a0144e6dac90547fefe2f89Padmanabh Ratnakarstatic int be_add_mac_from_list(struct be_adapter *adapter, u8 *mac)
2583590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar{
2584590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar	u32 pmac_id;
2585e5e1ee89461543043a0144e6dac90547fefe2f89Padmanabh Ratnakar	int status;
2586e5e1ee89461543043a0144e6dac90547fefe2f89Padmanabh Ratnakar	bool pmac_id_active;
2587e5e1ee89461543043a0144e6dac90547fefe2f89Padmanabh Ratnakar
2588e5e1ee89461543043a0144e6dac90547fefe2f89Padmanabh Ratnakar	status = be_cmd_get_mac_from_list(adapter, 0, &pmac_id_active,
2589e5e1ee89461543043a0144e6dac90547fefe2f89Padmanabh Ratnakar							&pmac_id, mac);
2590590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar	if (status != 0)
2591590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar		goto do_none;
2592e5e1ee89461543043a0144e6dac90547fefe2f89Padmanabh Ratnakar
2593e5e1ee89461543043a0144e6dac90547fefe2f89Padmanabh Ratnakar	if (pmac_id_active) {
2594e5e1ee89461543043a0144e6dac90547fefe2f89Padmanabh Ratnakar		status = be_cmd_mac_addr_query(adapter, mac,
2595e5e1ee89461543043a0144e6dac90547fefe2f89Padmanabh Ratnakar				MAC_ADDRESS_TYPE_NETWORK,
2596e5e1ee89461543043a0144e6dac90547fefe2f89Padmanabh Ratnakar				false, adapter->if_handle, pmac_id);
2597e5e1ee89461543043a0144e6dac90547fefe2f89Padmanabh Ratnakar
2598e5e1ee89461543043a0144e6dac90547fefe2f89Padmanabh Ratnakar		if (!status)
2599fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde			adapter->pmac_id[0] = pmac_id;
2600e5e1ee89461543043a0144e6dac90547fefe2f89Padmanabh Ratnakar	} else {
2601e5e1ee89461543043a0144e6dac90547fefe2f89Padmanabh Ratnakar		status = be_cmd_pmac_add(adapter, mac,
2602fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde				adapter->if_handle, &adapter->pmac_id[0], 0);
2603e5e1ee89461543043a0144e6dac90547fefe2f89Padmanabh Ratnakar	}
2604590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakardo_none:
2605590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar	return status;
2606590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar}
2607590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar
26085fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perlastatic int be_setup(struct be_adapter *adapter)
26095fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla{
26105fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla	struct net_device *netdev = adapter->netdev;
2611f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	u32 cap_flags, en_flags;
2612a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla	u32 tx_fc, rx_fc;
261310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	int status;
2614ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi	u8 mac[ETH_ALEN];
2615ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi
261630128031d71741ef7d0e32c345e3bf02aa8a0704Sathya Perla	be_setup_init(adapter);
26176b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
2618f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	be_cmd_req_native_mode(adapter);
261973d540f282c0d8ce48fafd7fcc844e91f31d4103Sathya Perla
262010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	be_msix_enable(adapter);
262110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
262210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	status = be_evt_queues_create(adapter);
262310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	if (status)
2624a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla		goto err;
26256b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
262610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	status = be_tx_cqs_create(adapter);
262710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	if (status)
262810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		goto err;
262910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
263010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	status = be_rx_cqs_create(adapter);
263110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	if (status)
2632a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla		goto err;
26336b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
2634f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	status = be_mcc_queues_create(adapter);
263510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	if (status)
2636a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla		goto err;
26376b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
2638f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	memset(mac, 0, ETH_ALEN);
2639f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	status = be_cmd_mac_addr_query(adapter, mac, MAC_ADDRESS_TYPE_NETWORK,
2640590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar			true /*permanent */, 0, 0);
2641f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	if (status)
2642f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla		return status;
2643f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN);
2644f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN);
26452903dd654d8788425a9523959b02933ea6555229Sathya Perla
2646f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
2647f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla			BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS;
2648f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	cap_flags = en_flags | BE_IF_FLAGS_MCAST_PROMISCUOUS |
26495d5adb93d0efca8b47cc3e649a41ba650ff3d270Padmanabh Ratnakar			BE_IF_FLAGS_VLAN_PROMISCUOUS | BE_IF_FLAGS_PROMISCUOUS;
26505d5adb93d0efca8b47cc3e649a41ba650ff3d270Padmanabh Ratnakar
2651f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	if (adapter->function_caps & BE_FUNCTION_CAPS_RSS) {
2652f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla		cap_flags |= BE_IF_FLAGS_RSS;
2653f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla		en_flags |= BE_IF_FLAGS_RSS;
2654f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	}
2655f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	status = be_cmd_if_create(adapter, cap_flags, en_flags,
2656f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla			netdev->dev_addr, &adapter->if_handle,
2657fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde			&adapter->pmac_id[0], 0);
26585fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla	if (status != 0)
2659a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla		goto err;
26606b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
2661590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar	 /* The VF's permanent mac queried from card is incorrect.
2662590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar	  * For BEx: Query the mac configued by the PF using if_handle
2663590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar	  * For Lancer: Get and use mac_list to obtain mac address.
2664590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar	  */
2665590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar	if (!be_physfn(adapter)) {
2666590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar		if (lancer_chip(adapter))
2667e5e1ee89461543043a0144e6dac90547fefe2f89Padmanabh Ratnakar			status = be_add_mac_from_list(adapter, mac);
2668590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar		else
2669590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar			status = be_cmd_mac_addr_query(adapter, mac,
2670590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar					MAC_ADDRESS_TYPE_NETWORK, false,
2671590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar					adapter->if_handle, 0);
2672f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla		if (!status) {
2673f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla			memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN);
2674f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla			memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN);
2675f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla		}
2676f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	}
26770dffc83e5b831df1df83dfe32a0c267347f9950bAjit Khaparde
267810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	status = be_tx_qs_create(adapter);
267910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	if (status)
268010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		goto err;
268110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
268204b71175f340d4081680440e1b9cbffcd3f4a13cSathya Perla	be_cmd_get_fw_ver(adapter, adapter->fw_ver, NULL);
26835a56eb10babbcd7b3796dc3c28c271260aa3608dSomnath Kotur
2684a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla	status = be_vid_config(adapter, false, 0);
2685a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla	if (status)
2686a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla		goto err;
26877ab8b0b432cf5110624858e23ef264982e542f17Ajit Khaparde
2688a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla	be_set_rx_mode(adapter->netdev);
26895fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla
2690a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla	status = be_cmd_get_flow_control(adapter, &tx_fc, &rx_fc);
2691590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar	/* For Lancer: It is legal for this cmd to fail on VF */
2692590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar	if (status && (be_physfn(adapter) || !lancer_chip(adapter)))
2693a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla		goto err;
2694590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar
2695a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla	if (rx_fc != adapter->rx_fc || tx_fc != adapter->tx_fc) {
2696a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla		status = be_cmd_set_flow_control(adapter, adapter->tx_fc,
2697a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla					adapter->rx_fc);
2698590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar		/* For Lancer: It is legal for this cmd to fail on VF */
2699590c391dd362479b27a67c8d797ce348c5798b93Padmanabh Ratnakar		if (status && (be_physfn(adapter) || !lancer_chip(adapter)))
2700a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla			goto err;
2701a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla	}
27022dc1deb659d1fc29aaafc2c0b987547d6b383602Sathya Perla
2703a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla	pcie_set_readrq(adapter->pdev, 4096);
27045fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla
270511ac75ed1eb9d8f5ff067fa9a82ebf5075989281Sathya Perla	if (sriov_enabled(adapter)) {
2706f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla		status = be_vf_setup(adapter);
2707f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla		if (status)
2708f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla			goto err;
2709f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	}
2710f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla
2711191eb7563164529bc7d6a693742fe5bed33cf004Sathya Perla	schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
2712191eb7563164529bc7d6a693742fe5bed33cf004Sathya Perla	adapter->flags |= BE_FLAGS_WORKER_SCHEDULED;
2713191eb7563164529bc7d6a693742fe5bed33cf004Sathya Perla
2714f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	return 0;
2715a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perlaerr:
2716a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla	be_clear(adapter);
2717a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla	return status;
2718a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla}
27196b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
27206626873980475f303367f7b709f4703b571cf854Ivan Vecera#ifdef CONFIG_NET_POLL_CONTROLLER
27216626873980475f303367f7b709f4703b571cf854Ivan Vecerastatic void be_netpoll(struct net_device *netdev)
27226626873980475f303367f7b709f4703b571cf854Ivan Vecera{
27236626873980475f303367f7b709f4703b571cf854Ivan Vecera	struct be_adapter *adapter = netdev_priv(netdev);
272410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_eq_obj *eqo;
27256626873980475f303367f7b709f4703b571cf854Ivan Vecera	int i;
27266626873980475f303367f7b709f4703b571cf854Ivan Vecera
272710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	for_all_evt_queues(adapter, eqo, i)
272810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		event_handle(eqo);
272910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
273010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	return;
27316626873980475f303367f7b709f4703b571cf854Ivan Vecera}
27326626873980475f303367f7b709f4703b571cf854Ivan Vecera#endif
27336626873980475f303367f7b709f4703b571cf854Ivan Vecera
273484517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde#define FW_FILE_HDR_SIGN 	"ServerEngines Corp. "
2735fa9a6fed87df1b50804405e700f8d30251d3aaf1Sarveshwar Bandistatic bool be_flash_redboot(struct be_adapter *adapter,
27363f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			const u8 *p, u32 img_start, int image_size,
27373f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			int hdr_size)
2738fa9a6fed87df1b50804405e700f8d30251d3aaf1Sarveshwar Bandi{
2739fa9a6fed87df1b50804405e700f8d30251d3aaf1Sarveshwar Bandi	u32 crc_offset;
2740fa9a6fed87df1b50804405e700f8d30251d3aaf1Sarveshwar Bandi	u8 flashed_crc[4];
2741fa9a6fed87df1b50804405e700f8d30251d3aaf1Sarveshwar Bandi	int status;
27423f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde
27433f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde	crc_offset = hdr_size + img_start + image_size - 4;
27443f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde
2745fa9a6fed87df1b50804405e700f8d30251d3aaf1Sarveshwar Bandi	p += crc_offset;
27463f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde
27473f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde	status = be_cmd_get_flash_crc(adapter, flashed_crc,
2748f510fc64cce4646a1fd3c7e5ba7e36cad7e98f02Ajit Khaparde			(image_size - 4));
2749fa9a6fed87df1b50804405e700f8d30251d3aaf1Sarveshwar Bandi	if (status) {
2750fa9a6fed87df1b50804405e700f8d30251d3aaf1Sarveshwar Bandi		dev_err(&adapter->pdev->dev,
2751fa9a6fed87df1b50804405e700f8d30251d3aaf1Sarveshwar Bandi		"could not get crc from flash, not flashing redboot\n");
2752fa9a6fed87df1b50804405e700f8d30251d3aaf1Sarveshwar Bandi		return false;
2753fa9a6fed87df1b50804405e700f8d30251d3aaf1Sarveshwar Bandi	}
2754fa9a6fed87df1b50804405e700f8d30251d3aaf1Sarveshwar Bandi
2755fa9a6fed87df1b50804405e700f8d30251d3aaf1Sarveshwar Bandi	/*update redboot only if crc does not match*/
2756fa9a6fed87df1b50804405e700f8d30251d3aaf1Sarveshwar Bandi	if (!memcmp(flashed_crc, p, 4))
2757fa9a6fed87df1b50804405e700f8d30251d3aaf1Sarveshwar Bandi		return false;
2758fa9a6fed87df1b50804405e700f8d30251d3aaf1Sarveshwar Bandi	else
2759fa9a6fed87df1b50804405e700f8d30251d3aaf1Sarveshwar Bandi		return true;
2760fa9a6fed87df1b50804405e700f8d30251d3aaf1Sarveshwar Bandi}
2761fa9a6fed87df1b50804405e700f8d30251d3aaf1Sarveshwar Bandi
2762306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perlastatic bool phy_flashing_required(struct be_adapter *adapter)
2763306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla{
2764306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla	int status = 0;
2765306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla	struct be_phy_info phy_info;
2766306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla
2767306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla	status = be_cmd_get_phy_info(adapter, &phy_info);
2768306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla	if (status)
2769306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla		return false;
2770306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla	if ((phy_info.phy_type == TN_8022) &&
2771306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla		(phy_info.interface_type == PHY_TYPE_BASET_10GB)) {
2772306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla		return true;
2773306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla	}
2774306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla	return false;
2775306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla}
2776306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla
27773f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khapardestatic int be_flash_data(struct be_adapter *adapter,
277884517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde			const struct firmware *fw,
27793f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			struct be_dma_mem *flash_cmd, int num_of_images)
27803f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde
278184517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde{
27823f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde	int status = 0, i, filehdr_size = 0;
27833f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde	u32 total_bytes = 0, flash_op;
278484517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde	int num_bytes;
278584517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde	const u8 *p = fw->data;
278684517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde	struct be_cmd_write_flashrom *req = flash_cmd->va;
2787215faf9c5f6e319e97edea9e178123e07825c14dJoe Perches	const struct flash_comp *pflashcomp;
27889fe969345b10931319b3f1e7034fbdeb786de234Sarveshwar Bandi	int num_comp;
27893f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde
2790306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla	static const struct flash_comp gen3_flash_types[10] = {
27913f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		{ FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE,
27923f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			FLASH_IMAGE_MAX_SIZE_g3},
27933f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		{ FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT,
27943f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			FLASH_REDBOOT_IMAGE_MAX_SIZE_g3},
27953f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		{ FLASH_iSCSI_BIOS_START_g3, IMG_TYPE_BIOS,
27963f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			FLASH_BIOS_IMAGE_MAX_SIZE_g3},
27973f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		{ FLASH_PXE_BIOS_START_g3, IMG_TYPE_PXE_BIOS,
27983f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			FLASH_BIOS_IMAGE_MAX_SIZE_g3},
27993f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		{ FLASH_FCoE_BIOS_START_g3, IMG_TYPE_FCOE_BIOS,
28003f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			FLASH_BIOS_IMAGE_MAX_SIZE_g3},
28013f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		{ FLASH_iSCSI_BACKUP_IMAGE_START_g3, IMG_TYPE_ISCSI_BACKUP,
28023f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			FLASH_IMAGE_MAX_SIZE_g3},
28033f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		{ FLASH_FCoE_PRIMARY_IMAGE_START_g3, IMG_TYPE_FCOE_FW_ACTIVE,
28043f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			FLASH_IMAGE_MAX_SIZE_g3},
28053f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		{ FLASH_FCoE_BACKUP_IMAGE_START_g3, IMG_TYPE_FCOE_FW_BACKUP,
28069fe969345b10931319b3f1e7034fbdeb786de234Sarveshwar Bandi			FLASH_IMAGE_MAX_SIZE_g3},
28079fe969345b10931319b3f1e7034fbdeb786de234Sarveshwar Bandi		{ FLASH_NCSI_START_g3, IMG_TYPE_NCSI_FW,
2808306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla			FLASH_NCSI_IMAGE_MAX_SIZE_g3},
2809306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla		{ FLASH_PHY_FW_START_g3, IMG_TYPE_PHY_FW,
2810306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla			FLASH_PHY_FW_IMAGE_MAX_SIZE_g3}
28113f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde	};
2812215faf9c5f6e319e97edea9e178123e07825c14dJoe Perches	static const struct flash_comp gen2_flash_types[8] = {
28133f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		{ FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE,
28143f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			FLASH_IMAGE_MAX_SIZE_g2},
28153f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		{ FLASH_REDBOOT_START_g2, IMG_TYPE_REDBOOT,
28163f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			FLASH_REDBOOT_IMAGE_MAX_SIZE_g2},
28173f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		{ FLASH_iSCSI_BIOS_START_g2, IMG_TYPE_BIOS,
28183f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			FLASH_BIOS_IMAGE_MAX_SIZE_g2},
28193f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		{ FLASH_PXE_BIOS_START_g2, IMG_TYPE_PXE_BIOS,
28203f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			FLASH_BIOS_IMAGE_MAX_SIZE_g2},
28213f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		{ FLASH_FCoE_BIOS_START_g2, IMG_TYPE_FCOE_BIOS,
28223f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			FLASH_BIOS_IMAGE_MAX_SIZE_g2},
28233f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		{ FLASH_iSCSI_BACKUP_IMAGE_START_g2, IMG_TYPE_ISCSI_BACKUP,
28243f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			FLASH_IMAGE_MAX_SIZE_g2},
28253f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		{ FLASH_FCoE_PRIMARY_IMAGE_START_g2, IMG_TYPE_FCOE_FW_ACTIVE,
28263f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			FLASH_IMAGE_MAX_SIZE_g2},
28273f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		{ FLASH_FCoE_BACKUP_IMAGE_START_g2, IMG_TYPE_FCOE_FW_BACKUP,
28283f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			 FLASH_IMAGE_MAX_SIZE_g2}
28293f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde	};
28303f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde
28313f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde	if (adapter->generation == BE_GEN3) {
28323f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		pflashcomp = gen3_flash_types;
28333f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		filehdr_size = sizeof(struct flash_file_hdr_g3);
2834215faf9c5f6e319e97edea9e178123e07825c14dJoe Perches		num_comp = ARRAY_SIZE(gen3_flash_types);
28353f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde	} else {
28363f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		pflashcomp = gen2_flash_types;
28373f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		filehdr_size = sizeof(struct flash_file_hdr_g2);
2838215faf9c5f6e319e97edea9e178123e07825c14dJoe Perches		num_comp = ARRAY_SIZE(gen2_flash_types);
283984517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde	}
28409fe969345b10931319b3f1e7034fbdeb786de234Sarveshwar Bandi	for (i = 0; i < num_comp; i++) {
28419fe969345b10931319b3f1e7034fbdeb786de234Sarveshwar Bandi		if ((pflashcomp[i].optype == IMG_TYPE_NCSI_FW) &&
28429fe969345b10931319b3f1e7034fbdeb786de234Sarveshwar Bandi				memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0)
28439fe969345b10931319b3f1e7034fbdeb786de234Sarveshwar Bandi			continue;
2844306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla		if (pflashcomp[i].optype == IMG_TYPE_PHY_FW) {
2845306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla			if (!phy_flashing_required(adapter))
2846306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla				continue;
2847306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla		}
28483f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) &&
28493f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			(!be_flash_redboot(adapter, fw->data,
2850fae21a4da5767db0c0b481360780d6e8c7f906aeAjit Khaparde			pflashcomp[i].offset, pflashcomp[i].size, filehdr_size +
2851fae21a4da5767db0c0b481360780d6e8c7f906aeAjit Khaparde			(num_of_images * sizeof(struct image_hdr)))))
28523f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			continue;
28533f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		p = fw->data;
28543f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		p += filehdr_size + pflashcomp[i].offset
28553f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			+ (num_of_images * sizeof(struct image_hdr));
2856306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla		if (p + pflashcomp[i].size > fw->data + fw->size)
2857306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla			return -1;
2858306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla		total_bytes = pflashcomp[i].size;
28593f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		while (total_bytes) {
28603f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			if (total_bytes > 32*1024)
28613f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde				num_bytes = 32*1024;
28623f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			else
28633f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde				num_bytes = total_bytes;
28643f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			total_bytes -= num_bytes;
2865306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla			if (!total_bytes) {
2866306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla				if (pflashcomp[i].optype == IMG_TYPE_PHY_FW)
2867306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla					flash_op = FLASHROM_OPER_PHY_FLASH;
2868306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla				else
2869306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla					flash_op = FLASHROM_OPER_FLASH;
2870306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla			} else {
2871306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla				if (pflashcomp[i].optype == IMG_TYPE_PHY_FW)
2872306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla					flash_op = FLASHROM_OPER_PHY_SAVE;
2873306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla				else
2874306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla					flash_op = FLASHROM_OPER_SAVE;
2875306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla			}
28763f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			memcpy(req->params.data_buf, p, num_bytes);
28773f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			p += num_bytes;
28783f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			status = be_cmd_write_flashrom(adapter, flash_cmd,
28793f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde				pflashcomp[i].optype, flash_op, num_bytes);
28803f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			if (status) {
2881306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla				if ((status == ILLEGAL_IOCTL_REQ) &&
2882306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla					(pflashcomp[i].optype ==
2883306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla						IMG_TYPE_PHY_FW))
2884306f13487c9f7d6e3303a547e01e22958a04c666Sathya Perla					break;
28853f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde				dev_err(&adapter->pdev->dev,
28863f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde					"cmd to write to flash rom failed.\n");
28873f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde				return -1;
28883f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			}
288984517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde		}
289084517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde	}
289184517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde	return 0;
289284517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde}
289384517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde
28943f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khapardestatic int get_ufigen_type(struct flash_file_hdr_g2 *fhdr)
28953f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde{
28963f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde	if (fhdr == NULL)
28973f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		return 0;
28983f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde	if (fhdr->build[0] == '3')
28993f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		return BE_GEN3;
29003f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde	else if (fhdr->build[0] == '2')
29013f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		return BE_GEN2;
29023f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde	else
29033f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		return 0;
29043f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde}
29053f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde
2906485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundaraostatic int lancer_fw_download(struct be_adapter *adapter,
2907485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao				const struct firmware *fw)
290884517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde{
2909485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao#define LANCER_FW_DOWNLOAD_CHUNK      (32 * 1024)
2910485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao#define LANCER_FW_DOWNLOAD_LOCATION   "/prg"
291184517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde	struct be_dma_mem flash_cmd;
2912485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	const u8 *data_ptr = NULL;
2913485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	u8 *dest_image_ptr = NULL;
2914485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	size_t image_size = 0;
2915485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	u32 chunk_size = 0;
2916485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	u32 data_written = 0;
2917485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	u32 offset = 0;
2918485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	int status = 0;
2919485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	u8 add_status = 0;
292084517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde
2921485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	if (!IS_ALIGNED(fw->size, sizeof(u32))) {
2922d9efd2af461abb7b54c49c1b7e654d496dd1d379Sarveshwar Bandi		dev_err(&adapter->pdev->dev,
2923485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao			"FW Image not properly aligned. "
2924485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao			"Length must be 4 byte aligned.\n");
2925485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		status = -EINVAL;
2926485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		goto lancer_fw_exit;
2927d9efd2af461abb7b54c49c1b7e654d496dd1d379Sarveshwar Bandi	}
2928d9efd2af461abb7b54c49c1b7e654d496dd1d379Sarveshwar Bandi
2929485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	flash_cmd.size = sizeof(struct lancer_cmd_req_write_object)
2930485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao				+ LANCER_FW_DOWNLOAD_CHUNK;
2931485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size,
2932485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao						&flash_cmd.dma, GFP_KERNEL);
2933485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	if (!flash_cmd.va) {
2934485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		status = -ENOMEM;
2935485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		dev_err(&adapter->pdev->dev,
2936485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao			"Memory allocation failure while flashing\n");
2937485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		goto lancer_fw_exit;
2938485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	}
293984517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde
2940485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	dest_image_ptr = flash_cmd.va +
2941485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao				sizeof(struct lancer_cmd_req_write_object);
2942485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	image_size = fw->size;
2943485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	data_ptr = fw->data;
2944485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao
2945485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	while (image_size) {
2946485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		chunk_size = min_t(u32, image_size, LANCER_FW_DOWNLOAD_CHUNK);
2947485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao
2948485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		/* Copy the image chunk content. */
2949485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		memcpy(dest_image_ptr, data_ptr, chunk_size);
2950485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao
2951485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		status = lancer_cmd_write_object(adapter, &flash_cmd,
2952485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao				chunk_size, offset, LANCER_FW_DOWNLOAD_LOCATION,
2953485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao				&data_written, &add_status);
2954485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao
2955485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		if (status)
2956485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao			break;
2957485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao
2958485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		offset += data_written;
2959485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		data_ptr += data_written;
2960485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		image_size -= data_written;
2961485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	}
2962485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao
2963485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	if (!status) {
2964485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		/* Commit the FW written */
2965485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		status = lancer_cmd_write_object(adapter, &flash_cmd,
2966485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao					0, offset, LANCER_FW_DOWNLOAD_LOCATION,
2967485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao					&data_written, &add_status);
2968485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	}
2969485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao
2970485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	dma_free_coherent(&adapter->pdev->dev, flash_cmd.size, flash_cmd.va,
2971485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao				flash_cmd.dma);
2972485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	if (status) {
2973485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		dev_err(&adapter->pdev->dev,
2974485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao			"Firmware load error. "
2975485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao			"Status code: 0x%x Additional Status: 0x%x\n",
2976485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao			status, add_status);
2977485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		goto lancer_fw_exit;
2978485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	}
2979485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao
2980485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n");
2981485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundaraolancer_fw_exit:
2982485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	return status;
2983485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao}
2984485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao
2985485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundaraostatic int be_fw_download(struct be_adapter *adapter, const struct firmware* fw)
2986485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao{
2987485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	struct flash_file_hdr_g2 *fhdr;
2988485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	struct flash_file_hdr_g3 *fhdr3;
2989485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	struct image_hdr *img_hdr_ptr = NULL;
2990485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	struct be_dma_mem flash_cmd;
2991485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	const u8 *p;
2992485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	int status = 0, i = 0, num_imgs = 0;
299384517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde
299484517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde	p = fw->data;
29953f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde	fhdr = (struct flash_file_hdr_g2 *) p;
299684517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde
299784517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde	flash_cmd.size = sizeof(struct be_cmd_write_flashrom) + 32*1024;
29982b7bcebf958c74124220ee8103024def8597b36cIvan Vecera	flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size,
29992b7bcebf958c74124220ee8103024def8597b36cIvan Vecera					  &flash_cmd.dma, GFP_KERNEL);
300084517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde	if (!flash_cmd.va) {
300184517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde		status = -ENOMEM;
300284517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde		dev_err(&adapter->pdev->dev,
300384517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde			"Memory allocation failure while flashing\n");
3004485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		goto be_fw_exit;
300584517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde	}
300684517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde
30073f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde	if ((adapter->generation == BE_GEN3) &&
30083f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			(get_ufigen_type(fhdr) == BE_GEN3)) {
30093f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		fhdr3 = (struct flash_file_hdr_g3 *) fw->data;
30108b93b710a9cd70d67013b4b0f00df7dfda058064Ajit Khaparde		num_imgs = le32_to_cpu(fhdr3->num_imgs);
30118b93b710a9cd70d67013b4b0f00df7dfda058064Ajit Khaparde		for (i = 0; i < num_imgs; i++) {
30123f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			img_hdr_ptr = (struct image_hdr *) (fw->data +
30133f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde					(sizeof(struct flash_file_hdr_g3) +
30148b93b710a9cd70d67013b4b0f00df7dfda058064Ajit Khaparde					 i * sizeof(struct image_hdr)));
30158b93b710a9cd70d67013b4b0f00df7dfda058064Ajit Khaparde			if (le32_to_cpu(img_hdr_ptr->imageid) == 1)
30168b93b710a9cd70d67013b4b0f00df7dfda058064Ajit Khaparde				status = be_flash_data(adapter, fw, &flash_cmd,
30178b93b710a9cd70d67013b4b0f00df7dfda058064Ajit Khaparde							num_imgs);
30183f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		}
30193f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde	} else if ((adapter->generation == BE_GEN2) &&
30203f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			(get_ufigen_type(fhdr) == BE_GEN2)) {
30213f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		status = be_flash_data(adapter, fw, &flash_cmd, 0);
30223f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde	} else {
30233f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		dev_err(&adapter->pdev->dev,
30243f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde			"UFI and Interface are not compatible for flashing\n");
30253f0d4560aedaa67546eaeb3dc75fcdf68ec21036Ajit Khaparde		status = -1;
302684517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde	}
302784517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde
30282b7bcebf958c74124220ee8103024def8597b36cIvan Vecera	dma_free_coherent(&adapter->pdev->dev, flash_cmd.size, flash_cmd.va,
30292b7bcebf958c74124220ee8103024def8597b36cIvan Vecera			  flash_cmd.dma);
303084517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde	if (status) {
303184517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde		dev_err(&adapter->pdev->dev, "Firmware load error\n");
3032485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		goto be_fw_exit;
303384517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde	}
303484517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde
3035af901ca181d92aac3a7dc265144a9081a86d8f39André Goddard Rosa	dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n");
303684517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde
3037485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundaraobe_fw_exit:
3038485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	return status;
3039485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao}
3040485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao
3041485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundaraoint be_load_fw(struct be_adapter *adapter, u8 *fw_file)
3042485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao{
3043485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	const struct firmware *fw;
3044485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	int status;
3045485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao
3046485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	if (!netif_running(adapter->netdev)) {
3047485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		dev_err(&adapter->pdev->dev,
3048485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao			"Firmware load not allowed (interface is down)\n");
3049485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		return -1;
3050485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	}
3051485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao
3052485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
3053485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	if (status)
3054485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		goto fw_exit;
3055485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao
3056485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file);
3057485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao
3058485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	if (lancer_chip(adapter))
3059485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		status = lancer_fw_download(adapter, fw);
3060485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao	else
3061485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao		status = be_fw_download(adapter, fw);
3062485bf569ba798b4702bc2efbfd3a355fe2c8db04Shripad Nunjundarao
306384517482e19bc775de7b3b4e998dee2f506bc34eAjit Khapardefw_exit:
306484517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde	release_firmware(fw);
306584517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde	return status;
306684517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde}
306784517482e19bc775de7b3b4e998dee2f506bc34eAjit Khaparde
3068e5686ad82ca2aeed7a8f24ffca115c0b7478dec9stephen hemmingerstatic const struct net_device_ops be_netdev_ops = {
30696b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	.ndo_open		= be_open,
30706b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	.ndo_stop		= be_close,
30716b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	.ndo_start_xmit		= be_xmit,
3072a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla	.ndo_set_rx_mode	= be_set_rx_mode,
30736b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	.ndo_set_mac_address	= be_mac_addr_set,
30746b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	.ndo_change_mtu		= be_change_mtu,
3075ab1594e92e6765fd4af316f130eea8f5c920823dSathya Perla	.ndo_get_stats64	= be_get_stats64,
30766b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	.ndo_validate_addr	= eth_validate_addr,
30776b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	.ndo_vlan_rx_add_vid	= be_vlan_add_vid,
30786b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	.ndo_vlan_rx_kill_vid	= be_vlan_rem_vid,
307964600ea5f389858e183d3739776f4667265cc77fAjit Khaparde	.ndo_set_vf_mac		= be_set_vf_mac,
30801da87b7fafebb7874622602f79a5fec0425aede7Ajit Khaparde	.ndo_set_vf_vlan	= be_set_vf_vlan,
3081e1d187353fc0597d24cf3169b1bbc1776058e883Ajit Khaparde	.ndo_set_vf_tx_rate	= be_set_vf_tx_rate,
30826626873980475f303367f7b709f4703b571cf854Ivan Vecera	.ndo_get_vf_config	= be_get_vf_config,
30836626873980475f303367f7b709f4703b571cf854Ivan Vecera#ifdef CONFIG_NET_POLL_CONTROLLER
30846626873980475f303367f7b709f4703b571cf854Ivan Vecera	.ndo_poll_controller	= be_netpoll,
30856626873980475f303367f7b709f4703b571cf854Ivan Vecera#endif
30866b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla};
30876b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
30886b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic void be_netdev_init(struct net_device *netdev)
30896b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
30906b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_adapter *adapter = netdev_priv(netdev);
309110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_eq_obj *eqo;
30923abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	int i;
30936b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
30946332c8d3a5e352fae854cbcac764622e083461e5Michał Mirosław	netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
30958b8ddc68df13032a5666438b48dfb7a86de3a610Michał Mirosław		NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |
30968b8ddc68df13032a5666438b48dfb7a86de3a610Michał Mirosław		NETIF_F_HW_VLAN_TX;
30978b8ddc68df13032a5666438b48dfb7a86de3a610Michał Mirosław	if (be_multi_rxq(adapter))
30988b8ddc68df13032a5666438b48dfb7a86de3a610Michał Mirosław		netdev->hw_features |= NETIF_F_RXHASH;
30996332c8d3a5e352fae854cbcac764622e083461e5Michał Mirosław
31006332c8d3a5e352fae854cbcac764622e083461e5Michał Mirosław	netdev->features |= netdev->hw_features |
31018b8ddc68df13032a5666438b48dfb7a86de3a610Michał Mirosław		NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
31024b97291429bf59c09a969184a7d2ebde7287e7ebAjit Khaparde
3103eb8a50d9a6118a310c0b01d47091a2a5d994b549Padmanabh Ratnakar	netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
31047903264402546f45f9bac8ad2bfdb00d00eb124aMichał Mirosław		NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
310551c59870f324805ed30eaa2c0089b4cb5f9f7c71Ajit Khaparde
3106fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde	netdev->priv_flags |= IFF_UNICAST_FLT;
3107fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde
31086b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	netdev->flags |= IFF_MULTICAST;
31096b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
3110c190e3c8f6b22004b9cdc62ee5e7ba2fa5f74dc7Ajit Khaparde	netif_set_gso_max_size(netdev, 65535);
3111c190e3c8f6b22004b9cdc62ee5e7ba2fa5f74dc7Ajit Khaparde
311210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	netdev->netdev_ops = &be_netdev_ops;
31136b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
31146b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	SET_ETHTOOL_OPS(netdev, &be_ethtool_ops);
31156b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
311610ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	for_all_evt_queues(adapter, eqo, i)
311710ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		netif_napi_add(netdev, &eqo->napi, be_poll, BE_NAPI_WEIGHT);
31186b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
31196b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
31206b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic void be_unmap_pci_bars(struct be_adapter *adapter)
31216b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
31228788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla	if (adapter->csr)
31238788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla		iounmap(adapter->csr);
31248788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla	if (adapter->db)
31258788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla		iounmap(adapter->db);
31266b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
31276b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
31286b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic int be_map_pci_bars(struct be_adapter *adapter)
31296b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
31306b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	u8 __iomem *addr;
3131db3ea7819d035ff01c8260fce364511adfae0eaaSathya Perla	int db_reg;
31326b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
3133fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	if (lancer_chip(adapter)) {
3134fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		addr = ioremap_nocache(pci_resource_start(adapter->pdev, 0),
3135fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla			pci_resource_len(adapter->pdev, 0));
3136fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		if (addr == NULL)
3137fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla			return -ENOMEM;
3138fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		adapter->db = addr;
3139fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		return 0;
3140fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	}
3141fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla
3142ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi	if (be_physfn(adapter)) {
3143ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi		addr = ioremap_nocache(pci_resource_start(adapter->pdev, 2),
3144ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi				pci_resource_len(adapter->pdev, 2));
3145ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi		if (addr == NULL)
3146ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi			return -ENOMEM;
3147ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi		adapter->csr = addr;
3148ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi	}
31496b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
3150ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi	if (adapter->generation == BE_GEN2) {
3151ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi		db_reg = 4;
3152ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi	} else {
3153ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi		if (be_physfn(adapter))
3154ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi			db_reg = 4;
3155ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi		else
3156ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi			db_reg = 0;
3157ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi	}
3158ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi	addr = ioremap_nocache(pci_resource_start(adapter->pdev, db_reg),
3159ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi				pci_resource_len(adapter->pdev, db_reg));
31606b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (addr == NULL)
31616b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		goto pci_map_err;
3162ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi	adapter->db = addr;
3163ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi
31646b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return 0;
31656b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlapci_map_err:
31666b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	be_unmap_pci_bars(adapter);
31676b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return -ENOMEM;
31686b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
31696b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
31706b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
31716b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic void be_ctrl_cleanup(struct be_adapter *adapter)
31726b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
31738788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla	struct be_dma_mem *mem = &adapter->mbox_mem_alloced;
31746b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
31756b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	be_unmap_pci_bars(adapter);
31766b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
31776b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (mem->va)
31782b7bcebf958c74124220ee8103024def8597b36cIvan Vecera		dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va,
31792b7bcebf958c74124220ee8103024def8597b36cIvan Vecera				  mem->dma);
3180e7b909a68cfb83e4bafdadac39534969ce260518Sathya Perla
31815b8821b787495273ba4fb333a3561c6da382a9a7Sathya Perla	mem = &adapter->rx_filter;
3182e7b909a68cfb83e4bafdadac39534969ce260518Sathya Perla	if (mem->va)
31832b7bcebf958c74124220ee8103024def8597b36cIvan Vecera		dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va,
31842b7bcebf958c74124220ee8103024def8597b36cIvan Vecera				  mem->dma);
31856b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
31866b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
31876b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic int be_ctrl_init(struct be_adapter *adapter)
31886b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
31898788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla	struct be_dma_mem *mbox_mem_alloc = &adapter->mbox_mem_alloced;
31908788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla	struct be_dma_mem *mbox_mem_align = &adapter->mbox_mem;
31915b8821b787495273ba4fb333a3561c6da382a9a7Sathya Perla	struct be_dma_mem *rx_filter = &adapter->rx_filter;
31926b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	int status;
31936b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
31946b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	status = be_map_pci_bars(adapter);
31956b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (status)
3196e7b909a68cfb83e4bafdadac39534969ce260518Sathya Perla		goto done;
31976b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
31986b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16;
31992b7bcebf958c74124220ee8103024def8597b36cIvan Vecera	mbox_mem_alloc->va = dma_alloc_coherent(&adapter->pdev->dev,
32002b7bcebf958c74124220ee8103024def8597b36cIvan Vecera						mbox_mem_alloc->size,
32012b7bcebf958c74124220ee8103024def8597b36cIvan Vecera						&mbox_mem_alloc->dma,
32022b7bcebf958c74124220ee8103024def8597b36cIvan Vecera						GFP_KERNEL);
32036b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (!mbox_mem_alloc->va) {
3204e7b909a68cfb83e4bafdadac39534969ce260518Sathya Perla		status = -ENOMEM;
3205e7b909a68cfb83e4bafdadac39534969ce260518Sathya Perla		goto unmap_pci_bars;
32066b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
32076b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	mbox_mem_align->size = sizeof(struct be_mcc_mailbox);
32086b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	mbox_mem_align->va = PTR_ALIGN(mbox_mem_alloc->va, 16);
32096b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16);
32106b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox));
3211e7b909a68cfb83e4bafdadac39534969ce260518Sathya Perla
32125b8821b787495273ba4fb333a3561c6da382a9a7Sathya Perla	rx_filter->size = sizeof(struct be_cmd_req_rx_filter);
32135b8821b787495273ba4fb333a3561c6da382a9a7Sathya Perla	rx_filter->va = dma_alloc_coherent(&adapter->pdev->dev, rx_filter->size,
32145b8821b787495273ba4fb333a3561c6da382a9a7Sathya Perla					&rx_filter->dma, GFP_KERNEL);
32155b8821b787495273ba4fb333a3561c6da382a9a7Sathya Perla	if (rx_filter->va == NULL) {
3216e7b909a68cfb83e4bafdadac39534969ce260518Sathya Perla		status = -ENOMEM;
3217e7b909a68cfb83e4bafdadac39534969ce260518Sathya Perla		goto free_mbox;
3218e7b909a68cfb83e4bafdadac39534969ce260518Sathya Perla	}
32195b8821b787495273ba4fb333a3561c6da382a9a7Sathya Perla	memset(rx_filter->va, 0, rx_filter->size);
3220e7b909a68cfb83e4bafdadac39534969ce260518Sathya Perla
32212984961c388381c1830f95e1c2dc2137301b1009Ivan Vecera	mutex_init(&adapter->mbox_lock);
32228788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla	spin_lock_init(&adapter->mcc_lock);
32238788fdc2a53cf012a43808877eaa6ac7e3c923b4Sathya Perla	spin_lock_init(&adapter->mcc_cq_lock);
3224a8f447bda3ee00e3a3ab080c48db40078ea65221Sathya Perla
3225dd131e76e562fa0c6f9dd53130e8d08d39a0b62cSarveshwar Bandi	init_completion(&adapter->flash_compl);
3226cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	pci_save_state(adapter->pdev);
32276b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return 0;
3228e7b909a68cfb83e4bafdadac39534969ce260518Sathya Perla
3229e7b909a68cfb83e4bafdadac39534969ce260518Sathya Perlafree_mbox:
32302b7bcebf958c74124220ee8103024def8597b36cIvan Vecera	dma_free_coherent(&adapter->pdev->dev, mbox_mem_alloc->size,
32312b7bcebf958c74124220ee8103024def8597b36cIvan Vecera			  mbox_mem_alloc->va, mbox_mem_alloc->dma);
3232e7b909a68cfb83e4bafdadac39534969ce260518Sathya Perla
3233e7b909a68cfb83e4bafdadac39534969ce260518Sathya Perlaunmap_pci_bars:
3234e7b909a68cfb83e4bafdadac39534969ce260518Sathya Perla	be_unmap_pci_bars(adapter);
3235e7b909a68cfb83e4bafdadac39534969ce260518Sathya Perla
3236e7b909a68cfb83e4bafdadac39534969ce260518Sathya Perladone:
3237e7b909a68cfb83e4bafdadac39534969ce260518Sathya Perla	return status;
32386b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
32396b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
32406b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic void be_stats_cleanup(struct be_adapter *adapter)
32416b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
32423abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	struct be_dma_mem *cmd = &adapter->stats_cmd;
32436b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
32446b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (cmd->va)
32452b7bcebf958c74124220ee8103024def8597b36cIvan Vecera		dma_free_coherent(&adapter->pdev->dev, cmd->size,
32462b7bcebf958c74124220ee8103024def8597b36cIvan Vecera				  cmd->va, cmd->dma);
32476b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
32486b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
32496b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic int be_stats_init(struct be_adapter *adapter)
32506b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
32513abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	struct be_dma_mem *cmd = &adapter->stats_cmd;
32526b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
3253005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier	if (adapter->generation == BE_GEN2) {
325489a88ab84b946a90839fb66ca3583a2504c11292Ajit Khaparde		cmd->size = sizeof(struct be_cmd_req_get_stats_v0);
3255005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier	} else {
3256005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier		if (lancer_chip(adapter))
3257005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier			cmd->size = sizeof(struct lancer_cmd_req_pport_stats);
3258005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier		else
3259005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier			cmd->size = sizeof(struct be_cmd_req_get_stats_v1);
3260005d569600b404cae0b356e3c4085290ecc17775Selvin Xavier	}
32612b7bcebf958c74124220ee8103024def8597b36cIvan Vecera	cmd->va = dma_alloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma,
32622b7bcebf958c74124220ee8103024def8597b36cIvan Vecera				     GFP_KERNEL);
32636b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (cmd->va == NULL)
32646b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		return -1;
3265d291b9af1a1a12f59a464494900c6e0db26e2ec3David S. Miller	memset(cmd->va, 0, cmd->size);
32666b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return 0;
32676b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
32686b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
32696b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic void __devexit be_remove(struct pci_dev *pdev)
32706b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
32716b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_adapter *adapter = pci_get_drvdata(pdev);
32728d56ff11708e5809c644a6d687a5dff4551043b4Sathya Perla
32736b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (!adapter)
32746b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		return;
32756b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
32766b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	unregister_netdev(adapter->netdev);
32776b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
32785fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla	be_clear(adapter);
32795fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla
32806b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	be_stats_cleanup(adapter);
32816b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
32826b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	be_ctrl_cleanup(adapter);
32836b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
3284ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi	be_sriov_disable(adapter);
3285ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi
32866b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	pci_set_drvdata(pdev, NULL);
32876b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	pci_release_regions(pdev);
32886b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	pci_disable_device(pdev);
32896b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
32906b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	free_netdev(adapter->netdev);
32916b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
32926b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
32934762f6cec4455f3bbe4ca82c100fe5d85d3c02a2Ajit Khapardebool be_is_wol_supported(struct be_adapter *adapter)
32944762f6cec4455f3bbe4ca82c100fe5d85d3c02a2Ajit Khaparde{
32954762f6cec4455f3bbe4ca82c100fe5d85d3c02a2Ajit Khaparde	return ((adapter->wol_cap & BE_WOL_CAP) &&
32964762f6cec4455f3bbe4ca82c100fe5d85d3c02a2Ajit Khaparde		!be_is_wol_excluded(adapter)) ? true : false;
32974762f6cec4455f3bbe4ca82c100fe5d85d3c02a2Ajit Khaparde}
32984762f6cec4455f3bbe4ca82c100fe5d85d3c02a2Ajit Khaparde
32992243e2e95e24f4c4b1c6575b874ebe0b837d2208Sathya Perlastatic int be_get_config(struct be_adapter *adapter)
33006b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
33016b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	int status;
33026b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
33033abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	status = be_cmd_query_fw_cfg(adapter, &adapter->port_num,
33043abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla			&adapter->function_mode, &adapter->function_caps);
330543a04fdc369ce4fb6718b95e1c930ff8661e65c1Sathya Perla	if (status)
330643a04fdc369ce4fb6718b95e1c930ff8661e65c1Sathya Perla		return status;
330743a04fdc369ce4fb6718b95e1c930ff8661e65c1Sathya Perla
3308752961a11e847e604aeaaa798cac438c1e671ba4Sathya Perla	if (adapter->function_mode & FLEX10_MODE)
3309456d9c962bb5824423fa93277c8f7f5b2e3d5e1cAjit Khaparde		adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/8;
331082903e4bfca1578336a91c0c17839b484c12295dAjit Khaparde	else
331182903e4bfca1578336a91c0c17839b484c12295dAjit Khaparde		adapter->max_vlans = BE_NUM_VLANS_SUPPORTED;
331282903e4bfca1578336a91c0c17839b484c12295dAjit Khaparde
3313fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde	if (be_physfn(adapter))
3314fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde		adapter->max_pmac_cnt = BE_UC_PMAC_COUNT;
3315fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde	else
3316fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde		adapter->max_pmac_cnt = BE_VF_UC_PMAC_COUNT;
3317fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde
3318fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde	/* primary mac needs 1 pmac entry */
3319fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde	adapter->pmac_id = kcalloc(adapter->max_pmac_cnt + 1,
3320fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde				  sizeof(u32), GFP_KERNEL);
3321fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde	if (!adapter->pmac_id)
3322fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde		return -ENOMEM;
3323fbc13f018c0043146f8eccc7d6a6c0e66339e2d5Ajit Khaparde
33249e1453c5c5fe670bb98a6097b262122386b0d3feAjit Khaparde	status = be_cmd_get_cntl_attributes(adapter);
33259e1453c5c5fe670bb98a6097b262122386b0d3feAjit Khaparde	if (status)
33269e1453c5c5fe670bb98a6097b262122386b0d3feAjit Khaparde		return status;
33279e1453c5c5fe670bb98a6097b262122386b0d3feAjit Khaparde
33284762f6cec4455f3bbe4ca82c100fe5d85d3c02a2Ajit Khaparde	status = be_cmd_get_acpi_wol_cap(adapter);
33294762f6cec4455f3bbe4ca82c100fe5d85d3c02a2Ajit Khaparde	if (status) {
33304762f6cec4455f3bbe4ca82c100fe5d85d3c02a2Ajit Khaparde		/* in case of a failure to get wol capabillities
33314762f6cec4455f3bbe4ca82c100fe5d85d3c02a2Ajit Khaparde		 * check the exclusion list to determine WOL capability */
33324762f6cec4455f3bbe4ca82c100fe5d85d3c02a2Ajit Khaparde		if (!be_is_wol_excluded(adapter))
33334762f6cec4455f3bbe4ca82c100fe5d85d3c02a2Ajit Khaparde			adapter->wol_cap |= BE_WOL_CAP;
33344762f6cec4455f3bbe4ca82c100fe5d85d3c02a2Ajit Khaparde	}
33354762f6cec4455f3bbe4ca82c100fe5d85d3c02a2Ajit Khaparde
33364762f6cec4455f3bbe4ca82c100fe5d85d3c02a2Ajit Khaparde	if (be_is_wol_supported(adapter))
33374762f6cec4455f3bbe4ca82c100fe5d85d3c02a2Ajit Khaparde		adapter->wol = true;
33384762f6cec4455f3bbe4ca82c100fe5d85d3c02a2Ajit Khaparde
33392243e2e95e24f4c4b1c6575b874ebe0b837d2208Sathya Perla	return 0;
33406b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
33416b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
3342fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perlastatic int be_dev_family_check(struct be_adapter *adapter)
3343fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla{
3344fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	struct pci_dev *pdev = adapter->pdev;
3345fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	u32 sli_intf = 0, if_type;
3346fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla
3347fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	switch (pdev->device) {
3348fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	case BE_DEVICE_ID1:
3349fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	case OC_DEVICE_ID1:
3350fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		adapter->generation = BE_GEN2;
3351fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		break;
3352fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	case BE_DEVICE_ID2:
3353fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	case OC_DEVICE_ID2:
3354ecedb6ae908e3a8a19942da921a3ffb1c5a0d6abAjit Khaparde	case OC_DEVICE_ID5:
3355fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		adapter->generation = BE_GEN3;
3356fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		break;
3357fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	case OC_DEVICE_ID3:
335812f4d0a8770ab26639091d0b2509b19681daad69Mammatha Edhala	case OC_DEVICE_ID4:
3359fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		pci_read_config_dword(pdev, SLI_INTF_REG_OFFSET, &sli_intf);
3360fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >>
3361fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla						SLI_INTF_IF_TYPE_SHIFT;
3362fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla
3363fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		if (((sli_intf & SLI_INTF_VALID_MASK) != SLI_INTF_VALID) ||
3364fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla			if_type != 0x02) {
3365fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla			dev_err(&pdev->dev, "SLI_INTF reg val is not valid\n");
3366fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla			return -EINVAL;
3367fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		}
3368fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		adapter->sli_family = ((sli_intf & SLI_INTF_FAMILY_MASK) >>
3369fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla					 SLI_INTF_FAMILY_SHIFT);
3370fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		adapter->generation = BE_GEN3;
3371fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		break;
3372fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	default:
3373fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		adapter->generation = 0;
3374fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	}
3375fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	return 0;
3376fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla}
3377fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla
337837eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakarstatic int lancer_wait_ready(struct be_adapter *adapter)
337937eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar{
3380d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar#define SLIPORT_READY_TIMEOUT 30
338137eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar	u32 sliport_status;
338237eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar	int status = 0, i;
338337eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar
338437eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar	for (i = 0; i < SLIPORT_READY_TIMEOUT; i++) {
338537eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar		sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
338637eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar		if (sliport_status & SLIPORT_STATUS_RDY_MASK)
338737eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar			break;
338837eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar
3389d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		msleep(1000);
339037eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar	}
339137eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar
339237eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar	if (i == SLIPORT_READY_TIMEOUT)
339337eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar		status = -1;
339437eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar
339537eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar	return status;
339637eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar}
339737eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar
339837eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakarstatic int lancer_test_and_set_rdy_state(struct be_adapter *adapter)
339937eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar{
340037eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar	int status;
340137eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar	u32 sliport_status, err, reset_needed;
340237eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar	status = lancer_wait_ready(adapter);
340337eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar	if (!status) {
340437eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar		sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
340537eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar		err = sliport_status & SLIPORT_STATUS_ERR_MASK;
340637eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar		reset_needed = sliport_status & SLIPORT_STATUS_RN_MASK;
340737eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar		if (err && reset_needed) {
340837eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar			iowrite32(SLI_PORT_CONTROL_IP_MASK,
340937eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar					adapter->db + SLIPORT_CONTROL_OFFSET);
341037eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar
341137eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar			/* check adapter has corrected the error */
341237eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar			status = lancer_wait_ready(adapter);
341337eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar			sliport_status = ioread32(adapter->db +
341437eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar							SLIPORT_STATUS_OFFSET);
341537eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar			sliport_status &= (SLIPORT_STATUS_ERR_MASK |
341637eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar						SLIPORT_STATUS_RN_MASK);
341737eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar			if (status || sliport_status)
341837eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar				status = -1;
341937eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar		} else if (err || reset_needed) {
342037eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar			status = -1;
342137eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar		}
342237eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar	}
342337eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar	return status;
342437eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar}
342537eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar
3426d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakarstatic void lancer_test_and_recover_fn_err(struct be_adapter *adapter)
3427d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar{
3428d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	int status;
3429d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	u32 sliport_status;
3430d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar
3431d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	if (adapter->eeh_err || adapter->ue_detected)
3432d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		return;
3433d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar
3434d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
3435d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar
3436d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
3437d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		dev_err(&adapter->pdev->dev,
3438d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar				"Adapter in error state."
3439d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar				"Trying to recover.\n");
3440d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar
3441d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		status = lancer_test_and_set_rdy_state(adapter);
3442d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		if (status)
3443d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar			goto err;
3444d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar
3445d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		netif_device_detach(adapter->netdev);
3446d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar
3447d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		if (netif_running(adapter->netdev))
3448d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar			be_close(adapter->netdev);
3449d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar
3450d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		be_clear(adapter);
3451d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar
3452d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		adapter->fw_timeout = false;
3453d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar
3454d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		status = be_setup(adapter);
3455d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		if (status)
3456d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar			goto err;
3457d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar
3458d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		if (netif_running(adapter->netdev)) {
3459d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar			status = be_open(adapter->netdev);
3460d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar			if (status)
3461d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar				goto err;
3462d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		}
3463d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar
3464d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		netif_device_attach(adapter->netdev);
3465d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar
3466d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		dev_err(&adapter->pdev->dev,
3467d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar				"Adapter error recovery succeeded\n");
3468d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	}
3469d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	return;
3470d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakarerr:
3471d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	dev_err(&adapter->pdev->dev,
3472d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar			"Adapter error recovery failed\n");
3473d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar}
3474d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar
3475d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakarstatic void be_worker(struct work_struct *work)
3476d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar{
3477d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	struct be_adapter *adapter =
3478d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		container_of(work, struct be_adapter, work.work);
3479d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	struct be_rx_obj *rxo;
348010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	struct be_eq_obj *eqo;
3481d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	int i;
3482d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar
3483d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	if (lancer_chip(adapter))
3484d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		lancer_test_and_recover_fn_err(adapter);
3485d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar
3486d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	be_detect_dump_ue(adapter);
3487d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar
3488d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	/* when interrupts are not yet enabled, just reap any pending
3489d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	* mcc completions */
3490d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	if (!netif_running(adapter->netdev)) {
349110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		be_process_mcc(adapter);
3492d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		goto reschedule;
3493d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	}
3494d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar
3495d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	if (!adapter->stats_cmd_sent) {
3496d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		if (lancer_chip(adapter))
3497d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar			lancer_cmd_get_pport_stats(adapter,
3498d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar						&adapter->stats_cmd);
3499d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		else
3500d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar			be_cmd_get_stats(adapter, &adapter->stats_cmd);
3501d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	}
3502d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar
3503d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	for_all_rx_queues(adapter, rxo, i) {
3504d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		if (rxo->rx_post_starved) {
3505d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar			rxo->rx_post_starved = false;
3506d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar			be_post_rx_frags(rxo, GFP_KERNEL);
3507d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		}
3508d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	}
3509d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar
351010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	for_all_evt_queues(adapter, eqo, i)
351110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		be_eqd_update(adapter, eqo);
351210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
3513d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakarreschedule:
3514d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	adapter->work_counter++;
3515d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar	schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
3516d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar}
3517d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar
35186b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic int __devinit be_probe(struct pci_dev *pdev,
35196b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			const struct pci_device_id *pdev_id)
35206b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
35216b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	int status = 0;
35226b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_adapter *adapter;
35236b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct net_device *netdev;
35246b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
35256b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	status = pci_enable_device(pdev);
35266b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (status)
35276b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		goto do_none;
35286b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
35296b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	status = pci_request_regions(pdev, DRV_NAME);
35306b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (status)
35316b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		goto disable_dev;
35326b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	pci_set_master(pdev);
35336b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
35343c8def9776c3d4636291432522ea312f7a44be95Sathya Perla	netdev = alloc_etherdev_mq(sizeof(struct be_adapter), MAX_TX_QS);
35356b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (netdev == NULL) {
35366b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		status = -ENOMEM;
35376b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		goto rel_reg;
35386b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
35396b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	adapter = netdev_priv(netdev);
35406b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	adapter->pdev = pdev;
35416b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	pci_set_drvdata(pdev, adapter);
3542fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla
3543fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	status = be_dev_family_check(adapter);
354463657b9c319588cd35ed869e19cc6255dbef0d20Sathya Perla	if (status)
3545fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla		goto free_netdev;
3546fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla
35476b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	adapter->netdev = netdev;
35482243e2e95e24f4c4b1c6575b874ebe0b837d2208Sathya Perla	SET_NETDEV_DEV(netdev, &pdev->dev);
35496b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
35502b7bcebf958c74124220ee8103024def8597b36cIvan Vecera	status = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
35516b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (!status) {
35526b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		netdev->features |= NETIF_F_HIGHDMA;
35536b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	} else {
35542b7bcebf958c74124220ee8103024def8597b36cIvan Vecera		status = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
35556b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		if (status) {
35566b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			dev_err(&pdev->dev, "Could not set PCI DMA Mask\n");
35576b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			goto free_netdev;
35586b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		}
35596b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
35606b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
3561f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	status = be_sriov_enable(adapter);
3562f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla	if (status)
3563f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla		goto free_netdev;
3564ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi
35656b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	status = be_ctrl_init(adapter);
35666b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (status)
3567f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perla		goto disable_sriov;
35686b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
356937eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar	if (lancer_chip(adapter)) {
3570d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		status = lancer_wait_ready(adapter);
3571d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		if (!status) {
3572d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar			iowrite32(SLI_PORT_CONTROL_IP_MASK,
3573d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar					adapter->db + SLIPORT_CONTROL_OFFSET);
3574d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar			status = lancer_test_and_set_rdy_state(adapter);
3575d8110f62c020ebc49108de57510a1482bfcbe86aPadmanabh Ratnakar		}
357637eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar		if (status) {
357737eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar			dev_err(&pdev->dev, "Adapter in non recoverable error\n");
357848f5a19168c228e6533401c563d9fcbc152bc33fAjit Khaparde			goto ctrl_clean;
357937eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar		}
358037eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar	}
358137eed1cbbd446dc2808e1bff717010aa978fc0dePadmanabh Ratnakar
35822243e2e95e24f4c4b1c6575b874ebe0b837d2208Sathya Perla	/* sync up with fw's ready state */
3583ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi	if (be_physfn(adapter)) {
3584ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi		status = be_cmd_POST(adapter);
3585ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi		if (status)
3586ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi			goto ctrl_clean;
3587ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi	}
35886b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
35892243e2e95e24f4c4b1c6575b874ebe0b837d2208Sathya Perla	/* tell fw we're ready to fire cmds */
35902243e2e95e24f4c4b1c6575b874ebe0b837d2208Sathya Perla	status = be_cmd_fw_init(adapter);
35916b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (status)
35922243e2e95e24f4c4b1c6575b874ebe0b837d2208Sathya Perla		goto ctrl_clean;
35932243e2e95e24f4c4b1c6575b874ebe0b837d2208Sathya Perla
3594a4b4dfab6ca808a5d1073cdfb7f39e8ce59f71e2Ajit Khaparde	status = be_cmd_reset_function(adapter);
3595a4b4dfab6ca808a5d1073cdfb7f39e8ce59f71e2Ajit Khaparde	if (status)
3596a4b4dfab6ca808a5d1073cdfb7f39e8ce59f71e2Ajit Khaparde		goto ctrl_clean;
3597556ae19110f2de5ace4733e0c19e5fa01fad08b3Sarveshwar Bandi
359810ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	/* The INTR bit may be set in the card when probed by a kdump kernel
359910ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	 * after a crash.
360010ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	 */
360110ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	if (!lancer_chip(adapter))
360210ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		be_intr_set(adapter, false);
360310ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla
36042243e2e95e24f4c4b1c6575b874ebe0b837d2208Sathya Perla	status = be_stats_init(adapter);
36052243e2e95e24f4c4b1c6575b874ebe0b837d2208Sathya Perla	if (status)
36062243e2e95e24f4c4b1c6575b874ebe0b837d2208Sathya Perla		goto ctrl_clean;
36072243e2e95e24f4c4b1c6575b874ebe0b837d2208Sathya Perla
36082243e2e95e24f4c4b1c6575b874ebe0b837d2208Sathya Perla	status = be_get_config(adapter);
36096b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (status)
36106b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		goto stats_clean;
36116b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
36126b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	INIT_DELAYED_WORK(&adapter->work, be_worker);
3613a54769f51b9495f8313224fea670ab6fe720f4b1Sathya Perla	adapter->rx_fc = adapter->tx_fc = true;
36146b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
36155fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla	status = be_setup(adapter);
36165fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla	if (status)
36173abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla		goto msix_disable;
36182243e2e95e24f4c4b1c6575b874ebe0b837d2208Sathya Perla
36193abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	be_netdev_init(netdev);
36206b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	status = register_netdev(netdev);
36216b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (status != 0)
36225fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla		goto unsetup;
36236b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
362410ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla	dev_info(&pdev->dev, "%s: %s port %d\n", netdev->name, nic_name(pdev),
362510ef9ab4329edd08bccc7a8d34b96b85714195ceSathya Perla		adapter->port_num);
362634b1ef04fc050d171e055f75d6a3384e1323bd38Somnath Kotur
36276b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return 0;
36286b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
36295fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perlaunsetup:
36305fb379ee67a7ec55ff65b467b472f3d69b60ba16Sathya Perla	be_clear(adapter);
36313abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perlamsix_disable:
36323abcdeda59c1d4cf2bf83311ed2d544355ec7c2dSathya Perla	be_msix_disable(adapter);
36336b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastats_clean:
36346b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	be_stats_cleanup(adapter);
36356b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlactrl_clean:
36366b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	be_ctrl_cleanup(adapter);
3637f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perladisable_sriov:
3638ba343c7736b36d62d276e20383588bcf9403d6c6Sarveshwar Bandi	be_sriov_disable(adapter);
3639f9449ab76805a2f0e739f5e85a6d9e32d089f1b2Sathya Perlafree_netdev:
3640fe6d2a38b2076cba515dc95b5dc1589a7ab51c17Sathya Perla	free_netdev(netdev);
36418d56ff11708e5809c644a6d687a5dff4551043b4Sathya Perla	pci_set_drvdata(pdev, NULL);
36426b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlarel_reg:
36436b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	pci_release_regions(pdev);
36446b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perladisable_dev:
36456b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	pci_disable_device(pdev);
36466b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlado_none:
3647c4ca2374312b4de819dd700e72a68395eddb5fcbAjit Khaparde	dev_err(&pdev->dev, "%s initialization failed\n", nic_name(pdev));
36486b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return status;
36496b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
36506b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
36516b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic int be_suspend(struct pci_dev *pdev, pm_message_t state)
36526b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
36536b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_adapter *adapter = pci_get_drvdata(pdev);
36546b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct net_device *netdev =  adapter->netdev;
36556b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
365671d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde	if (adapter->wol)
365771d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde		be_setup_wol(adapter, true);
365871d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde
36596b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	netif_device_detach(netdev);
36606b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (netif_running(netdev)) {
36616b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		rtnl_lock();
36626b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		be_close(netdev);
36636b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		rtnl_unlock();
36646b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
36659b0365f1954b0b54a896171b4438ed42ad7ef02fSarveshwar Bandi	be_clear(adapter);
36666b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
36676b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	pci_save_state(pdev);
36686b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	pci_disable_device(pdev);
36696b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	pci_set_power_state(pdev, pci_choose_state(pdev, state));
36706b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return 0;
36716b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
36726b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
36736b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic int be_resume(struct pci_dev *pdev)
36746b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
36756b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	int status = 0;
36766b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct be_adapter *adapter = pci_get_drvdata(pdev);
36776b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	struct net_device *netdev =  adapter->netdev;
36786b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
36796b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	netif_device_detach(netdev);
36806b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
36816b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	status = pci_enable_device(pdev);
36826b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (status)
36836b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		return status;
36846b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
36856b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	pci_set_power_state(pdev, 0);
36866b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	pci_restore_state(pdev);
36876b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
36882243e2e95e24f4c4b1c6575b874ebe0b837d2208Sathya Perla	/* tell fw we're ready to fire cmds */
36892243e2e95e24f4c4b1c6575b874ebe0b837d2208Sathya Perla	status = be_cmd_fw_init(adapter);
36902243e2e95e24f4c4b1c6575b874ebe0b837d2208Sathya Perla	if (status)
36912243e2e95e24f4c4b1c6575b874ebe0b837d2208Sathya Perla		return status;
36922243e2e95e24f4c4b1c6575b874ebe0b837d2208Sathya Perla
36939b0365f1954b0b54a896171b4438ed42ad7ef02fSarveshwar Bandi	be_setup(adapter);
36946b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	if (netif_running(netdev)) {
36956b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		rtnl_lock();
36966b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		be_open(netdev);
36976b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		rtnl_unlock();
36986b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
36996b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	netif_device_attach(netdev);
370071d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde
370171d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde	if (adapter->wol)
370271d8d1b58aa4025ea73a66a130a98d0ed077f9b1Ajit Khaparde		be_setup_wol(adapter, false);
3703a4ca055fc3124e1b6aee6b491a157cd242ee5226Ajit Khaparde
37046b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return 0;
37056b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
37066b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
370782456b031e3c3b5bf95a7e49bd9b68b146446e76Sathya Perla/*
370882456b031e3c3b5bf95a7e49bd9b68b146446e76Sathya Perla * An FLR will stop BE from DMAing any data.
370982456b031e3c3b5bf95a7e49bd9b68b146446e76Sathya Perla */
371082456b031e3c3b5bf95a7e49bd9b68b146446e76Sathya Perlastatic void be_shutdown(struct pci_dev *pdev)
371182456b031e3c3b5bf95a7e49bd9b68b146446e76Sathya Perla{
371282456b031e3c3b5bf95a7e49bd9b68b146446e76Sathya Perla	struct be_adapter *adapter = pci_get_drvdata(pdev);
371382456b031e3c3b5bf95a7e49bd9b68b146446e76Sathya Perla
37142d5d4154650459b61a8e7097d186a89d89dab8edAjit Khaparde	if (!adapter)
37152d5d4154650459b61a8e7097d186a89d89dab8edAjit Khaparde		return;
371682456b031e3c3b5bf95a7e49bd9b68b146446e76Sathya Perla
37170f4a682882171d81c9e3c33c1094b87a197c09faSathya Perla	cancel_delayed_work_sync(&adapter->work);
3718a4ca055fc3124e1b6aee6b491a157cd242ee5226Ajit Khaparde
37192d5d4154650459b61a8e7097d186a89d89dab8edAjit Khaparde	netif_device_detach(adapter->netdev);
372082456b031e3c3b5bf95a7e49bd9b68b146446e76Sathya Perla
372182456b031e3c3b5bf95a7e49bd9b68b146446e76Sathya Perla	if (adapter->wol)
372282456b031e3c3b5bf95a7e49bd9b68b146446e76Sathya Perla		be_setup_wol(adapter, true);
372382456b031e3c3b5bf95a7e49bd9b68b146446e76Sathya Perla
372457841869197831542f25c739beaeab4465977878Ajit Khaparde	be_cmd_reset_function(adapter);
372557841869197831542f25c739beaeab4465977878Ajit Khaparde
372682456b031e3c3b5bf95a7e49bd9b68b146446e76Sathya Perla	pci_disable_device(pdev);
372782456b031e3c3b5bf95a7e49bd9b68b146446e76Sathya Perla}
372882456b031e3c3b5bf95a7e49bd9b68b146446e76Sathya Perla
3729cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perlastatic pci_ers_result_t be_eeh_err_detected(struct pci_dev *pdev,
3730cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla				pci_channel_state_t state)
3731cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla{
3732cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	struct be_adapter *adapter = pci_get_drvdata(pdev);
3733cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	struct net_device *netdev =  adapter->netdev;
3734cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
3735cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	dev_err(&adapter->pdev->dev, "EEH error detected\n");
3736cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
3737cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	adapter->eeh_err = true;
3738cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
3739cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	netif_device_detach(netdev);
3740cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
3741cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	if (netif_running(netdev)) {
3742cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla		rtnl_lock();
3743cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla		be_close(netdev);
3744cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla		rtnl_unlock();
3745cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	}
3746cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	be_clear(adapter);
3747cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
3748cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	if (state == pci_channel_io_perm_failure)
3749cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla		return PCI_ERS_RESULT_DISCONNECT;
3750cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
3751cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	pci_disable_device(pdev);
3752cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
3753cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	return PCI_ERS_RESULT_NEED_RESET;
3754cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla}
3755cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
3756cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perlastatic pci_ers_result_t be_eeh_reset(struct pci_dev *pdev)
3757cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla{
3758cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	struct be_adapter *adapter = pci_get_drvdata(pdev);
3759cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	int status;
3760cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
3761cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	dev_info(&adapter->pdev->dev, "EEH reset\n");
3762cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	adapter->eeh_err = false;
37636589ade019dcab245d3bb847370f855b56cdf6adSathya Perla	adapter->ue_detected = false;
37646589ade019dcab245d3bb847370f855b56cdf6adSathya Perla	adapter->fw_timeout = false;
3765cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
3766cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	status = pci_enable_device(pdev);
3767cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	if (status)
3768cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla		return PCI_ERS_RESULT_DISCONNECT;
3769cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
3770cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	pci_set_master(pdev);
3771cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	pci_set_power_state(pdev, 0);
3772cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	pci_restore_state(pdev);
3773cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
3774cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	/* Check if card is ok and fw is ready */
3775cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	status = be_cmd_POST(adapter);
3776cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	if (status)
3777cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla		return PCI_ERS_RESULT_DISCONNECT;
3778cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
3779cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	return PCI_ERS_RESULT_RECOVERED;
3780cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla}
3781cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
3782cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perlastatic void be_eeh_resume(struct pci_dev *pdev)
3783cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla{
3784cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	int status = 0;
3785cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	struct be_adapter *adapter = pci_get_drvdata(pdev);
3786cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	struct net_device *netdev =  adapter->netdev;
3787cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
3788cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	dev_info(&adapter->pdev->dev, "EEH resume\n");
3789cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
3790cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	pci_save_state(pdev);
3791cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
3792cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	/* tell fw we're ready to fire cmds */
3793cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	status = be_cmd_fw_init(adapter);
3794cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	if (status)
3795cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla		goto err;
3796cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
3797cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	status = be_setup(adapter);
3798cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	if (status)
3799cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla		goto err;
3800cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
3801cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	if (netif_running(netdev)) {
3802cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla		status = be_open(netdev);
3803cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla		if (status)
3804cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla			goto err;
3805cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	}
3806cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	netif_device_attach(netdev);
3807cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	return;
3808cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perlaerr:
3809cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	dev_err(&adapter->pdev->dev, "EEH resume failed\n");
3810cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla}
3811cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
3812cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perlastatic struct pci_error_handlers be_eeh_handlers = {
3813cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	.error_detected = be_eeh_err_detected,
3814cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	.slot_reset = be_eeh_reset,
3815cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	.resume = be_eeh_resume,
3816cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla};
3817cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla
38186b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic struct pci_driver be_driver = {
38196b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	.name = DRV_NAME,
38206b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	.id_table = be_dev_ids,
38216b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	.probe = be_probe,
38226b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	.remove = be_remove,
38236b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	.suspend = be_suspend,
3824cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	.resume = be_resume,
382582456b031e3c3b5bf95a7e49bd9b68b146446e76Sathya Perla	.shutdown = be_shutdown,
3826cf588477a3fbf085426e5c0b6205984ebb7e2187Sathya Perla	.err_handler = &be_eeh_handlers
38276b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla};
38286b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
38296b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic int __init be_init_module(void)
38306b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
38318e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches	if (rx_frag_size != 8192 && rx_frag_size != 4096 &&
38328e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches	    rx_frag_size != 2048) {
38336b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		printk(KERN_WARNING DRV_NAME
38346b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			" : Module param rx_frag_size must be 2048/4096/8192."
38356b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla			" Using 2048\n");
38366b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla		rx_frag_size = 2048;
38376b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	}
38386b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
38396b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	return pci_register_driver(&be_driver);
38406b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
38416b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlamodule_init(be_init_module);
38426b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla
38436b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlastatic void __exit be_exit_module(void)
38446b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla{
38456b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla	pci_unregister_driver(&be_driver);
38466b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perla}
38476b7c5b947c671a96e39f9526a5fd70c178b8dfd1Sathya Perlamodule_exit(be_exit_module);
3848