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 ®); 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