linux/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
<<
>>
Prefs
   1/*
   2 * QLogic qlcnic NIC Driver
   3 * Copyright (c) 2009-2013 QLogic Corporation
   4 *
   5 * See LICENSE.qlcnic for copyright and licensing details.
   6 */
   7
   8#include "qlcnic.h"
   9#include "qlcnic_hdr.h"
  10
  11#include <linux/slab.h>
  12#include <net/ip.h>
  13#include <linux/bitops.h>
  14
  15#define MASK(n) ((1ULL<<(n))-1)
  16#define OCM_WIN_P3P(addr) (addr & 0xffc0000)
  17
  18#define GET_MEM_OFFS_2M(addr) (addr & MASK(18))
  19
  20#define CRB_BLK(off)    ((off >> 20) & 0x3f)
  21#define CRB_SUBBLK(off) ((off >> 16) & 0xf)
  22#define CRB_WINDOW_2M   (0x130060)
  23#define CRB_HI(off)     ((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000))
  24#define CRB_INDIRECT_2M (0x1e0000UL)
  25
  26struct qlcnic_ms_reg_ctrl {
  27        u32 ocm_window;
  28        u32 control;
  29        u32 hi;
  30        u32 low;
  31        u32 rd[4];
  32        u32 wd[4];
  33        u64 off;
  34};
  35
  36#ifndef readq
  37static inline u64 readq(void __iomem *addr)
  38{
  39        return readl(addr) | (((u64) readl(addr + 4)) << 32LL);
  40}
  41#endif
  42
  43#ifndef writeq
  44static inline void writeq(u64 val, void __iomem *addr)
  45{
  46        writel(((u32) (val)), (addr));
  47        writel(((u32) (val >> 32)), (addr + 4));
  48}
  49#endif
  50
  51static struct crb_128M_2M_block_map
  52crb_128M_2M_map[64] __cacheline_aligned_in_smp = {
  53    {{{0, 0,         0,         0} } },         /* 0: PCI */
  54    {{{1, 0x0100000, 0x0102000, 0x120000},      /* 1: PCIE */
  55          {1, 0x0110000, 0x0120000, 0x130000},
  56          {1, 0x0120000, 0x0122000, 0x124000},
  57          {1, 0x0130000, 0x0132000, 0x126000},
  58          {1, 0x0140000, 0x0142000, 0x128000},
  59          {1, 0x0150000, 0x0152000, 0x12a000},
  60          {1, 0x0160000, 0x0170000, 0x110000},
  61          {1, 0x0170000, 0x0172000, 0x12e000},
  62          {0, 0x0000000, 0x0000000, 0x000000},
  63          {0, 0x0000000, 0x0000000, 0x000000},
  64          {0, 0x0000000, 0x0000000, 0x000000},
  65          {0, 0x0000000, 0x0000000, 0x000000},
  66          {0, 0x0000000, 0x0000000, 0x000000},
  67          {0, 0x0000000, 0x0000000, 0x000000},
  68          {1, 0x01e0000, 0x01e0800, 0x122000},
  69          {0, 0x0000000, 0x0000000, 0x000000} } },
  70        {{{1, 0x0200000, 0x0210000, 0x180000} } },/* 2: MN */
  71    {{{0, 0,         0,         0} } },     /* 3: */
  72    {{{1, 0x0400000, 0x0401000, 0x169000} } },/* 4: P2NR1 */
  73    {{{1, 0x0500000, 0x0510000, 0x140000} } },/* 5: SRE   */
  74    {{{1, 0x0600000, 0x0610000, 0x1c0000} } },/* 6: NIU   */
  75    {{{1, 0x0700000, 0x0704000, 0x1b8000} } },/* 7: QM    */
  76    {{{1, 0x0800000, 0x0802000, 0x170000},  /* 8: SQM0  */
  77      {0, 0x0000000, 0x0000000, 0x000000},
  78      {0, 0x0000000, 0x0000000, 0x000000},
  79      {0, 0x0000000, 0x0000000, 0x000000},
  80      {0, 0x0000000, 0x0000000, 0x000000},
  81      {0, 0x0000000, 0x0000000, 0x000000},
  82      {0, 0x0000000, 0x0000000, 0x000000},
  83      {0, 0x0000000, 0x0000000, 0x000000},
  84      {0, 0x0000000, 0x0000000, 0x000000},
  85      {0, 0x0000000, 0x0000000, 0x000000},
  86      {0, 0x0000000, 0x0000000, 0x000000},
  87      {0, 0x0000000, 0x0000000, 0x000000},
  88      {0, 0x0000000, 0x0000000, 0x000000},
  89      {0, 0x0000000, 0x0000000, 0x000000},
  90      {0, 0x0000000, 0x0000000, 0x000000},
  91      {1, 0x08f0000, 0x08f2000, 0x172000} } },
  92    {{{1, 0x0900000, 0x0902000, 0x174000},      /* 9: SQM1*/
  93      {0, 0x0000000, 0x0000000, 0x000000},
  94      {0, 0x0000000, 0x0000000, 0x000000},
  95      {0, 0x0000000, 0x0000000, 0x000000},
  96      {0, 0x0000000, 0x0000000, 0x000000},
  97      {0, 0x0000000, 0x0000000, 0x000000},
  98      {0, 0x0000000, 0x0000000, 0x000000},
  99      {0, 0x0000000, 0x0000000, 0x000000},
 100      {0, 0x0000000, 0x0000000, 0x000000},
 101      {0, 0x0000000, 0x0000000, 0x000000},
 102      {0, 0x0000000, 0x0000000, 0x000000},
 103      {0, 0x0000000, 0x0000000, 0x000000},
 104      {0, 0x0000000, 0x0000000, 0x000000},
 105      {0, 0x0000000, 0x0000000, 0x000000},
 106      {0, 0x0000000, 0x0000000, 0x000000},
 107      {1, 0x09f0000, 0x09f2000, 0x176000} } },
 108    {{{0, 0x0a00000, 0x0a02000, 0x178000},      /* 10: SQM2*/
 109      {0, 0x0000000, 0x0000000, 0x000000},
 110      {0, 0x0000000, 0x0000000, 0x000000},
 111      {0, 0x0000000, 0x0000000, 0x000000},
 112      {0, 0x0000000, 0x0000000, 0x000000},
 113      {0, 0x0000000, 0x0000000, 0x000000},
 114      {0, 0x0000000, 0x0000000, 0x000000},
 115      {0, 0x0000000, 0x0000000, 0x000000},
 116      {0, 0x0000000, 0x0000000, 0x000000},
 117      {0, 0x0000000, 0x0000000, 0x000000},
 118      {0, 0x0000000, 0x0000000, 0x000000},
 119      {0, 0x0000000, 0x0000000, 0x000000},
 120      {0, 0x0000000, 0x0000000, 0x000000},
 121      {0, 0x0000000, 0x0000000, 0x000000},
 122      {0, 0x0000000, 0x0000000, 0x000000},
 123      {1, 0x0af0000, 0x0af2000, 0x17a000} } },
 124    {{{0, 0x0b00000, 0x0b02000, 0x17c000},      /* 11: SQM3*/
 125      {0, 0x0000000, 0x0000000, 0x000000},
 126      {0, 0x0000000, 0x0000000, 0x000000},
 127      {0, 0x0000000, 0x0000000, 0x000000},
 128      {0, 0x0000000, 0x0000000, 0x000000},
 129      {0, 0x0000000, 0x0000000, 0x000000},
 130      {0, 0x0000000, 0x0000000, 0x000000},
 131      {0, 0x0000000, 0x0000000, 0x000000},
 132      {0, 0x0000000, 0x0000000, 0x000000},
 133      {0, 0x0000000, 0x0000000, 0x000000},
 134      {0, 0x0000000, 0x0000000, 0x000000},
 135      {0, 0x0000000, 0x0000000, 0x000000},
 136      {0, 0x0000000, 0x0000000, 0x000000},
 137      {0, 0x0000000, 0x0000000, 0x000000},
 138      {0, 0x0000000, 0x0000000, 0x000000},
 139      {1, 0x0bf0000, 0x0bf2000, 0x17e000} } },
 140        {{{1, 0x0c00000, 0x0c04000, 0x1d4000} } },/* 12: I2Q */
 141        {{{1, 0x0d00000, 0x0d04000, 0x1a4000} } },/* 13: TMR */
 142        {{{1, 0x0e00000, 0x0e04000, 0x1a0000} } },/* 14: ROMUSB */
 143        {{{1, 0x0f00000, 0x0f01000, 0x164000} } },/* 15: PEG4 */
 144        {{{0, 0x1000000, 0x1004000, 0x1a8000} } },/* 16: XDMA */
 145        {{{1, 0x1100000, 0x1101000, 0x160000} } },/* 17: PEG0 */
 146        {{{1, 0x1200000, 0x1201000, 0x161000} } },/* 18: PEG1 */
 147        {{{1, 0x1300000, 0x1301000, 0x162000} } },/* 19: PEG2 */
 148        {{{1, 0x1400000, 0x1401000, 0x163000} } },/* 20: PEG3 */
 149        {{{1, 0x1500000, 0x1501000, 0x165000} } },/* 21: P2ND */
 150        {{{1, 0x1600000, 0x1601000, 0x166000} } },/* 22: P2NI */
 151        {{{0, 0,         0,         0} } },     /* 23: */
 152        {{{0, 0,         0,         0} } },     /* 24: */
 153        {{{0, 0,         0,         0} } },     /* 25: */
 154        {{{0, 0,         0,         0} } },     /* 26: */
 155        {{{0, 0,         0,         0} } },     /* 27: */
 156        {{{0, 0,         0,         0} } },     /* 28: */
 157        {{{1, 0x1d00000, 0x1d10000, 0x190000} } },/* 29: MS */
 158    {{{1, 0x1e00000, 0x1e01000, 0x16a000} } },/* 30: P2NR2 */
 159    {{{1, 0x1f00000, 0x1f10000, 0x150000} } },/* 31: EPG */
 160        {{{0} } },                              /* 32: PCI */
 161        {{{1, 0x2100000, 0x2102000, 0x120000},  /* 33: PCIE */
 162          {1, 0x2110000, 0x2120000, 0x130000},
 163          {1, 0x2120000, 0x2122000, 0x124000},
 164          {1, 0x2130000, 0x2132000, 0x126000},
 165          {1, 0x2140000, 0x2142000, 0x128000},
 166          {1, 0x2150000, 0x2152000, 0x12a000},
 167          {1, 0x2160000, 0x2170000, 0x110000},
 168          {1, 0x2170000, 0x2172000, 0x12e000},
 169          {0, 0x0000000, 0x0000000, 0x000000},
 170          {0, 0x0000000, 0x0000000, 0x000000},
 171          {0, 0x0000000, 0x0000000, 0x000000},
 172          {0, 0x0000000, 0x0000000, 0x000000},
 173          {0, 0x0000000, 0x0000000, 0x000000},
 174          {0, 0x0000000, 0x0000000, 0x000000},
 175          {0, 0x0000000, 0x0000000, 0x000000},
 176          {0, 0x0000000, 0x0000000, 0x000000} } },
 177        {{{1, 0x2200000, 0x2204000, 0x1b0000} } },/* 34: CAM */
 178        {{{0} } },                              /* 35: */
 179        {{{0} } },                              /* 36: */
 180        {{{0} } },                              /* 37: */
 181        {{{0} } },                              /* 38: */
 182        {{{0} } },                              /* 39: */
 183        {{{1, 0x2800000, 0x2804000, 0x1a4000} } },/* 40: TMR */
 184        {{{1, 0x2900000, 0x2901000, 0x16b000} } },/* 41: P2NR3 */
 185        {{{1, 0x2a00000, 0x2a00400, 0x1ac400} } },/* 42: RPMX1 */
 186        {{{1, 0x2b00000, 0x2b00400, 0x1ac800} } },/* 43: RPMX2 */
 187        {{{1, 0x2c00000, 0x2c00400, 0x1acc00} } },/* 44: RPMX3 */
 188        {{{1, 0x2d00000, 0x2d00400, 0x1ad000} } },/* 45: RPMX4 */
 189        {{{1, 0x2e00000, 0x2e00400, 0x1ad400} } },/* 46: RPMX5 */
 190        {{{1, 0x2f00000, 0x2f00400, 0x1ad800} } },/* 47: RPMX6 */
 191        {{{1, 0x3000000, 0x3000400, 0x1adc00} } },/* 48: RPMX7 */
 192        {{{0, 0x3100000, 0x3104000, 0x1a8000} } },/* 49: XDMA */
 193        {{{1, 0x3200000, 0x3204000, 0x1d4000} } },/* 50: I2Q */
 194        {{{1, 0x3300000, 0x3304000, 0x1a0000} } },/* 51: ROMUSB */
 195        {{{0} } },                              /* 52: */
 196        {{{1, 0x3500000, 0x3500400, 0x1ac000} } },/* 53: RPMX0 */
 197        {{{1, 0x3600000, 0x3600400, 0x1ae000} } },/* 54: RPMX8 */
 198        {{{1, 0x3700000, 0x3700400, 0x1ae400} } },/* 55: RPMX9 */
 199        {{{1, 0x3800000, 0x3804000, 0x1d0000} } },/* 56: OCM0 */
 200        {{{1, 0x3900000, 0x3904000, 0x1b4000} } },/* 57: CRYPTO */
 201        {{{1, 0x3a00000, 0x3a04000, 0x1d8000} } },/* 58: SMB */
 202        {{{0} } },                              /* 59: I2C0 */
 203        {{{0} } },                              /* 60: I2C1 */
 204        {{{1, 0x3d00000, 0x3d04000, 0x1d8000} } },/* 61: LPC */
 205        {{{1, 0x3e00000, 0x3e01000, 0x167000} } },/* 62: P2NC */
 206        {{{1, 0x3f00000, 0x3f01000, 0x168000} } }       /* 63: P2NR0 */
 207};
 208
 209/*
 210 * top 12 bits of crb internal address (hub, agent)
 211 */
 212static const unsigned crb_hub_agt[64] = {
 213        0,
 214        QLCNIC_HW_CRB_HUB_AGT_ADR_PS,
 215        QLCNIC_HW_CRB_HUB_AGT_ADR_MN,
 216        QLCNIC_HW_CRB_HUB_AGT_ADR_MS,
 217        0,
 218        QLCNIC_HW_CRB_HUB_AGT_ADR_SRE,
 219        QLCNIC_HW_CRB_HUB_AGT_ADR_NIU,
 220        QLCNIC_HW_CRB_HUB_AGT_ADR_QMN,
 221        QLCNIC_HW_CRB_HUB_AGT_ADR_SQN0,
 222        QLCNIC_HW_CRB_HUB_AGT_ADR_SQN1,
 223        QLCNIC_HW_CRB_HUB_AGT_ADR_SQN2,
 224        QLCNIC_HW_CRB_HUB_AGT_ADR_SQN3,
 225        QLCNIC_HW_CRB_HUB_AGT_ADR_I2Q,
 226        QLCNIC_HW_CRB_HUB_AGT_ADR_TIMR,
 227        QLCNIC_HW_CRB_HUB_AGT_ADR_ROMUSB,
 228        QLCNIC_HW_CRB_HUB_AGT_ADR_PGN4,
 229        QLCNIC_HW_CRB_HUB_AGT_ADR_XDMA,
 230        QLCNIC_HW_CRB_HUB_AGT_ADR_PGN0,
 231        QLCNIC_HW_CRB_HUB_AGT_ADR_PGN1,
 232        QLCNIC_HW_CRB_HUB_AGT_ADR_PGN2,
 233        QLCNIC_HW_CRB_HUB_AGT_ADR_PGN3,
 234        QLCNIC_HW_CRB_HUB_AGT_ADR_PGND,
 235        QLCNIC_HW_CRB_HUB_AGT_ADR_PGNI,
 236        QLCNIC_HW_CRB_HUB_AGT_ADR_PGS0,
 237        QLCNIC_HW_CRB_HUB_AGT_ADR_PGS1,
 238        QLCNIC_HW_CRB_HUB_AGT_ADR_PGS2,
 239        QLCNIC_HW_CRB_HUB_AGT_ADR_PGS3,
 240        0,
 241        QLCNIC_HW_CRB_HUB_AGT_ADR_PGSI,
 242        QLCNIC_HW_CRB_HUB_AGT_ADR_SN,
 243        0,
 244        QLCNIC_HW_CRB_HUB_AGT_ADR_EG,
 245        0,
 246        QLCNIC_HW_CRB_HUB_AGT_ADR_PS,
 247        QLCNIC_HW_CRB_HUB_AGT_ADR_CAM,
 248        0,
 249        0,
 250        0,
 251        0,
 252        0,
 253        QLCNIC_HW_CRB_HUB_AGT_ADR_TIMR,
 254        0,
 255        QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX1,
 256        QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX2,
 257        QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX3,
 258        QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX4,
 259        QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX5,
 260        QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX6,
 261        QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX7,
 262        QLCNIC_HW_CRB_HUB_AGT_ADR_XDMA,
 263        QLCNIC_HW_CRB_HUB_AGT_ADR_I2Q,
 264        QLCNIC_HW_CRB_HUB_AGT_ADR_ROMUSB,
 265        0,
 266        QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX0,
 267        QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX8,
 268        QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX9,
 269        QLCNIC_HW_CRB_HUB_AGT_ADR_OCM0,
 270        0,
 271        QLCNIC_HW_CRB_HUB_AGT_ADR_SMB,
 272        QLCNIC_HW_CRB_HUB_AGT_ADR_I2C0,
 273        QLCNIC_HW_CRB_HUB_AGT_ADR_I2C1,
 274        0,
 275        QLCNIC_HW_CRB_HUB_AGT_ADR_PGNC,
 276        0,
 277};
 278
 279static const u32 msi_tgt_status[8] = {
 280        ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1,
 281        ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3,
 282        ISR_INT_TARGET_STATUS_F4, ISR_INT_TARGET_STATUS_F5,
 283        ISR_INT_TARGET_STATUS_F6, ISR_INT_TARGET_STATUS_F7
 284};
 285
 286/*  PCI Windowing for DDR regions.  */
 287
 288#define QLCNIC_PCIE_SEM_TIMEOUT 10000
 289
 290static void qlcnic_read_window_reg(u32 addr, void __iomem *bar0, u32 *data)
 291{
 292        u32 dest;
 293        void __iomem *val;
 294
 295        dest = addr & 0xFFFF0000;
 296        val = bar0 + QLCNIC_FW_DUMP_REG1;
 297        writel(dest, val);
 298        readl(val);
 299        val = bar0 + QLCNIC_FW_DUMP_REG2 + LSW(addr);
 300        *data = readl(val);
 301}
 302
 303static void qlcnic_write_window_reg(u32 addr, void __iomem *bar0, u32 data)
 304{
 305        u32 dest;
 306        void __iomem *val;
 307
 308        dest = addr & 0xFFFF0000;
 309        val = bar0 + QLCNIC_FW_DUMP_REG1;
 310        writel(dest, val);
 311        readl(val);
 312        val = bar0 + QLCNIC_FW_DUMP_REG2 + LSW(addr);
 313        writel(data, val);
 314        readl(val);
 315}
 316
 317int
 318qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg)
 319{
 320        int done = 0, timeout = 0;
 321
 322        while (!done) {
 323                done = QLCRD32(adapter, QLCNIC_PCIE_REG(PCIE_SEM_LOCK(sem)));
 324                if (done == 1)
 325                        break;
 326                if (++timeout >= QLCNIC_PCIE_SEM_TIMEOUT) {
 327                        dev_err(&adapter->pdev->dev,
 328                                "Failed to acquire sem=%d lock; holdby=%d\n",
 329                                sem, id_reg ? QLCRD32(adapter, id_reg) : -1);
 330                        return -EIO;
 331                }
 332                msleep(1);
 333        }
 334
 335        if (id_reg)
 336                QLCWR32(adapter, id_reg, adapter->portnum);
 337
 338        return 0;
 339}
 340
 341void
 342qlcnic_pcie_sem_unlock(struct qlcnic_adapter *adapter, int sem)
 343{
 344        QLCRD32(adapter, QLCNIC_PCIE_REG(PCIE_SEM_UNLOCK(sem)));
 345}
 346
 347int qlcnic_ind_rd(struct qlcnic_adapter *adapter, u32 addr)
 348{
 349        u32 data;
 350
 351        if (qlcnic_82xx_check(adapter))
 352                qlcnic_read_window_reg(addr, adapter->ahw->pci_base0, &data);
 353        else {
 354                data = qlcnic_83xx_rd_reg_indirect(adapter, addr);
 355                if (data == -EIO)
 356                        return -EIO;
 357        }
 358        return data;
 359}
 360
 361void qlcnic_ind_wr(struct qlcnic_adapter *adapter, u32 addr, u32 data)
 362{
 363        if (qlcnic_82xx_check(adapter))
 364                qlcnic_write_window_reg(addr, adapter->ahw->pci_base0, data);
 365        else
 366                qlcnic_83xx_wrt_reg_indirect(adapter, addr, data);
 367}
 368
 369static int
 370qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter,
 371                struct cmd_desc_type0 *cmd_desc_arr, int nr_desc)
 372{
 373        u32 i, producer;
 374        struct qlcnic_cmd_buffer *pbuf;
 375        struct cmd_desc_type0 *cmd_desc;
 376        struct qlcnic_host_tx_ring *tx_ring;
 377
 378        i = 0;
 379
 380        if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
 381                return -EIO;
 382
 383        tx_ring = adapter->tx_ring;
 384        __netif_tx_lock_bh(tx_ring->txq);
 385
 386        producer = tx_ring->producer;
 387
 388        if (nr_desc >= qlcnic_tx_avail(tx_ring)) {
 389                netif_tx_stop_queue(tx_ring->txq);
 390                smp_mb();
 391                if (qlcnic_tx_avail(tx_ring) > nr_desc) {
 392                        if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH)
 393                                netif_tx_wake_queue(tx_ring->txq);
 394                } else {
 395                        adapter->stats.xmit_off++;
 396                        __netif_tx_unlock_bh(tx_ring->txq);
 397                        return -EBUSY;
 398                }
 399        }
 400
 401        do {
 402                cmd_desc = &cmd_desc_arr[i];
 403
 404                pbuf = &tx_ring->cmd_buf_arr[producer];
 405                pbuf->skb = NULL;
 406                pbuf->frag_count = 0;
 407
 408                memcpy(&tx_ring->desc_head[producer],
 409                       cmd_desc, sizeof(struct cmd_desc_type0));
 410
 411                producer = get_next_index(producer, tx_ring->num_desc);
 412                i++;
 413
 414        } while (i != nr_desc);
 415
 416        tx_ring->producer = producer;
 417
 418        qlcnic_update_cmd_producer(tx_ring);
 419
 420        __netif_tx_unlock_bh(tx_ring->txq);
 421
 422        return 0;
 423}
 424
 425int qlcnic_82xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
 426                                   u16 vlan_id, u8 op)
 427{
 428        struct qlcnic_nic_req req;
 429        struct qlcnic_mac_req *mac_req;
 430        struct qlcnic_vlan_req *vlan_req;
 431        u64 word;
 432
 433        memset(&req, 0, sizeof(struct qlcnic_nic_req));
 434        req.qhdr = cpu_to_le64(QLCNIC_REQUEST << 23);
 435
 436        word = QLCNIC_MAC_EVENT | ((u64)adapter->portnum << 16);
 437        req.req_hdr = cpu_to_le64(word);
 438
 439        mac_req = (struct qlcnic_mac_req *)&req.words[0];
 440        mac_req->op = op;
 441        memcpy(mac_req->mac_addr, addr, 6);
 442
 443        vlan_req = (struct qlcnic_vlan_req *)&req.words[1];
 444        vlan_req->vlan_id = cpu_to_le16(vlan_id);
 445
 446        return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
 447}
 448
 449int qlcnic_nic_del_mac(struct qlcnic_adapter *adapter, const u8 *addr)
 450{
 451        struct list_head *head;
 452        struct qlcnic_mac_list_s *cur;
 453        int err = -EINVAL;
 454
 455        /* Delete MAC from the existing list */
 456        list_for_each(head, &adapter->mac_list) {
 457                cur = list_entry(head, struct qlcnic_mac_list_s, list);
 458                if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) {
 459                        err = qlcnic_sre_macaddr_change(adapter, cur->mac_addr,
 460                                                        0, QLCNIC_MAC_DEL);
 461                        if (err)
 462                                return err;
 463                        list_del(&cur->list);
 464                        kfree(cur);
 465                        return err;
 466                }
 467        }
 468        return err;
 469}
 470
 471int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, const u8 *addr, u16 vlan)
 472{
 473        struct list_head *head;
 474        struct qlcnic_mac_list_s *cur;
 475
 476        /* look up if already exists */
 477        list_for_each(head, &adapter->mac_list) {
 478                cur = list_entry(head, struct qlcnic_mac_list_s, list);
 479                if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0)
 480                        return 0;
 481        }
 482
 483        cur = kzalloc(sizeof(struct qlcnic_mac_list_s), GFP_ATOMIC);
 484        if (cur == NULL)
 485                return -ENOMEM;
 486
 487        memcpy(cur->mac_addr, addr, ETH_ALEN);
 488
 489        if (qlcnic_sre_macaddr_change(adapter,
 490                                cur->mac_addr, vlan, QLCNIC_MAC_ADD)) {
 491                kfree(cur);
 492                return -EIO;
 493        }
 494
 495        list_add_tail(&cur->list, &adapter->mac_list);
 496        return 0;
 497}
 498
 499void __qlcnic_set_multi(struct net_device *netdev, u16 vlan)
 500{
 501        struct qlcnic_adapter *adapter = netdev_priv(netdev);
 502        struct netdev_hw_addr *ha;
 503        static const u8 bcast_addr[ETH_ALEN] = {
 504                0xff, 0xff, 0xff, 0xff, 0xff, 0xff
 505        };
 506        u32 mode = VPORT_MISS_MODE_DROP;
 507
 508        if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
 509                return;
 510
 511        if (!qlcnic_sriov_vf_check(adapter))
 512                qlcnic_nic_add_mac(adapter, adapter->mac_addr, vlan);
 513        qlcnic_nic_add_mac(adapter, bcast_addr, vlan);
 514
 515        if (netdev->flags & IFF_PROMISC) {
 516                if (!(adapter->flags & QLCNIC_PROMISC_DISABLED))
 517                        mode = VPORT_MISS_MODE_ACCEPT_ALL;
 518                goto send_fw_cmd;
 519        }
 520
 521        if ((netdev->flags & IFF_ALLMULTI) ||
 522            (netdev_mc_count(netdev) > adapter->ahw->max_mc_count)) {
 523                mode = VPORT_MISS_MODE_ACCEPT_MULTI;
 524                goto send_fw_cmd;
 525        }
 526
 527        if (!netdev_mc_empty(netdev) && !qlcnic_sriov_vf_check(adapter)) {
 528                netdev_for_each_mc_addr(ha, netdev) {
 529                        qlcnic_nic_add_mac(adapter, ha->addr, vlan);
 530                }
 531        }
 532
 533        if (qlcnic_sriov_vf_check(adapter))
 534                qlcnic_vf_add_mc_list(netdev, vlan);
 535
 536send_fw_cmd:
 537        if (!qlcnic_sriov_vf_check(adapter)) {
 538                if (mode == VPORT_MISS_MODE_ACCEPT_ALL &&
 539                    !adapter->fdb_mac_learn) {
 540                        qlcnic_alloc_lb_filters_mem(adapter);
 541                        adapter->drv_mac_learn = true;
 542                } else {
 543                        adapter->drv_mac_learn = false;
 544                }
 545        }
 546
 547        qlcnic_nic_set_promisc(adapter, mode);
 548}
 549
 550void qlcnic_set_multi(struct net_device *netdev)
 551{
 552        struct qlcnic_adapter *adapter = netdev_priv(netdev);
 553        struct netdev_hw_addr *ha;
 554        struct qlcnic_mac_list_s *cur;
 555
 556        if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
 557                return;
 558        if (qlcnic_sriov_vf_check(adapter)) {
 559                if (!netdev_mc_empty(netdev)) {
 560                        netdev_for_each_mc_addr(ha, netdev) {
 561                                cur = kzalloc(sizeof(struct qlcnic_mac_list_s),
 562                                              GFP_ATOMIC);
 563                                if (cur == NULL)
 564                                        break;
 565                                memcpy(cur->mac_addr,
 566                                       ha->addr, ETH_ALEN);
 567                                list_add_tail(&cur->list, &adapter->vf_mc_list);
 568                        }
 569                }
 570                qlcnic_sriov_vf_schedule_multi(adapter->netdev);
 571                return;
 572        }
 573        __qlcnic_set_multi(netdev, 0);
 574}
 575
 576int qlcnic_82xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
 577{
 578        struct qlcnic_nic_req req;
 579        u64 word;
 580
 581        memset(&req, 0, sizeof(struct qlcnic_nic_req));
 582
 583        req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
 584
 585        word = QLCNIC_H2C_OPCODE_SET_MAC_RECEIVE_MODE |
 586                        ((u64)adapter->portnum << 16);
 587        req.req_hdr = cpu_to_le64(word);
 588
 589        req.words[0] = cpu_to_le64(mode);
 590
 591        return qlcnic_send_cmd_descs(adapter,
 592                                (struct cmd_desc_type0 *)&req, 1);
 593}
 594
 595void qlcnic_82xx_free_mac_list(struct qlcnic_adapter *adapter)
 596{
 597        struct qlcnic_mac_list_s *cur;
 598        struct list_head *head = &adapter->mac_list;
 599
 600        while (!list_empty(head)) {
 601                cur = list_entry(head->next, struct qlcnic_mac_list_s, list);
 602                qlcnic_sre_macaddr_change(adapter,
 603                                cur->mac_addr, 0, QLCNIC_MAC_DEL);
 604                list_del(&cur->list);
 605                kfree(cur);
 606        }
 607}
 608
 609void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter)
 610{
 611        struct qlcnic_filter *tmp_fil;
 612        struct hlist_node *n;
 613        struct hlist_head *head;
 614        int i;
 615        unsigned long time;
 616        u8 cmd;
 617
 618        for (i = 0; i < adapter->fhash.fbucket_size; i++) {
 619                head = &(adapter->fhash.fhead[i]);
 620                hlist_for_each_entry_safe(tmp_fil, n, head, fnode) {
 621                        cmd =  tmp_fil->vlan_id ? QLCNIC_MAC_VLAN_DEL :
 622                                                  QLCNIC_MAC_DEL;
 623                        time = tmp_fil->ftime;
 624                        if (jiffies > (QLCNIC_FILTER_AGE * HZ + time)) {
 625                                qlcnic_sre_macaddr_change(adapter,
 626                                                          tmp_fil->faddr,
 627                                                          tmp_fil->vlan_id,
 628                                                          cmd);
 629                                spin_lock_bh(&adapter->mac_learn_lock);
 630                                adapter->fhash.fnum--;
 631                                hlist_del(&tmp_fil->fnode);
 632                                spin_unlock_bh(&adapter->mac_learn_lock);
 633                                kfree(tmp_fil);
 634                        }
 635                }
 636        }
 637        for (i = 0; i < adapter->rx_fhash.fbucket_size; i++) {
 638                head = &(adapter->rx_fhash.fhead[i]);
 639
 640                hlist_for_each_entry_safe(tmp_fil, n, head, fnode)
 641                {
 642                        time = tmp_fil->ftime;
 643                        if (jiffies > (QLCNIC_FILTER_AGE * HZ + time)) {
 644                                spin_lock_bh(&adapter->rx_mac_learn_lock);
 645                                adapter->rx_fhash.fnum--;
 646                                hlist_del(&tmp_fil->fnode);
 647                                spin_unlock_bh(&adapter->rx_mac_learn_lock);
 648                                kfree(tmp_fil);
 649                        }
 650                }
 651        }
 652}
 653
 654void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter)
 655{
 656        struct qlcnic_filter *tmp_fil;
 657        struct hlist_node *n;
 658        struct hlist_head *head;
 659        int i;
 660        u8 cmd;
 661
 662        for (i = 0; i < adapter->fhash.fbucket_size; i++) {
 663                head = &(adapter->fhash.fhead[i]);
 664                hlist_for_each_entry_safe(tmp_fil, n, head, fnode) {
 665                        cmd =  tmp_fil->vlan_id ? QLCNIC_MAC_VLAN_DEL :
 666                                                  QLCNIC_MAC_DEL;
 667                        qlcnic_sre_macaddr_change(adapter,
 668                                                  tmp_fil->faddr,
 669                                                  tmp_fil->vlan_id,
 670                                                  cmd);
 671                        spin_lock_bh(&adapter->mac_learn_lock);
 672                        adapter->fhash.fnum--;
 673                        hlist_del(&tmp_fil->fnode);
 674                        spin_unlock_bh(&adapter->mac_learn_lock);
 675                        kfree(tmp_fil);
 676                }
 677        }
 678}
 679
 680static int qlcnic_set_fw_loopback(struct qlcnic_adapter *adapter, u8 flag)
 681{
 682        struct qlcnic_nic_req req;
 683        int rv;
 684
 685        memset(&req, 0, sizeof(struct qlcnic_nic_req));
 686
 687        req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
 688        req.req_hdr = cpu_to_le64(QLCNIC_H2C_OPCODE_CONFIG_LOOPBACK |
 689                ((u64) adapter->portnum << 16) | ((u64) 0x1 << 32));
 690
 691        req.words[0] = cpu_to_le64(flag);
 692
 693        rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
 694        if (rv != 0)
 695                dev_err(&adapter->pdev->dev, "%sting loopback mode failed\n",
 696                                flag ? "Set" : "Reset");
 697        return rv;
 698}
 699
 700int qlcnic_82xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
 701{
 702        if (qlcnic_set_fw_loopback(adapter, mode))
 703                return -EIO;
 704
 705        if (qlcnic_nic_set_promisc(adapter,
 706                                   VPORT_MISS_MODE_ACCEPT_ALL)) {
 707                qlcnic_set_fw_loopback(adapter, 0);
 708                return -EIO;
 709        }
 710
 711        msleep(1000);
 712        return 0;
 713}
 714
 715int qlcnic_82xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
 716{
 717        struct net_device *netdev = adapter->netdev;
 718
 719        mode = VPORT_MISS_MODE_DROP;
 720        qlcnic_set_fw_loopback(adapter, 0);
 721
 722        if (netdev->flags & IFF_PROMISC)
 723                mode = VPORT_MISS_MODE_ACCEPT_ALL;
 724        else if (netdev->flags & IFF_ALLMULTI)
 725                mode = VPORT_MISS_MODE_ACCEPT_MULTI;
 726
 727        qlcnic_nic_set_promisc(adapter, mode);
 728        msleep(1000);
 729        return 0;
 730}
 731
 732/*
 733 * Send the interrupt coalescing parameter set by ethtool to the card.
 734 */
 735void qlcnic_82xx_config_intr_coalesce(struct qlcnic_adapter *adapter)
 736{
 737        struct qlcnic_nic_req req;
 738        int rv;
 739
 740        memset(&req, 0, sizeof(struct qlcnic_nic_req));
 741
 742        req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
 743
 744        req.req_hdr = cpu_to_le64(QLCNIC_CONFIG_INTR_COALESCE |
 745                ((u64) adapter->portnum << 16));
 746
 747        req.words[0] = cpu_to_le64(((u64) adapter->ahw->coal.flag) << 32);
 748        req.words[2] = cpu_to_le64(adapter->ahw->coal.rx_packets |
 749                        ((u64) adapter->ahw->coal.rx_time_us) << 16);
 750        req.words[5] = cpu_to_le64(adapter->ahw->coal.timer_out |
 751                        ((u64) adapter->ahw->coal.type) << 32 |
 752                        ((u64) adapter->ahw->coal.sts_ring_mask) << 40);
 753        rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
 754        if (rv != 0)
 755                dev_err(&adapter->netdev->dev,
 756                        "Could not send interrupt coalescing parameters\n");
 757}
 758
 759#define QLCNIC_ENABLE_IPV4_LRO          1
 760#define QLCNIC_ENABLE_IPV6_LRO          2
 761#define QLCNIC_NO_DEST_IPV4_CHECK       (1 << 8)
 762#define QLCNIC_NO_DEST_IPV6_CHECK       (2 << 8)
 763
 764int qlcnic_82xx_config_hw_lro(struct qlcnic_adapter *adapter, int enable)
 765{
 766        struct qlcnic_nic_req req;
 767        u64 word;
 768        int rv;
 769
 770        if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
 771                return 0;
 772
 773        memset(&req, 0, sizeof(struct qlcnic_nic_req));
 774
 775        req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
 776
 777        word = QLCNIC_H2C_OPCODE_CONFIG_HW_LRO | ((u64)adapter->portnum << 16);
 778        req.req_hdr = cpu_to_le64(word);
 779
 780        word = 0;
 781        if (enable) {
 782                word = QLCNIC_ENABLE_IPV4_LRO | QLCNIC_NO_DEST_IPV4_CHECK;
 783                if (adapter->ahw->capabilities2 & QLCNIC_FW_CAP2_HW_LRO_IPV6)
 784                        word |= QLCNIC_ENABLE_IPV6_LRO |
 785                                QLCNIC_NO_DEST_IPV6_CHECK;
 786        }
 787
 788        req.words[0] = cpu_to_le64(word);
 789
 790        rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
 791        if (rv != 0)
 792                dev_err(&adapter->netdev->dev,
 793                        "Could not send configure hw lro request\n");
 794
 795        return rv;
 796}
 797
 798int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable)
 799{
 800        struct qlcnic_nic_req req;
 801        u64 word;
 802        int rv;
 803
 804        if (!!(adapter->flags & QLCNIC_BRIDGE_ENABLED) == enable)
 805                return 0;
 806
 807        memset(&req, 0, sizeof(struct qlcnic_nic_req));
 808
 809        req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
 810
 811        word = QLCNIC_H2C_OPCODE_CONFIG_BRIDGING |
 812                ((u64)adapter->portnum << 16);
 813        req.req_hdr = cpu_to_le64(word);
 814
 815        req.words[0] = cpu_to_le64(enable);
 816
 817        rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
 818        if (rv != 0)
 819                dev_err(&adapter->netdev->dev,
 820                        "Could not send configure bridge mode request\n");
 821
 822        adapter->flags ^= QLCNIC_BRIDGE_ENABLED;
 823
 824        return rv;
 825}
 826
 827
 828#define QLCNIC_RSS_HASHTYPE_IP_TCP      0x3
 829#define QLCNIC_ENABLE_TYPE_C_RSS        BIT_10
 830#define QLCNIC_RSS_FEATURE_FLAG (1ULL << 63)
 831#define QLCNIC_RSS_IND_TABLE_MASK       0x7ULL
 832
 833int qlcnic_82xx_config_rss(struct qlcnic_adapter *adapter, int enable)
 834{
 835        struct qlcnic_nic_req req;
 836        u64 word;
 837        int i, rv;
 838
 839        static const u64 key[] = {
 840                0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
 841                0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
 842                0x255b0ec26d5a56daULL
 843        };
 844
 845        memset(&req, 0, sizeof(struct qlcnic_nic_req));
 846        req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
 847
 848        word = QLCNIC_H2C_OPCODE_CONFIG_RSS | ((u64)adapter->portnum << 16);
 849        req.req_hdr = cpu_to_le64(word);
 850
 851        /*
 852         * RSS request:
 853         * bits 3-0: hash_method
 854         *      5-4: hash_type_ipv4
 855         *      7-6: hash_type_ipv6
 856         *        8: enable
 857         *        9: use indirection table
 858         *       10: type-c rss
 859         *       11: udp rss
 860         *    47-12: reserved
 861         *    62-48: indirection table mask
 862         *       63: feature flag
 863         */
 864        word =  ((u64)(QLCNIC_RSS_HASHTYPE_IP_TCP & 0x3) << 4) |
 865                ((u64)(QLCNIC_RSS_HASHTYPE_IP_TCP & 0x3) << 6) |
 866                ((u64)(enable & 0x1) << 8) |
 867                ((u64)QLCNIC_RSS_IND_TABLE_MASK << 48) |
 868                (u64)QLCNIC_ENABLE_TYPE_C_RSS |
 869                (u64)QLCNIC_RSS_FEATURE_FLAG;
 870
 871        req.words[0] = cpu_to_le64(word);
 872        for (i = 0; i < 5; i++)
 873                req.words[i+1] = cpu_to_le64(key[i]);
 874
 875        rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
 876        if (rv != 0)
 877                dev_err(&adapter->netdev->dev, "could not configure RSS\n");
 878
 879        return rv;
 880}
 881
 882void qlcnic_82xx_config_ipaddr(struct qlcnic_adapter *adapter,
 883                               __be32 ip, int cmd)
 884{
 885        struct qlcnic_nic_req req;
 886        struct qlcnic_ipaddr *ipa;
 887        u64 word;
 888        int rv;
 889
 890        memset(&req, 0, sizeof(struct qlcnic_nic_req));
 891        req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
 892
 893        word = QLCNIC_H2C_OPCODE_CONFIG_IPADDR | ((u64)adapter->portnum << 16);
 894        req.req_hdr = cpu_to_le64(word);
 895
 896        req.words[0] = cpu_to_le64(cmd);
 897        ipa = (struct qlcnic_ipaddr *)&req.words[1];
 898        ipa->ipv4 = ip;
 899
 900        rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
 901        if (rv != 0)
 902                dev_err(&adapter->netdev->dev,
 903                                "could not notify %s IP 0x%x reuqest\n",
 904                                (cmd == QLCNIC_IP_UP) ? "Add" : "Remove", ip);
 905}
 906
 907int qlcnic_82xx_linkevent_request(struct qlcnic_adapter *adapter, int enable)
 908{
 909        struct qlcnic_nic_req req;
 910        u64 word;
 911        int rv;
 912        memset(&req, 0, sizeof(struct qlcnic_nic_req));
 913        req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
 914
 915        word = QLCNIC_H2C_OPCODE_GET_LINKEVENT | ((u64)adapter->portnum << 16);
 916        req.req_hdr = cpu_to_le64(word);
 917        req.words[0] = cpu_to_le64(enable | (enable << 8));
 918        rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
 919        if (rv != 0)
 920                dev_err(&adapter->netdev->dev,
 921                                "could not configure link notification\n");
 922
 923        return rv;
 924}
 925
 926int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter)
 927{
 928        struct qlcnic_nic_req req;
 929        u64 word;
 930        int rv;
 931
 932        if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
 933                return 0;
 934
 935        memset(&req, 0, sizeof(struct qlcnic_nic_req));
 936        req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
 937
 938        word = QLCNIC_H2C_OPCODE_LRO_REQUEST |
 939                ((u64)adapter->portnum << 16) |
 940                ((u64)QLCNIC_LRO_REQUEST_CLEANUP << 56) ;
 941
 942        req.req_hdr = cpu_to_le64(word);
 943
 944        rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
 945        if (rv != 0)
 946                dev_err(&adapter->netdev->dev,
 947                                 "could not cleanup lro flows\n");
 948
 949        return rv;
 950}
 951
 952/*
 953 * qlcnic_change_mtu - Change the Maximum Transfer Unit
 954 * @returns 0 on success, negative on failure
 955 */
 956
 957int qlcnic_change_mtu(struct net_device *netdev, int mtu)
 958{
 959        struct qlcnic_adapter *adapter = netdev_priv(netdev);
 960        int rc = 0;
 961
 962        if (mtu < P3P_MIN_MTU || mtu > P3P_MAX_MTU) {
 963                dev_err(&adapter->netdev->dev, "%d bytes < mtu < %d bytes"
 964                        " not supported\n", P3P_MAX_MTU, P3P_MIN_MTU);
 965                return -EINVAL;
 966        }
 967
 968        rc = qlcnic_fw_cmd_set_mtu(adapter, mtu);
 969
 970        if (!rc)
 971                netdev->mtu = mtu;
 972
 973        return rc;
 974}
 975
 976static netdev_features_t qlcnic_process_flags(struct qlcnic_adapter *adapter,
 977                                              netdev_features_t features)
 978{
 979        u32 offload_flags = adapter->offload_flags;
 980
 981        if (offload_flags & BIT_0) {
 982                features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
 983                            NETIF_F_IPV6_CSUM;
 984                adapter->rx_csum = 1;
 985                if (QLCNIC_IS_TSO_CAPABLE(adapter)) {
 986                        if (!(offload_flags & BIT_1))
 987                                features &= ~NETIF_F_TSO;
 988                        else
 989                                features |= NETIF_F_TSO;
 990
 991                        if (!(offload_flags & BIT_2))
 992                                features &= ~NETIF_F_TSO6;
 993                        else
 994                                features |= NETIF_F_TSO6;
 995                }
 996        } else {
 997                features &= ~(NETIF_F_RXCSUM |
 998                              NETIF_F_IP_CSUM |
 999                              NETIF_F_IPV6_CSUM);
1000
1001                if (QLCNIC_IS_TSO_CAPABLE(adapter))
1002                        features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
1003                adapter->rx_csum = 0;
1004        }
1005
1006        return features;
1007}
1008
1009netdev_features_t qlcnic_fix_features(struct net_device *netdev,
1010        netdev_features_t features)
1011{
1012        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1013        netdev_features_t changed;
1014
1015        if (qlcnic_82xx_check(adapter) &&
1016            (adapter->flags & QLCNIC_ESWITCH_ENABLED)) {
1017                if (adapter->flags & QLCNIC_APP_CHANGED_FLAGS) {
1018                        features = qlcnic_process_flags(adapter, features);
1019                } else {
1020                        changed = features ^ netdev->features;
1021                        features ^= changed & (NETIF_F_RXCSUM |
1022                                               NETIF_F_IP_CSUM |
1023                                               NETIF_F_IPV6_CSUM |
1024                                               NETIF_F_TSO |
1025                                               NETIF_F_TSO6);
1026                }
1027        }
1028
1029        if (!(features & NETIF_F_RXCSUM))
1030                features &= ~NETIF_F_LRO;
1031
1032        return features;
1033}
1034
1035
1036int qlcnic_set_features(struct net_device *netdev, netdev_features_t features)
1037{
1038        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1039        netdev_features_t changed = netdev->features ^ features;
1040        int hw_lro = (features & NETIF_F_LRO) ? QLCNIC_LRO_ENABLED : 0;
1041
1042        if (!(changed & NETIF_F_LRO))
1043                return 0;
1044
1045        netdev->features ^= NETIF_F_LRO;
1046
1047        if (qlcnic_config_hw_lro(adapter, hw_lro))
1048                return -EIO;
1049
1050        if (!hw_lro && qlcnic_82xx_check(adapter)) {
1051                if (qlcnic_send_lro_cleanup(adapter))
1052                        return -EIO;
1053        }
1054
1055        return 0;
1056}
1057
1058/*
1059 * Changes the CRB window to the specified window.
1060 */
1061 /* Returns < 0 if off is not valid,
1062 *       1 if window access is needed. 'off' is set to offset from
1063 *         CRB space in 128M pci map
1064 *       0 if no window access is needed. 'off' is set to 2M addr
1065 * In: 'off' is offset from base in 128M pci map
1066 */
1067static int qlcnic_pci_get_crb_addr_2M(struct qlcnic_hardware_context *ahw,
1068                                      ulong off, void __iomem **addr)
1069{
1070        const struct crb_128M_2M_sub_block_map *m;
1071
1072        if ((off >= QLCNIC_CRB_MAX) || (off < QLCNIC_PCI_CRBSPACE))
1073                return -EINVAL;
1074
1075        off -= QLCNIC_PCI_CRBSPACE;
1076
1077        /*
1078         * Try direct map
1079         */
1080        m = &crb_128M_2M_map[CRB_BLK(off)].sub_block[CRB_SUBBLK(off)];
1081
1082        if (m->valid && (m->start_128M <= off) && (m->end_128M > off)) {
1083                *addr = ahw->pci_base0 + m->start_2M +
1084                        (off - m->start_128M);
1085                return 0;
1086        }
1087
1088        /*
1089         * Not in direct map, use crb window
1090         */
1091        *addr = ahw->pci_base0 + CRB_INDIRECT_2M + (off & MASK(16));
1092        return 1;
1093}
1094
1095/*
1096 * In: 'off' is offset from CRB space in 128M pci map
1097 * Out: 'off' is 2M pci map addr
1098 * side effect: lock crb window
1099 */
1100static int
1101qlcnic_pci_set_crbwindow_2M(struct qlcnic_adapter *adapter, ulong off)
1102{
1103        u32 window;
1104        void __iomem *addr = adapter->ahw->pci_base0 + CRB_WINDOW_2M;
1105
1106        off -= QLCNIC_PCI_CRBSPACE;
1107
1108        window = CRB_HI(off);
1109        if (window == 0) {
1110                dev_err(&adapter->pdev->dev, "Invalid offset 0x%lx\n", off);
1111                return -EIO;
1112        }
1113
1114        writel(window, addr);
1115        if (readl(addr) != window) {
1116                if (printk_ratelimit())
1117                        dev_warn(&adapter->pdev->dev,
1118                                "failed to set CRB window to %d off 0x%lx\n",
1119                                window, off);
1120                return -EIO;
1121        }
1122        return 0;
1123}
1124
1125int qlcnic_82xx_hw_write_wx_2M(struct qlcnic_adapter *adapter, ulong off,
1126                               u32 data)
1127{
1128        unsigned long flags;
1129        int rv;
1130        void __iomem *addr = NULL;
1131
1132        rv = qlcnic_pci_get_crb_addr_2M(adapter->ahw, off, &addr);
1133
1134        if (rv == 0) {
1135                writel(data, addr);
1136                return 0;
1137        }
1138
1139        if (rv > 0) {
1140                /* indirect access */
1141                write_lock_irqsave(&adapter->ahw->crb_lock, flags);
1142                crb_win_lock(adapter);
1143                rv = qlcnic_pci_set_crbwindow_2M(adapter, off);
1144                if (!rv)
1145                        writel(data, addr);
1146                crb_win_unlock(adapter);
1147                write_unlock_irqrestore(&adapter->ahw->crb_lock, flags);
1148                return rv;
1149        }
1150
1151        dev_err(&adapter->pdev->dev,
1152                        "%s: invalid offset: 0x%016lx\n", __func__, off);
1153        dump_stack();
1154        return -EIO;
1155}
1156
1157int qlcnic_82xx_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off)
1158{
1159        unsigned long flags;
1160        int rv;
1161        u32 data = -1;
1162        void __iomem *addr = NULL;
1163
1164        rv = qlcnic_pci_get_crb_addr_2M(adapter->ahw, off, &addr);
1165
1166        if (rv == 0)
1167                return readl(addr);
1168
1169        if (rv > 0) {
1170                /* indirect access */
1171                write_lock_irqsave(&adapter->ahw->crb_lock, flags);
1172                crb_win_lock(adapter);
1173                if (!qlcnic_pci_set_crbwindow_2M(adapter, off))
1174                        data = readl(addr);
1175                crb_win_unlock(adapter);
1176                write_unlock_irqrestore(&adapter->ahw->crb_lock, flags);
1177                return data;
1178        }
1179
1180        dev_err(&adapter->pdev->dev,
1181                        "%s: invalid offset: 0x%016lx\n", __func__, off);
1182        dump_stack();
1183        return -1;
1184}
1185
1186void __iomem *qlcnic_get_ioaddr(struct qlcnic_hardware_context *ahw,
1187                                u32 offset)
1188{
1189        void __iomem *addr = NULL;
1190
1191        WARN_ON(qlcnic_pci_get_crb_addr_2M(ahw, offset, &addr));
1192
1193        return addr;
1194}
1195
1196static int qlcnic_pci_mem_access_direct(struct qlcnic_adapter *adapter,
1197                                        u32 window, u64 off, u64 *data, int op)
1198{
1199        void __iomem *addr;
1200        u32 start;
1201
1202        mutex_lock(&adapter->ahw->mem_lock);
1203
1204        writel(window, adapter->ahw->ocm_win_crb);
1205        /* read back to flush */
1206        readl(adapter->ahw->ocm_win_crb);
1207        start = QLCNIC_PCI_OCM0_2M + off;
1208
1209        addr = adapter->ahw->pci_base0 + start;
1210
1211        if (op == 0)    /* read */
1212                *data = readq(addr);
1213        else            /* write */
1214                writeq(*data, addr);
1215
1216        /* Set window to 0 */
1217        writel(0, adapter->ahw->ocm_win_crb);
1218        readl(adapter->ahw->ocm_win_crb);
1219
1220        mutex_unlock(&adapter->ahw->mem_lock);
1221        return 0;
1222}
1223
1224void
1225qlcnic_pci_camqm_read_2M(struct qlcnic_adapter *adapter, u64 off, u64 *data)
1226{
1227        void __iomem *addr = adapter->ahw->pci_base0 +
1228                QLCNIC_PCI_CAMQM_2M_BASE + (off - QLCNIC_PCI_CAMQM);
1229
1230        mutex_lock(&adapter->ahw->mem_lock);
1231        *data = readq(addr);
1232        mutex_unlock(&adapter->ahw->mem_lock);
1233}
1234
1235void
1236qlcnic_pci_camqm_write_2M(struct qlcnic_adapter *adapter, u64 off, u64 data)
1237{
1238        void __iomem *addr = adapter->ahw->pci_base0 +
1239                QLCNIC_PCI_CAMQM_2M_BASE + (off - QLCNIC_PCI_CAMQM);
1240
1241        mutex_lock(&adapter->ahw->mem_lock);
1242        writeq(data, addr);
1243        mutex_unlock(&adapter->ahw->mem_lock);
1244}
1245
1246
1247
1248/* Set MS memory control data for different adapters */
1249static void qlcnic_set_ms_controls(struct qlcnic_adapter *adapter, u64 off,
1250                                   struct qlcnic_ms_reg_ctrl *ms)
1251{
1252        ms->control = QLCNIC_MS_CTRL;
1253        ms->low = QLCNIC_MS_ADDR_LO;
1254        ms->hi = QLCNIC_MS_ADDR_HI;
1255        if (off & 0xf) {
1256                ms->wd[0] = QLCNIC_MS_WRTDATA_LO;
1257                ms->rd[0] = QLCNIC_MS_RDDATA_LO;
1258                ms->wd[1] = QLCNIC_MS_WRTDATA_HI;
1259                ms->rd[1] = QLCNIC_MS_RDDATA_HI;
1260                ms->wd[2] = QLCNIC_MS_WRTDATA_ULO;
1261                ms->wd[3] = QLCNIC_MS_WRTDATA_UHI;
1262                ms->rd[2] = QLCNIC_MS_RDDATA_ULO;
1263                ms->rd[3] = QLCNIC_MS_RDDATA_UHI;
1264        } else {
1265                ms->wd[0] = QLCNIC_MS_WRTDATA_ULO;
1266                ms->rd[0] = QLCNIC_MS_RDDATA_ULO;
1267                ms->wd[1] = QLCNIC_MS_WRTDATA_UHI;
1268                ms->rd[1] = QLCNIC_MS_RDDATA_UHI;
1269                ms->wd[2] = QLCNIC_MS_WRTDATA_LO;
1270                ms->wd[3] = QLCNIC_MS_WRTDATA_HI;
1271                ms->rd[2] = QLCNIC_MS_RDDATA_LO;
1272                ms->rd[3] = QLCNIC_MS_RDDATA_HI;
1273        }
1274
1275        ms->ocm_window = OCM_WIN_P3P(off);
1276        ms->off = GET_MEM_OFFS_2M(off);
1277}
1278
1279int qlcnic_pci_mem_write_2M(struct qlcnic_adapter *adapter, u64 off, u64 data)
1280{
1281        int j, ret = 0;
1282        u32 temp, off8;
1283        struct qlcnic_ms_reg_ctrl ms;
1284
1285        /* Only 64-bit aligned access */
1286        if (off & 7)
1287                return -EIO;
1288
1289        memset(&ms, 0, sizeof(struct qlcnic_ms_reg_ctrl));
1290        if (!(ADDR_IN_RANGE(off, QLCNIC_ADDR_QDR_NET,
1291                            QLCNIC_ADDR_QDR_NET_MAX) ||
1292              ADDR_IN_RANGE(off, QLCNIC_ADDR_DDR_NET,
1293                            QLCNIC_ADDR_DDR_NET_MAX)))
1294                return -EIO;
1295
1296        qlcnic_set_ms_controls(adapter, off, &ms);
1297
1298        if (ADDR_IN_RANGE(off, QLCNIC_ADDR_OCM0, QLCNIC_ADDR_OCM0_MAX))
1299                return qlcnic_pci_mem_access_direct(adapter, ms.ocm_window,
1300                                                    ms.off, &data, 1);
1301
1302        off8 = off & ~0xf;
1303
1304        mutex_lock(&adapter->ahw->mem_lock);
1305
1306        qlcnic_ind_wr(adapter, ms.low, off8);
1307        qlcnic_ind_wr(adapter, ms.hi, 0);
1308
1309        qlcnic_ind_wr(adapter, ms.control, TA_CTL_ENABLE);
1310        qlcnic_ind_wr(adapter, ms.control, QLCNIC_TA_START_ENABLE);
1311
1312        for (j = 0; j < MAX_CTL_CHECK; j++) {
1313                temp = qlcnic_ind_rd(adapter, ms.control);
1314                if ((temp & TA_CTL_BUSY) == 0)
1315                        break;
1316        }
1317
1318        if (j >= MAX_CTL_CHECK) {
1319                ret = -EIO;
1320                goto done;
1321        }
1322
1323        /* This is the modify part of read-modify-write */
1324        qlcnic_ind_wr(adapter, ms.wd[0], qlcnic_ind_rd(adapter, ms.rd[0]));
1325        qlcnic_ind_wr(adapter, ms.wd[1], qlcnic_ind_rd(adapter, ms.rd[1]));
1326        /* This is the write part of read-modify-write */
1327        qlcnic_ind_wr(adapter, ms.wd[2], data & 0xffffffff);
1328        qlcnic_ind_wr(adapter, ms.wd[3], (data >> 32) & 0xffffffff);
1329
1330        qlcnic_ind_wr(adapter, ms.control, QLCNIC_TA_WRITE_ENABLE);
1331        qlcnic_ind_wr(adapter, ms.control, QLCNIC_TA_WRITE_START);
1332
1333        for (j = 0; j < MAX_CTL_CHECK; j++) {
1334                temp = qlcnic_ind_rd(adapter, ms.control);
1335                if ((temp & TA_CTL_BUSY) == 0)
1336                        break;
1337        }
1338
1339        if (j >= MAX_CTL_CHECK) {
1340                if (printk_ratelimit())
1341                        dev_err(&adapter->pdev->dev,
1342                                        "failed to write through agent\n");
1343                ret = -EIO;
1344        } else
1345                ret = 0;
1346
1347done:
1348        mutex_unlock(&adapter->ahw->mem_lock);
1349
1350        return ret;
1351}
1352
1353int qlcnic_pci_mem_read_2M(struct qlcnic_adapter *adapter, u64 off, u64 *data)
1354{
1355        int j, ret;
1356        u32 temp, off8;
1357        u64 val;
1358        struct qlcnic_ms_reg_ctrl ms;
1359
1360        /* Only 64-bit aligned access */
1361        if (off & 7)
1362                return -EIO;
1363        if (!(ADDR_IN_RANGE(off, QLCNIC_ADDR_QDR_NET,
1364                            QLCNIC_ADDR_QDR_NET_MAX) ||
1365              ADDR_IN_RANGE(off, QLCNIC_ADDR_DDR_NET,
1366                            QLCNIC_ADDR_DDR_NET_MAX)))
1367                return -EIO;
1368
1369        memset(&ms, 0, sizeof(struct qlcnic_ms_reg_ctrl));
1370        qlcnic_set_ms_controls(adapter, off, &ms);
1371
1372        if (ADDR_IN_RANGE(off, QLCNIC_ADDR_OCM0, QLCNIC_ADDR_OCM0_MAX))
1373                return qlcnic_pci_mem_access_direct(adapter, ms.ocm_window,
1374                                                    ms.off, data, 0);
1375
1376        mutex_lock(&adapter->ahw->mem_lock);
1377
1378        off8 = off & ~0xf;
1379
1380        qlcnic_ind_wr(adapter, ms.low, off8);
1381        qlcnic_ind_wr(adapter, ms.hi, 0);
1382
1383        qlcnic_ind_wr(adapter, ms.control, TA_CTL_ENABLE);
1384        qlcnic_ind_wr(adapter, ms.control, QLCNIC_TA_START_ENABLE);
1385
1386        for (j = 0; j < MAX_CTL_CHECK; j++) {
1387                temp = qlcnic_ind_rd(adapter, ms.control);
1388                if ((temp & TA_CTL_BUSY) == 0)
1389                        break;
1390        }
1391
1392        if (j >= MAX_CTL_CHECK) {
1393                if (printk_ratelimit())
1394                        dev_err(&adapter->pdev->dev,
1395                                        "failed to read through agent\n");
1396                ret = -EIO;
1397        } else {
1398
1399                temp = qlcnic_ind_rd(adapter, ms.rd[3]);
1400                val = (u64)temp << 32;
1401                val |= qlcnic_ind_rd(adapter, ms.rd[2]);
1402                *data = val;
1403                ret = 0;
1404        }
1405
1406        mutex_unlock(&adapter->ahw->mem_lock);
1407
1408        return ret;
1409}
1410
1411int qlcnic_82xx_get_board_info(struct qlcnic_adapter *adapter)
1412{
1413        int offset, board_type, magic;
1414        struct pci_dev *pdev = adapter->pdev;
1415
1416        offset = QLCNIC_FW_MAGIC_OFFSET;
1417        if (qlcnic_rom_fast_read(adapter, offset, &magic))
1418                return -EIO;
1419
1420        if (magic != QLCNIC_BDINFO_MAGIC) {
1421                dev_err(&pdev->dev, "invalid board config, magic=%08x\n",
1422                        magic);
1423                return -EIO;
1424        }
1425
1426        offset = QLCNIC_BRDTYPE_OFFSET;
1427        if (qlcnic_rom_fast_read(adapter, offset, &board_type))
1428                return -EIO;
1429
1430        adapter->ahw->board_type = board_type;
1431
1432        if (board_type == QLCNIC_BRDTYPE_P3P_4_GB_MM) {
1433                u32 gpio = QLCRD32(adapter, QLCNIC_ROMUSB_GLB_PAD_GPIO_I);
1434                if ((gpio & 0x8000) == 0)
1435                        board_type = QLCNIC_BRDTYPE_P3P_10G_TP;
1436        }
1437
1438        switch (board_type) {
1439        case QLCNIC_BRDTYPE_P3P_HMEZ:
1440        case QLCNIC_BRDTYPE_P3P_XG_LOM:
1441        case QLCNIC_BRDTYPE_P3P_10G_CX4:
1442        case QLCNIC_BRDTYPE_P3P_10G_CX4_LP:
1443        case QLCNIC_BRDTYPE_P3P_IMEZ:
1444        case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS:
1445        case QLCNIC_BRDTYPE_P3P_10G_SFP_CT:
1446        case QLCNIC_BRDTYPE_P3P_10G_SFP_QT:
1447        case QLCNIC_BRDTYPE_P3P_10G_XFP:
1448        case QLCNIC_BRDTYPE_P3P_10000_BASE_T:
1449                adapter->ahw->port_type = QLCNIC_XGBE;
1450                break;
1451        case QLCNIC_BRDTYPE_P3P_REF_QG:
1452        case QLCNIC_BRDTYPE_P3P_4_GB:
1453        case QLCNIC_BRDTYPE_P3P_4_GB_MM:
1454                adapter->ahw->port_type = QLCNIC_GBE;
1455                break;
1456        case QLCNIC_BRDTYPE_P3P_10G_TP:
1457                adapter->ahw->port_type = (adapter->portnum < 2) ?
1458                        QLCNIC_XGBE : QLCNIC_GBE;
1459                break;
1460        default:
1461                dev_err(&pdev->dev, "unknown board type %x\n", board_type);
1462                adapter->ahw->port_type = QLCNIC_XGBE;
1463                break;
1464        }
1465
1466        return 0;
1467}
1468
1469int
1470qlcnic_wol_supported(struct qlcnic_adapter *adapter)
1471{
1472        u32 wol_cfg;
1473
1474        wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
1475        if (wol_cfg & (1UL << adapter->portnum)) {
1476                wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
1477                if (wol_cfg & (1 << adapter->portnum))
1478                        return 1;
1479        }
1480
1481        return 0;
1482}
1483
1484int qlcnic_82xx_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate)
1485{
1486        struct qlcnic_nic_req   req;
1487        int rv;
1488        u64 word;
1489
1490        memset(&req, 0, sizeof(struct qlcnic_nic_req));
1491        req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
1492
1493        word = QLCNIC_H2C_OPCODE_CONFIG_LED | ((u64)adapter->portnum << 16);
1494        req.req_hdr = cpu_to_le64(word);
1495
1496        req.words[0] = cpu_to_le64(((u64)rate << 32) | adapter->portnum);
1497        req.words[1] = cpu_to_le64(state);
1498
1499        rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
1500        if (rv)
1501                dev_err(&adapter->pdev->dev, "LED configuration failed.\n");
1502
1503        return rv;
1504}
1505
1506void qlcnic_82xx_get_func_no(struct qlcnic_adapter *adapter)
1507{
1508        void __iomem *msix_base_addr;
1509        u32 func;
1510        u32 msix_base;
1511
1512        pci_read_config_dword(adapter->pdev, QLCNIC_MSIX_TABLE_OFFSET, &func);
1513        msix_base_addr = adapter->ahw->pci_base0 + QLCNIC_MSIX_BASE;
1514        msix_base = readl(msix_base_addr);
1515        func = (func - msix_base) / QLCNIC_MSIX_TBL_PGSIZE;
1516        adapter->ahw->pci_func = func;
1517}
1518
1519void qlcnic_82xx_read_crb(struct qlcnic_adapter *adapter, char *buf,
1520                          loff_t offset, size_t size)
1521{
1522        u32 data;
1523        u64 qmdata;
1524
1525        if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) {
1526                qlcnic_pci_camqm_read_2M(adapter, offset, &qmdata);
1527                memcpy(buf, &qmdata, size);
1528        } else {
1529                data = QLCRD32(adapter, offset);
1530                memcpy(buf, &data, size);
1531        }
1532}
1533
1534void qlcnic_82xx_write_crb(struct qlcnic_adapter *adapter, char *buf,
1535                           loff_t offset, size_t size)
1536{
1537        u32 data;
1538        u64 qmdata;
1539
1540        if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) {
1541                memcpy(&qmdata, buf, size);
1542                qlcnic_pci_camqm_write_2M(adapter, offset, qmdata);
1543        } else {
1544                memcpy(&data, buf, size);
1545                QLCWR32(adapter, offset, data);
1546        }
1547}
1548
1549int qlcnic_82xx_api_lock(struct qlcnic_adapter *adapter)
1550{
1551        return qlcnic_pcie_sem_lock(adapter, 5, 0);
1552}
1553
1554void qlcnic_82xx_api_unlock(struct qlcnic_adapter *adapter)
1555{
1556        qlcnic_pcie_sem_unlock(adapter, 5);
1557}
1558