1/* 2 * Copyright (C) 2009 - QLogic Corporation. 3 * All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 2 8 * of the License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 18 * MA 02111-1307, USA. 19 * 20 * The full GNU General Public License is included in this distribution 21 * in the file called "COPYING". 22 * 23 */ 24 25#include "qlcnic.h" 26 27#include <linux/slab.h> 28#include <net/ip.h> 29 30#define MASK(n) ((1ULL<<(n))-1) 31#define OCM_WIN_P3P(addr) (addr & 0xffc0000) 32 33#define GET_MEM_OFFS_2M(addr) (addr & MASK(18)) 34 35#define CRB_BLK(off) ((off >> 20) & 0x3f) 36#define CRB_SUBBLK(off) ((off >> 16) & 0xf) 37#define CRB_WINDOW_2M (0x130060) 38#define CRB_HI(off) ((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000)) 39#define CRB_INDIRECT_2M (0x1e0000UL) 40 41 42#ifndef readq 43static inline u64 readq(void __iomem *addr) 44{ 45 return readl(addr) | (((u64) readl(addr + 4)) << 32LL); 46} 47#endif 48 49#ifndef writeq 50static inline void writeq(u64 val, void __iomem *addr) 51{ 52 writel(((u32) (val)), (addr)); 53 writel(((u32) (val >> 32)), (addr + 4)); 54} 55#endif 56 57static const struct crb_128M_2M_block_map 58crb_128M_2M_map[64] __cacheline_aligned_in_smp = { 59 {{{0, 0, 0, 0} } }, /* 0: PCI */ 60 {{{1, 0x0100000, 0x0102000, 0x120000}, /* 1: PCIE */ 61 {1, 0x0110000, 0x0120000, 0x130000}, 62 {1, 0x0120000, 0x0122000, 0x124000}, 63 {1, 0x0130000, 0x0132000, 0x126000}, 64 {1, 0x0140000, 0x0142000, 0x128000}, 65 {1, 0x0150000, 0x0152000, 0x12a000}, 66 {1, 0x0160000, 0x0170000, 0x110000}, 67 {1, 0x0170000, 0x0172000, 0x12e000}, 68 {0, 0x0000000, 0x0000000, 0x000000}, 69 {0, 0x0000000, 0x0000000, 0x000000}, 70 {0, 0x0000000, 0x0000000, 0x000000}, 71 {0, 0x0000000, 0x0000000, 0x000000}, 72 {0, 0x0000000, 0x0000000, 0x000000}, 73 {0, 0x0000000, 0x0000000, 0x000000}, 74 {1, 0x01e0000, 0x01e0800, 0x122000}, 75 {0, 0x0000000, 0x0000000, 0x000000} } }, 76 {{{1, 0x0200000, 0x0210000, 0x180000} } },/* 2: MN */ 77 {{{0, 0, 0, 0} } }, /* 3: */ 78 {{{1, 0x0400000, 0x0401000, 0x169000} } },/* 4: P2NR1 */ 79 {{{1, 0x0500000, 0x0510000, 0x140000} } },/* 5: SRE */ 80 {{{1, 0x0600000, 0x0610000, 0x1c0000} } },/* 6: NIU */ 81 {{{1, 0x0700000, 0x0704000, 0x1b8000} } },/* 7: QM */ 82 {{{1, 0x0800000, 0x0802000, 0x170000}, /* 8: SQM0 */ 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 {0, 0x0000000, 0x0000000, 0x000000}, 92 {0, 0x0000000, 0x0000000, 0x000000}, 93 {0, 0x0000000, 0x0000000, 0x000000}, 94 {0, 0x0000000, 0x0000000, 0x000000}, 95 {0, 0x0000000, 0x0000000, 0x000000}, 96 {0, 0x0000000, 0x0000000, 0x000000}, 97 {1, 0x08f0000, 0x08f2000, 0x172000} } }, 98 {{{1, 0x0900000, 0x0902000, 0x174000}, /* 9: SQM1*/ 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 {0, 0x0000000, 0x0000000, 0x000000}, 108 {0, 0x0000000, 0x0000000, 0x000000}, 109 {0, 0x0000000, 0x0000000, 0x000000}, 110 {0, 0x0000000, 0x0000000, 0x000000}, 111 {0, 0x0000000, 0x0000000, 0x000000}, 112 {0, 0x0000000, 0x0000000, 0x000000}, 113 {1, 0x09f0000, 0x09f2000, 0x176000} } }, 114 {{{0, 0x0a00000, 0x0a02000, 0x178000}, /* 10: SQM2*/ 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 {0, 0x0000000, 0x0000000, 0x000000}, 124 {0, 0x0000000, 0x0000000, 0x000000}, 125 {0, 0x0000000, 0x0000000, 0x000000}, 126 {0, 0x0000000, 0x0000000, 0x000000}, 127 {0, 0x0000000, 0x0000000, 0x000000}, 128 {0, 0x0000000, 0x0000000, 0x000000}, 129 {1, 0x0af0000, 0x0af2000, 0x17a000} } }, 130 {{{0, 0x0b00000, 0x0b02000, 0x17c000}, /* 11: SQM3*/ 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 {0, 0x0000000, 0x0000000, 0x000000}, 140 {0, 0x0000000, 0x0000000, 0x000000}, 141 {0, 0x0000000, 0x0000000, 0x000000}, 142 {0, 0x0000000, 0x0000000, 0x000000}, 143 {0, 0x0000000, 0x0000000, 0x000000}, 144 {0, 0x0000000, 0x0000000, 0x000000}, 145 {1, 0x0bf0000, 0x0bf2000, 0x17e000} } }, 146 {{{1, 0x0c00000, 0x0c04000, 0x1d4000} } },/* 12: I2Q */ 147 {{{1, 0x0d00000, 0x0d04000, 0x1a4000} } },/* 13: TMR */ 148 {{{1, 0x0e00000, 0x0e04000, 0x1a0000} } },/* 14: ROMUSB */ 149 {{{1, 0x0f00000, 0x0f01000, 0x164000} } },/* 15: PEG4 */ 150 {{{0, 0x1000000, 0x1004000, 0x1a8000} } },/* 16: XDMA */ 151 {{{1, 0x1100000, 0x1101000, 0x160000} } },/* 17: PEG0 */ 152 {{{1, 0x1200000, 0x1201000, 0x161000} } },/* 18: PEG1 */ 153 {{{1, 0x1300000, 0x1301000, 0x162000} } },/* 19: PEG2 */ 154 {{{1, 0x1400000, 0x1401000, 0x163000} } },/* 20: PEG3 */ 155 {{{1, 0x1500000, 0x1501000, 0x165000} } },/* 21: P2ND */ 156 {{{1, 0x1600000, 0x1601000, 0x166000} } },/* 22: P2NI */ 157 {{{0, 0, 0, 0} } }, /* 23: */ 158 {{{0, 0, 0, 0} } }, /* 24: */ 159 {{{0, 0, 0, 0} } }, /* 25: */ 160 {{{0, 0, 0, 0} } }, /* 26: */ 161 {{{0, 0, 0, 0} } }, /* 27: */ 162 {{{0, 0, 0, 0} } }, /* 28: */ 163 {{{1, 0x1d00000, 0x1d10000, 0x190000} } },/* 29: MS */ 164 {{{1, 0x1e00000, 0x1e01000, 0x16a000} } },/* 30: P2NR2 */ 165 {{{1, 0x1f00000, 0x1f10000, 0x150000} } },/* 31: EPG */ 166 {{{0} } }, /* 32: PCI */ 167 {{{1, 0x2100000, 0x2102000, 0x120000}, /* 33: PCIE */ 168 {1, 0x2110000, 0x2120000, 0x130000}, 169 {1, 0x2120000, 0x2122000, 0x124000}, 170 {1, 0x2130000, 0x2132000, 0x126000}, 171 {1, 0x2140000, 0x2142000, 0x128000}, 172 {1, 0x2150000, 0x2152000, 0x12a000}, 173 {1, 0x2160000, 0x2170000, 0x110000}, 174 {1, 0x2170000, 0x2172000, 0x12e000}, 175 {0, 0x0000000, 0x0000000, 0x000000}, 176 {0, 0x0000000, 0x0000000, 0x000000}, 177 {0, 0x0000000, 0x0000000, 0x000000}, 178 {0, 0x0000000, 0x0000000, 0x000000}, 179 {0, 0x0000000, 0x0000000, 0x000000}, 180 {0, 0x0000000, 0x0000000, 0x000000}, 181 {0, 0x0000000, 0x0000000, 0x000000}, 182 {0, 0x0000000, 0x0000000, 0x000000} } }, 183 {{{1, 0x2200000, 0x2204000, 0x1b0000} } },/* 34: CAM */ 184 {{{0} } }, /* 35: */ 185 {{{0} } }, /* 36: */ 186 {{{0} } }, /* 37: */ 187 {{{0} } }, /* 38: */ 188 {{{0} } }, /* 39: */ 189 {{{1, 0x2800000, 0x2804000, 0x1a4000} } },/* 40: TMR */ 190 {{{1, 0x2900000, 0x2901000, 0x16b000} } },/* 41: P2NR3 */ 191 {{{1, 0x2a00000, 0x2a00400, 0x1ac400} } },/* 42: RPMX1 */ 192 {{{1, 0x2b00000, 0x2b00400, 0x1ac800} } },/* 43: RPMX2 */ 193 {{{1, 0x2c00000, 0x2c00400, 0x1acc00} } },/* 44: RPMX3 */ 194 {{{1, 0x2d00000, 0x2d00400, 0x1ad000} } },/* 45: RPMX4 */ 195 {{{1, 0x2e00000, 0x2e00400, 0x1ad400} } },/* 46: RPMX5 */ 196 {{{1, 0x2f00000, 0x2f00400, 0x1ad800} } },/* 47: RPMX6 */ 197 {{{1, 0x3000000, 0x3000400, 0x1adc00} } },/* 48: RPMX7 */ 198 {{{0, 0x3100000, 0x3104000, 0x1a8000} } },/* 49: XDMA */ 199 {{{1, 0x3200000, 0x3204000, 0x1d4000} } },/* 50: I2Q */ 200 {{{1, 0x3300000, 0x3304000, 0x1a0000} } },/* 51: ROMUSB */ 201 {{{0} } }, /* 52: */ 202 {{{1, 0x3500000, 0x3500400, 0x1ac000} } },/* 53: RPMX0 */ 203 {{{1, 0x3600000, 0x3600400, 0x1ae000} } },/* 54: RPMX8 */ 204 {{{1, 0x3700000, 0x3700400, 0x1ae400} } },/* 55: RPMX9 */ 205 {{{1, 0x3800000, 0x3804000, 0x1d0000} } },/* 56: OCM0 */ 206 {{{1, 0x3900000, 0x3904000, 0x1b4000} } },/* 57: CRYPTO */ 207 {{{1, 0x3a00000, 0x3a04000, 0x1d8000} } },/* 58: SMB */ 208 {{{0} } }, /* 59: I2C0 */ 209 {{{0} } }, /* 60: I2C1 */ 210 {{{1, 0x3d00000, 0x3d04000, 0x1d8000} } },/* 61: LPC */ 211 {{{1, 0x3e00000, 0x3e01000, 0x167000} } },/* 62: P2NC */ 212 {{{1, 0x3f00000, 0x3f01000, 0x168000} } } /* 63: P2NR0 */ 213}; 214 215/* 216 * top 12 bits of crb internal address (hub, agent) 217 */ 218static const unsigned crb_hub_agt[64] = { 219 0, 220 QLCNIC_HW_CRB_HUB_AGT_ADR_PS, 221 QLCNIC_HW_CRB_HUB_AGT_ADR_MN, 222 QLCNIC_HW_CRB_HUB_AGT_ADR_MS, 223 0, 224 QLCNIC_HW_CRB_HUB_AGT_ADR_SRE, 225 QLCNIC_HW_CRB_HUB_AGT_ADR_NIU, 226 QLCNIC_HW_CRB_HUB_AGT_ADR_QMN, 227 QLCNIC_HW_CRB_HUB_AGT_ADR_SQN0, 228 QLCNIC_HW_CRB_HUB_AGT_ADR_SQN1, 229 QLCNIC_HW_CRB_HUB_AGT_ADR_SQN2, 230 QLCNIC_HW_CRB_HUB_AGT_ADR_SQN3, 231 QLCNIC_HW_CRB_HUB_AGT_ADR_I2Q, 232 QLCNIC_HW_CRB_HUB_AGT_ADR_TIMR, 233 QLCNIC_HW_CRB_HUB_AGT_ADR_ROMUSB, 234 QLCNIC_HW_CRB_HUB_AGT_ADR_PGN4, 235 QLCNIC_HW_CRB_HUB_AGT_ADR_XDMA, 236 QLCNIC_HW_CRB_HUB_AGT_ADR_PGN0, 237 QLCNIC_HW_CRB_HUB_AGT_ADR_PGN1, 238 QLCNIC_HW_CRB_HUB_AGT_ADR_PGN2, 239 QLCNIC_HW_CRB_HUB_AGT_ADR_PGN3, 240 QLCNIC_HW_CRB_HUB_AGT_ADR_PGND, 241 QLCNIC_HW_CRB_HUB_AGT_ADR_PGNI, 242 QLCNIC_HW_CRB_HUB_AGT_ADR_PGS0, 243 QLCNIC_HW_CRB_HUB_AGT_ADR_PGS1, 244 QLCNIC_HW_CRB_HUB_AGT_ADR_PGS2, 245 QLCNIC_HW_CRB_HUB_AGT_ADR_PGS3, 246 0, 247 QLCNIC_HW_CRB_HUB_AGT_ADR_PGSI, 248 QLCNIC_HW_CRB_HUB_AGT_ADR_SN, 249 0, 250 QLCNIC_HW_CRB_HUB_AGT_ADR_EG, 251 0, 252 QLCNIC_HW_CRB_HUB_AGT_ADR_PS, 253 QLCNIC_HW_CRB_HUB_AGT_ADR_CAM, 254 0, 255 0, 256 0, 257 0, 258 0, 259 QLCNIC_HW_CRB_HUB_AGT_ADR_TIMR, 260 0, 261 QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX1, 262 QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX2, 263 QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX3, 264 QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX4, 265 QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX5, 266 QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX6, 267 QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX7, 268 QLCNIC_HW_CRB_HUB_AGT_ADR_XDMA, 269 QLCNIC_HW_CRB_HUB_AGT_ADR_I2Q, 270 QLCNIC_HW_CRB_HUB_AGT_ADR_ROMUSB, 271 0, 272 QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX0, 273 QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX8, 274 QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX9, 275 QLCNIC_HW_CRB_HUB_AGT_ADR_OCM0, 276 0, 277 QLCNIC_HW_CRB_HUB_AGT_ADR_SMB, 278 QLCNIC_HW_CRB_HUB_AGT_ADR_I2C0, 279 QLCNIC_HW_CRB_HUB_AGT_ADR_I2C1, 280 0, 281 QLCNIC_HW_CRB_HUB_AGT_ADR_PGNC, 282 0, 283}; 284 285/* PCI Windowing for DDR regions. */ 286 287#define QLCNIC_PCIE_SEM_TIMEOUT 10000 288 289int 290qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg) 291{ 292 int done = 0, timeout = 0; 293 294 while (!done) { 295 done = QLCRD32(adapter, QLCNIC_PCIE_REG(PCIE_SEM_LOCK(sem))); 296 if (done == 1) 297 break; 298 if (++timeout >= QLCNIC_PCIE_SEM_TIMEOUT) { 299 dev_err(&adapter->pdev->dev, 300 "Failed to acquire sem=%d lock;reg_id=%d\n", 301 sem, id_reg); 302 return -EIO; 303 } 304 msleep(1); 305 } 306 307 if (id_reg) 308 QLCWR32(adapter, id_reg, adapter->portnum); 309 310 return 0; 311} 312 313void 314qlcnic_pcie_sem_unlock(struct qlcnic_adapter *adapter, int sem) 315{ 316 QLCRD32(adapter, QLCNIC_PCIE_REG(PCIE_SEM_UNLOCK(sem))); 317} 318 319static int 320qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter, 321 struct cmd_desc_type0 *cmd_desc_arr, int nr_desc) 322{ 323 u32 i, producer, consumer; 324 struct qlcnic_cmd_buffer *pbuf; 325 struct cmd_desc_type0 *cmd_desc; 326 struct qlcnic_host_tx_ring *tx_ring; 327 328 i = 0; 329 330 if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) 331 return -EIO; 332 333 tx_ring = adapter->tx_ring; 334 __netif_tx_lock_bh(tx_ring->txq); 335 336 producer = tx_ring->producer; 337 consumer = tx_ring->sw_consumer; 338 339 if (nr_desc >= qlcnic_tx_avail(tx_ring)) { 340 netif_tx_stop_queue(tx_ring->txq); 341 smp_mb(); 342 if (qlcnic_tx_avail(tx_ring) > nr_desc) { 343 if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH) 344 netif_tx_wake_queue(tx_ring->txq); 345 } else { 346 adapter->stats.xmit_off++; 347 __netif_tx_unlock_bh(tx_ring->txq); 348 return -EBUSY; 349 } 350 } 351 352 do { 353 cmd_desc = &cmd_desc_arr[i]; 354 355 pbuf = &tx_ring->cmd_buf_arr[producer]; 356 pbuf->skb = NULL; 357 pbuf->frag_count = 0; 358 359 memcpy(&tx_ring->desc_head[producer], 360 &cmd_desc_arr[i], sizeof(struct cmd_desc_type0)); 361 362 producer = get_next_index(producer, tx_ring->num_desc); 363 i++; 364 365 } while (i != nr_desc); 366 367 tx_ring->producer = producer; 368 369 qlcnic_update_cmd_producer(adapter, tx_ring); 370 371 __netif_tx_unlock_bh(tx_ring->txq); 372 373 return 0; 374} 375 376static int 377qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, 378 unsigned op) 379{ 380 struct qlcnic_nic_req req; 381 struct qlcnic_mac_req *mac_req; 382 u64 word; 383 384 memset(&req, 0, sizeof(struct qlcnic_nic_req)); 385 req.qhdr = cpu_to_le64(QLCNIC_REQUEST << 23); 386 387 word = QLCNIC_MAC_EVENT | ((u64)adapter->portnum << 16); 388 req.req_hdr = cpu_to_le64(word); 389 390 mac_req = (struct qlcnic_mac_req *)&req.words[0]; 391 mac_req->op = op; 392 memcpy(mac_req->mac_addr, addr, 6); 393 394 return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); 395} 396 397static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, u8 *addr) 398{ 399 struct list_head *head; 400 struct qlcnic_mac_list_s *cur; 401 402 /* look up if already exists */ 403 list_for_each(head, &adapter->mac_list) { 404 cur = list_entry(head, struct qlcnic_mac_list_s, list); 405 if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) 406 return 0; 407 } 408 409 cur = kzalloc(sizeof(struct qlcnic_mac_list_s), GFP_ATOMIC); 410 if (cur == NULL) { 411 dev_err(&adapter->netdev->dev, 412 "failed to add mac address filter\n"); 413 return -ENOMEM; 414 } 415 memcpy(cur->mac_addr, addr, ETH_ALEN); 416 417 if (qlcnic_sre_macaddr_change(adapter, 418 cur->mac_addr, QLCNIC_MAC_ADD)) { 419 kfree(cur); 420 return -EIO; 421 } 422 423 list_add_tail(&cur->list, &adapter->mac_list); 424 return 0; 425} 426 427void qlcnic_set_multi(struct net_device *netdev) 428{ 429 struct qlcnic_adapter *adapter = netdev_priv(netdev); 430 struct netdev_hw_addr *ha; 431 u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 432 u32 mode = VPORT_MISS_MODE_DROP; 433 434 if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) 435 return; 436 437 qlcnic_nic_add_mac(adapter, adapter->mac_addr); 438 qlcnic_nic_add_mac(adapter, bcast_addr); 439 440 if (netdev->flags & IFF_PROMISC) { 441 mode = VPORT_MISS_MODE_ACCEPT_ALL; 442 goto send_fw_cmd; 443 } 444 445 if ((netdev->flags & IFF_ALLMULTI) || 446 (netdev_mc_count(netdev) > adapter->max_mc_count)) { 447 mode = VPORT_MISS_MODE_ACCEPT_MULTI; 448 goto send_fw_cmd; 449 } 450 451 if (!netdev_mc_empty(netdev)) { 452 netdev_for_each_mc_addr(ha, netdev) { 453 qlcnic_nic_add_mac(adapter, ha->addr); 454 } 455 } 456 457send_fw_cmd: 458 qlcnic_nic_set_promisc(adapter, mode); 459} 460 461int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) 462{ 463 struct qlcnic_nic_req req; 464 u64 word; 465 466 memset(&req, 0, sizeof(struct qlcnic_nic_req)); 467 468 req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); 469 470 word = QLCNIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE | 471 ((u64)adapter->portnum << 16); 472 req.req_hdr = cpu_to_le64(word); 473 474 req.words[0] = cpu_to_le64(mode); 475 476 return qlcnic_send_cmd_descs(adapter, 477 (struct cmd_desc_type0 *)&req, 1); 478} 479 480void qlcnic_free_mac_list(struct qlcnic_adapter *adapter) 481{ 482 struct qlcnic_mac_list_s *cur; 483 struct list_head *head = &adapter->mac_list; 484 485 while (!list_empty(head)) { 486 cur = list_entry(head->next, struct qlcnic_mac_list_s, list); 487 qlcnic_sre_macaddr_change(adapter, 488 cur->mac_addr, QLCNIC_MAC_DEL); 489 list_del(&cur->list); 490 kfree(cur); 491 } 492} 493 494#define QLCNIC_CONFIG_INTR_COALESCE 3 495 496/* 497 * Send the interrupt coalescing parameter set by ethtool to the card. 498 */ 499int qlcnic_config_intr_coalesce(struct qlcnic_adapter *adapter) 500{ 501 struct qlcnic_nic_req req; 502 u64 word[6]; 503 int rv, i; 504 505 memset(&req, 0, sizeof(struct qlcnic_nic_req)); 506 507 req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); 508 509 word[0] = QLCNIC_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16); 510 req.req_hdr = cpu_to_le64(word[0]); 511 512 memcpy(&word[0], &adapter->coal, sizeof(adapter->coal)); 513 for (i = 0; i < 6; i++) 514 req.words[i] = cpu_to_le64(word[i]); 515 516 rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); 517 if (rv != 0) 518 dev_err(&adapter->netdev->dev, 519 "Could not send interrupt coalescing parameters\n"); 520 521 return rv; 522} 523 524int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable) 525{ 526 struct qlcnic_nic_req req; 527 u64 word; 528 int rv; 529 530 if ((adapter->flags & QLCNIC_LRO_ENABLED) == enable) 531 return 0; 532 533 memset(&req, 0, sizeof(struct qlcnic_nic_req)); 534 535 req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); 536 537 word = QLCNIC_H2C_OPCODE_CONFIG_HW_LRO | ((u64)adapter->portnum << 16); 538 req.req_hdr = cpu_to_le64(word); 539 540 req.words[0] = cpu_to_le64(enable); 541 542 rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); 543 if (rv != 0) 544 dev_err(&adapter->netdev->dev, 545 "Could not send configure hw lro request\n"); 546 547 adapter->flags ^= QLCNIC_LRO_ENABLED; 548 549 return rv; 550} 551 552int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable) 553{ 554 struct qlcnic_nic_req req; 555 u64 word; 556 int rv; 557 558 if (!!(adapter->flags & QLCNIC_BRIDGE_ENABLED) == enable) 559 return 0; 560 561 memset(&req, 0, sizeof(struct qlcnic_nic_req)); 562 563 req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); 564 565 word = QLCNIC_H2C_OPCODE_CONFIG_BRIDGING | 566 ((u64)adapter->portnum << 16); 567 req.req_hdr = cpu_to_le64(word); 568 569 req.words[0] = cpu_to_le64(enable); 570 571 rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); 572 if (rv != 0) 573 dev_err(&adapter->netdev->dev, 574 "Could not send configure bridge mode request\n"); 575 576 adapter->flags ^= QLCNIC_BRIDGE_ENABLED; 577 578 return rv; 579} 580 581 582#define RSS_HASHTYPE_IP_TCP 0x3 583 584int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable) 585{ 586 struct qlcnic_nic_req req; 587 u64 word; 588 int i, rv; 589 590 const u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL, 591 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL, 592 0x255b0ec26d5a56daULL }; 593 594 595 memset(&req, 0, sizeof(struct qlcnic_nic_req)); 596 req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); 597 598 word = QLCNIC_H2C_OPCODE_CONFIG_RSS | ((u64)adapter->portnum << 16); 599 req.req_hdr = cpu_to_le64(word); 600 601 /* 602 * RSS request: 603 * bits 3-0: hash_method 604 * 5-4: hash_type_ipv4 605 * 7-6: hash_type_ipv6 606 * 8: enable 607 * 9: use indirection table 608 * 47-10: reserved 609 * 63-48: indirection table mask 610 */ 611 word = ((u64)(RSS_HASHTYPE_IP_TCP & 0x3) << 4) | 612 ((u64)(RSS_HASHTYPE_IP_TCP & 0x3) << 6) | 613 ((u64)(enable & 0x1) << 8) | 614 ((0x7ULL) << 48); 615 req.words[0] = cpu_to_le64(word); 616 for (i = 0; i < 5; i++) 617 req.words[i+1] = cpu_to_le64(key[i]); 618 619 rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); 620 if (rv != 0) 621 dev_err(&adapter->netdev->dev, "could not configure RSS\n"); 622 623 return rv; 624} 625 626int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, u32 ip, int cmd) 627{ 628 struct qlcnic_nic_req req; 629 u64 word; 630 int rv; 631 632 memset(&req, 0, sizeof(struct qlcnic_nic_req)); 633 req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); 634 635 word = QLCNIC_H2C_OPCODE_CONFIG_IPADDR | ((u64)adapter->portnum << 16); 636 req.req_hdr = cpu_to_le64(word); 637 638 req.words[0] = cpu_to_le64(cmd); 639 req.words[1] = cpu_to_le64(ip); 640 641 rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); 642 if (rv != 0) 643 dev_err(&adapter->netdev->dev, 644 "could not notify %s IP 0x%x reuqest\n", 645 (cmd == QLCNIC_IP_UP) ? "Add" : "Remove", ip); 646 647 return rv; 648} 649 650int qlcnic_linkevent_request(struct qlcnic_adapter *adapter, int enable) 651{ 652 struct qlcnic_nic_req req; 653 u64 word; 654 int rv; 655 656 memset(&req, 0, sizeof(struct qlcnic_nic_req)); 657 req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); 658 659 word = QLCNIC_H2C_OPCODE_GET_LINKEVENT | ((u64)adapter->portnum << 16); 660 req.req_hdr = cpu_to_le64(word); 661 req.words[0] = cpu_to_le64(enable | (enable << 8)); 662 663 rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); 664 if (rv != 0) 665 dev_err(&adapter->netdev->dev, 666 "could not configure link notification\n"); 667 668 return rv; 669} 670 671int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter) 672{ 673 struct qlcnic_nic_req req; 674 u64 word; 675 int rv; 676 677 memset(&req, 0, sizeof(struct qlcnic_nic_req)); 678 req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); 679 680 word = QLCNIC_H2C_OPCODE_LRO_REQUEST | 681 ((u64)adapter->portnum << 16) | 682 ((u64)QLCNIC_LRO_REQUEST_CLEANUP << 56) ; 683 684 req.req_hdr = cpu_to_le64(word); 685 686 rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); 687 if (rv != 0) 688 dev_err(&adapter->netdev->dev, 689 "could not cleanup lro flows\n"); 690 691 return rv; 692} 693 694/* 695 * qlcnic_change_mtu - Change the Maximum Transfer Unit 696 * @returns 0 on success, negative on failure 697 */ 698 699int qlcnic_change_mtu(struct net_device *netdev, int mtu) 700{ 701 struct qlcnic_adapter *adapter = netdev_priv(netdev); 702 int rc = 0; 703 704 if (mtu > P3_MAX_MTU) { 705 dev_err(&adapter->netdev->dev, "mtu > %d bytes unsupported\n", 706 P3_MAX_MTU); 707 return -EINVAL; 708 } 709 710 rc = qlcnic_fw_cmd_set_mtu(adapter, mtu); 711 712 if (!rc) 713 netdev->mtu = mtu; 714 715 return rc; 716} 717 718int qlcnic_get_mac_addr(struct qlcnic_adapter *adapter, u8 *mac) 719{ 720 u32 crbaddr; 721 int pci_func = adapter->ahw.pci_func; 722 723 crbaddr = CRB_MAC_BLOCK_START + 724 (4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1)); 725 726 qlcnic_fetch_mac(adapter, crbaddr, crbaddr+4, pci_func & 1, mac); 727 728 return 0; 729} 730 731/* 732 * Changes the CRB window to the specified window. 733 */ 734 /* Returns < 0 if off is not valid, 735 * 1 if window access is needed. 'off' is set to offset from 736 * CRB space in 128M pci map 737 * 0 if no window access is needed. 'off' is set to 2M addr 738 * In: 'off' is offset from base in 128M pci map 739 */ 740static int 741qlcnic_pci_get_crb_addr_2M(struct qlcnic_adapter *adapter, 742 ulong off, void __iomem **addr) 743{ 744 const struct crb_128M_2M_sub_block_map *m; 745 746 if ((off >= QLCNIC_CRB_MAX) || (off < QLCNIC_PCI_CRBSPACE)) 747 return -EINVAL; 748 749 off -= QLCNIC_PCI_CRBSPACE; 750 751 /* 752 * Try direct map 753 */ 754 m = &crb_128M_2M_map[CRB_BLK(off)].sub_block[CRB_SUBBLK(off)]; 755 756 if (m->valid && (m->start_128M <= off) && (m->end_128M > off)) { 757 *addr = adapter->ahw.pci_base0 + m->start_2M + 758 (off - m->start_128M); 759 return 0; 760 } 761 762 /* 763 * Not in direct map, use crb window 764 */ 765 *addr = adapter->ahw.pci_base0 + CRB_INDIRECT_2M + (off & MASK(16)); 766 return 1; 767} 768 769/* 770 * In: 'off' is offset from CRB space in 128M pci map 771 * Out: 'off' is 2M pci map addr 772 * side effect: lock crb window 773 */ 774static int 775qlcnic_pci_set_crbwindow_2M(struct qlcnic_adapter *adapter, ulong off) 776{ 777 u32 window; 778 void __iomem *addr = adapter->ahw.pci_base0 + CRB_WINDOW_2M; 779 780 off -= QLCNIC_PCI_CRBSPACE; 781 782 window = CRB_HI(off); 783 if (window == 0) { 784 dev_err(&adapter->pdev->dev, "Invalid offset 0x%lx\n", off); 785 return -EIO; 786 } 787 788 writel(window, addr); 789 if (readl(addr) != window) { 790 if (printk_ratelimit()) 791 dev_warn(&adapter->pdev->dev, 792 "failed to set CRB window to %d off 0x%lx\n", 793 window, off); 794 return -EIO; 795 } 796 return 0; 797} 798 799int 800qlcnic_hw_write_wx_2M(struct qlcnic_adapter *adapter, ulong off, u32 data) 801{ 802 unsigned long flags; 803 int rv; 804 void __iomem *addr = NULL; 805 806 rv = qlcnic_pci_get_crb_addr_2M(adapter, off, &addr); 807 808 if (rv == 0) { 809 writel(data, addr); 810 return 0; 811 } 812 813 if (rv > 0) { 814 /* indirect access */ 815 write_lock_irqsave(&adapter->ahw.crb_lock, flags); 816 crb_win_lock(adapter); 817 rv = qlcnic_pci_set_crbwindow_2M(adapter, off); 818 if (!rv) 819 writel(data, addr); 820 crb_win_unlock(adapter); 821 write_unlock_irqrestore(&adapter->ahw.crb_lock, flags); 822 return rv; 823 } 824 825 dev_err(&adapter->pdev->dev, 826 "%s: invalid offset: 0x%016lx\n", __func__, off); 827 dump_stack(); 828 return -EIO; 829} 830 831u32 832qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off) 833{ 834 unsigned long flags; 835 int rv; 836 u32 data = -1; 837 void __iomem *addr = NULL; 838 839 rv = qlcnic_pci_get_crb_addr_2M(adapter, off, &addr); 840 841 if (rv == 0) 842 return readl(addr); 843 844 if (rv > 0) { 845 /* indirect access */ 846 write_lock_irqsave(&adapter->ahw.crb_lock, flags); 847 crb_win_lock(adapter); 848 if (!qlcnic_pci_set_crbwindow_2M(adapter, off)) 849 data = readl(addr); 850 crb_win_unlock(adapter); 851 write_unlock_irqrestore(&adapter->ahw.crb_lock, flags); 852 return data; 853 } 854 855 dev_err(&adapter->pdev->dev, 856 "%s: invalid offset: 0x%016lx\n", __func__, off); 857 dump_stack(); 858 return -1; 859} 860 861 862void __iomem * 863qlcnic_get_ioaddr(struct qlcnic_adapter *adapter, u32 offset) 864{ 865 void __iomem *addr = NULL; 866 867 WARN_ON(qlcnic_pci_get_crb_addr_2M(adapter, offset, &addr)); 868 869 return addr; 870} 871 872 873static int 874qlcnic_pci_set_window_2M(struct qlcnic_adapter *adapter, 875 u64 addr, u32 *start) 876{ 877 u32 window; 878 879 window = OCM_WIN_P3P(addr); 880 881 writel(window, adapter->ahw.ocm_win_crb); 882 /* read back to flush */ 883 readl(adapter->ahw.ocm_win_crb); 884 885 *start = QLCNIC_PCI_OCM0_2M + GET_MEM_OFFS_2M(addr); 886 return 0; 887} 888 889static int 890qlcnic_pci_mem_access_direct(struct qlcnic_adapter *adapter, u64 off, 891 u64 *data, int op) 892{ 893 void __iomem *addr; 894 int ret; 895 u32 start; 896 897 mutex_lock(&adapter->ahw.mem_lock); 898 899 ret = qlcnic_pci_set_window_2M(adapter, off, &start); 900 if (ret != 0) 901 goto unlock; 902 903 addr = adapter->ahw.pci_base0 + start; 904 905 if (op == 0) /* read */ 906 *data = readq(addr); 907 else /* write */ 908 writeq(*data, addr); 909 910unlock: 911 mutex_unlock(&adapter->ahw.mem_lock); 912 913 return ret; 914} 915 916void 917qlcnic_pci_camqm_read_2M(struct qlcnic_adapter *adapter, u64 off, u64 *data) 918{ 919 void __iomem *addr = adapter->ahw.pci_base0 + 920 QLCNIC_PCI_CAMQM_2M_BASE + (off - QLCNIC_PCI_CAMQM); 921 922 mutex_lock(&adapter->ahw.mem_lock); 923 *data = readq(addr); 924 mutex_unlock(&adapter->ahw.mem_lock); 925} 926 927void 928qlcnic_pci_camqm_write_2M(struct qlcnic_adapter *adapter, u64 off, u64 data) 929{ 930 void __iomem *addr = adapter->ahw.pci_base0 + 931 QLCNIC_PCI_CAMQM_2M_BASE + (off - QLCNIC_PCI_CAMQM); 932 933 mutex_lock(&adapter->ahw.mem_lock); 934 writeq(data, addr); 935 mutex_unlock(&adapter->ahw.mem_lock); 936} 937 938#define MAX_CTL_CHECK 1000 939 940int 941qlcnic_pci_mem_write_2M(struct qlcnic_adapter *adapter, 942 u64 off, u64 data) 943{ 944 int i, j, ret; 945 u32 temp, off8; 946 void __iomem *mem_crb; 947 948 /* Only 64-bit aligned access */ 949 if (off & 7) 950 return -EIO; 951 952 /* P3 onward, test agent base for MIU and SIU is same */ 953 if (ADDR_IN_RANGE(off, QLCNIC_ADDR_QDR_NET, 954 QLCNIC_ADDR_QDR_NET_MAX)) { 955 mem_crb = qlcnic_get_ioaddr(adapter, 956 QLCNIC_CRB_QDR_NET+MIU_TEST_AGT_BASE); 957 goto correct; 958 } 959 960 if (ADDR_IN_RANGE(off, QLCNIC_ADDR_DDR_NET, QLCNIC_ADDR_DDR_NET_MAX)) { 961 mem_crb = qlcnic_get_ioaddr(adapter, 962 QLCNIC_CRB_DDR_NET+MIU_TEST_AGT_BASE); 963 goto correct; 964 } 965 966 if (ADDR_IN_RANGE(off, QLCNIC_ADDR_OCM0, QLCNIC_ADDR_OCM0_MAX)) 967 return qlcnic_pci_mem_access_direct(adapter, off, &data, 1); 968 969 return -EIO; 970 971correct: 972 off8 = off & ~0xf; 973 974 mutex_lock(&adapter->ahw.mem_lock); 975 976 writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO)); 977 writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI)); 978 979 i = 0; 980 writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL)); 981 writel((TA_CTL_START | TA_CTL_ENABLE), 982 (mem_crb + TEST_AGT_CTRL)); 983 984 for (j = 0; j < MAX_CTL_CHECK; j++) { 985 temp = readl(mem_crb + TEST_AGT_CTRL); 986 if ((temp & TA_CTL_BUSY) == 0) 987 break; 988 } 989 990 if (j >= MAX_CTL_CHECK) { 991 ret = -EIO; 992 goto done; 993 } 994 995 i = (off & 0xf) ? 0 : 2; 996 writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i)), 997 mem_crb + MIU_TEST_AGT_WRDATA(i)); 998 writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i+1)), 999 mem_crb + MIU_TEST_AGT_WRDATA(i+1)); 1000 i = (off & 0xf) ? 2 : 0; 1001 1002 writel(data & 0xffffffff, 1003 mem_crb + MIU_TEST_AGT_WRDATA(i)); 1004 writel((data >> 32) & 0xffffffff, 1005 mem_crb + MIU_TEST_AGT_WRDATA(i+1)); 1006 1007 writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL)); 1008 writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE), 1009 (mem_crb + TEST_AGT_CTRL)); 1010 1011 for (j = 0; j < MAX_CTL_CHECK; j++) { 1012 temp = readl(mem_crb + TEST_AGT_CTRL); 1013 if ((temp & TA_CTL_BUSY) == 0) 1014 break; 1015 } 1016 1017 if (j >= MAX_CTL_CHECK) { 1018 if (printk_ratelimit()) 1019 dev_err(&adapter->pdev->dev, 1020 "failed to write through agent\n"); 1021 ret = -EIO; 1022 } else 1023 ret = 0; 1024 1025done: 1026 mutex_unlock(&adapter->ahw.mem_lock); 1027 1028 return ret; 1029} 1030 1031int 1032qlcnic_pci_mem_read_2M(struct qlcnic_adapter *adapter, 1033 u64 off, u64 *data) 1034{ 1035 int j, ret; 1036 u32 temp, off8; 1037 u64 val; 1038 void __iomem *mem_crb; 1039 1040 /* Only 64-bit aligned access */ 1041 if (off & 7) 1042 return -EIO; 1043 1044 /* P3 onward, test agent base for MIU and SIU is same */ 1045 if (ADDR_IN_RANGE(off, QLCNIC_ADDR_QDR_NET, 1046 QLCNIC_ADDR_QDR_NET_MAX)) { 1047 mem_crb = qlcnic_get_ioaddr(adapter, 1048 QLCNIC_CRB_QDR_NET+MIU_TEST_AGT_BASE); 1049 goto correct; 1050 } 1051 1052 if (ADDR_IN_RANGE(off, QLCNIC_ADDR_DDR_NET, QLCNIC_ADDR_DDR_NET_MAX)) { 1053 mem_crb = qlcnic_get_ioaddr(adapter, 1054 QLCNIC_CRB_DDR_NET+MIU_TEST_AGT_BASE); 1055 goto correct; 1056 } 1057 1058 if (ADDR_IN_RANGE(off, QLCNIC_ADDR_OCM0, QLCNIC_ADDR_OCM0_MAX)) { 1059 return qlcnic_pci_mem_access_direct(adapter, 1060 off, data, 0); 1061 } 1062 1063 return -EIO; 1064 1065correct: 1066 off8 = off & ~0xf; 1067 1068 mutex_lock(&adapter->ahw.mem_lock); 1069 1070 writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO)); 1071 writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI)); 1072 writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL)); 1073 writel((TA_CTL_START | TA_CTL_ENABLE), (mem_crb + TEST_AGT_CTRL)); 1074 1075 for (j = 0; j < MAX_CTL_CHECK; j++) { 1076 temp = readl(mem_crb + TEST_AGT_CTRL); 1077 if ((temp & TA_CTL_BUSY) == 0) 1078 break; 1079 } 1080 1081 if (j >= MAX_CTL_CHECK) { 1082 if (printk_ratelimit()) 1083 dev_err(&adapter->pdev->dev, 1084 "failed to read through agent\n"); 1085 ret = -EIO; 1086 } else { 1087 off8 = MIU_TEST_AGT_RDDATA_LO; 1088 if (off & 0xf) 1089 off8 = MIU_TEST_AGT_RDDATA_UPPER_LO; 1090 1091 temp = readl(mem_crb + off8 + 4); 1092 val = (u64)temp << 32; 1093 val |= readl(mem_crb + off8); 1094 *data = val; 1095 ret = 0; 1096 } 1097 1098 mutex_unlock(&adapter->ahw.mem_lock); 1099 1100 return ret; 1101} 1102 1103int qlcnic_get_board_info(struct qlcnic_adapter *adapter) 1104{ 1105 int offset, board_type, magic; 1106 struct pci_dev *pdev = adapter->pdev; 1107 1108 offset = QLCNIC_FW_MAGIC_OFFSET; 1109 if (qlcnic_rom_fast_read(adapter, offset, &magic)) 1110 return -EIO; 1111 1112 if (magic != QLCNIC_BDINFO_MAGIC) { 1113 dev_err(&pdev->dev, "invalid board config, magic=%08x\n", 1114 magic); 1115 return -EIO; 1116 } 1117 1118 offset = QLCNIC_BRDTYPE_OFFSET; 1119 if (qlcnic_rom_fast_read(adapter, offset, &board_type)) 1120 return -EIO; 1121 1122 adapter->ahw.board_type = board_type; 1123 1124 if (board_type == QLCNIC_BRDTYPE_P3_4_GB_MM) { 1125 u32 gpio = QLCRD32(adapter, QLCNIC_ROMUSB_GLB_PAD_GPIO_I); 1126 if ((gpio & 0x8000) == 0) 1127 board_type = QLCNIC_BRDTYPE_P3_10G_TP; 1128 } 1129 1130 switch (board_type) { 1131 case QLCNIC_BRDTYPE_P3_HMEZ: 1132 case QLCNIC_BRDTYPE_P3_XG_LOM: 1133 case QLCNIC_BRDTYPE_P3_10G_CX4: 1134 case QLCNIC_BRDTYPE_P3_10G_CX4_LP: 1135 case QLCNIC_BRDTYPE_P3_IMEZ: 1136 case QLCNIC_BRDTYPE_P3_10G_SFP_PLUS: 1137 case QLCNIC_BRDTYPE_P3_10G_SFP_CT: 1138 case QLCNIC_BRDTYPE_P3_10G_SFP_QT: 1139 case QLCNIC_BRDTYPE_P3_10G_XFP: 1140 case QLCNIC_BRDTYPE_P3_10000_BASE_T: 1141 adapter->ahw.port_type = QLCNIC_XGBE; 1142 break; 1143 case QLCNIC_BRDTYPE_P3_REF_QG: 1144 case QLCNIC_BRDTYPE_P3_4_GB: 1145 case QLCNIC_BRDTYPE_P3_4_GB_MM: 1146 adapter->ahw.port_type = QLCNIC_GBE; 1147 break; 1148 case QLCNIC_BRDTYPE_P3_10G_TP: 1149 adapter->ahw.port_type = (adapter->portnum < 2) ? 1150 QLCNIC_XGBE : QLCNIC_GBE; 1151 break; 1152 default: 1153 dev_err(&pdev->dev, "unknown board type %x\n", board_type); 1154 adapter->ahw.port_type = QLCNIC_XGBE; 1155 break; 1156 } 1157 1158 return 0; 1159} 1160 1161int 1162qlcnic_wol_supported(struct qlcnic_adapter *adapter) 1163{ 1164 u32 wol_cfg; 1165 1166 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV); 1167 if (wol_cfg & (1UL << adapter->portnum)) { 1168 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG); 1169 if (wol_cfg & (1 << adapter->portnum)) 1170 return 1; 1171 } 1172 1173 return 0; 1174} 1175 1176int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate) 1177{ 1178 struct qlcnic_nic_req req; 1179 int rv; 1180 u64 word; 1181 1182 memset(&req, 0, sizeof(struct qlcnic_nic_req)); 1183 req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); 1184 1185 word = QLCNIC_H2C_OPCODE_CONFIG_LED | ((u64)adapter->portnum << 16); 1186 req.req_hdr = cpu_to_le64(word); 1187 1188 req.words[0] = cpu_to_le64((u64)rate << 32); 1189 req.words[1] = cpu_to_le64(state); 1190 1191 rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); 1192 if (rv) 1193 dev_err(&adapter->pdev->dev, "LED configuration failed.\n"); 1194 1195 return rv; 1196} 1197 1198static int qlcnic_set_fw_loopback(struct qlcnic_adapter *adapter, u32 flag) 1199{ 1200 struct qlcnic_nic_req req; 1201 int rv; 1202 u64 word; 1203 1204 memset(&req, 0, sizeof(struct qlcnic_nic_req)); 1205 req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); 1206 1207 word = QLCNIC_H2C_OPCODE_CONFIG_LOOPBACK | 1208 ((u64)adapter->portnum << 16); 1209 req.req_hdr = cpu_to_le64(word); 1210 req.words[0] = cpu_to_le64(flag); 1211 1212 rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); 1213 if (rv) 1214 dev_err(&adapter->pdev->dev, 1215 "%sting loopback mode failed.\n", 1216 flag ? "Set" : "Reset"); 1217 return rv; 1218} 1219 1220int qlcnic_set_ilb_mode(struct qlcnic_adapter *adapter) 1221{ 1222 if (qlcnic_set_fw_loopback(adapter, 1)) 1223 return -EIO; 1224 1225 if (qlcnic_nic_set_promisc(adapter, 1226 VPORT_MISS_MODE_ACCEPT_ALL)) { 1227 qlcnic_set_fw_loopback(adapter, 0); 1228 return -EIO; 1229 } 1230 1231 msleep(1000); 1232 return 0; 1233} 1234 1235void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter) 1236{ 1237 int mode = VPORT_MISS_MODE_DROP; 1238 struct net_device *netdev = adapter->netdev; 1239 1240 qlcnic_set_fw_loopback(adapter, 0); 1241 1242 if (netdev->flags & IFF_PROMISC) 1243 mode = VPORT_MISS_MODE_ACCEPT_ALL; 1244 else if (netdev->flags & IFF_ALLMULTI) 1245 mode = VPORT_MISS_MODE_ACCEPT_MULTI; 1246 1247 qlcnic_nic_set_promisc(adapter, mode); 1248} 1249