Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'txgbe'

Mengyuan Lou says:

====================
net: WangXun txgbe/ngbe ethernet driver

This patch series adds support for WangXun NICS, to initialize
interface from software to firmware.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+1522 -11
+1
drivers/net/ethernet/wangxun/Kconfig
··· 24 24 config NGBE 25 25 tristate "Wangxun(R) GbE PCI Express adapters support" 26 26 depends on PCI 27 + select LIBWX 27 28 help 28 29 This driver supports Wangxun(R) GbE PCI Express family of 29 30 adapters.
+463
drivers/net/ethernet/wangxun/libwx/wx_hw.c
··· 73 73 } 74 74 EXPORT_SYMBOL(wx_check_flash_load); 75 75 76 + void wx_control_hw(struct wx_hw *wxhw, bool drv) 77 + { 78 + if (drv) { 79 + /* Let firmware know the driver has taken over */ 80 + wr32m(wxhw, WX_CFG_PORT_CTL, 81 + WX_CFG_PORT_CTL_DRV_LOAD, WX_CFG_PORT_CTL_DRV_LOAD); 82 + } else { 83 + /* Let firmware take over control of hw */ 84 + wr32m(wxhw, WX_CFG_PORT_CTL, 85 + WX_CFG_PORT_CTL_DRV_LOAD, 0); 86 + } 87 + } 88 + EXPORT_SYMBOL(wx_control_hw); 89 + 90 + /** 91 + * wx_mng_present - returns 0 when management capability is present 92 + * @wxhw: pointer to hardware structure 93 + */ 94 + int wx_mng_present(struct wx_hw *wxhw) 95 + { 96 + u32 fwsm; 97 + 98 + fwsm = rd32(wxhw, WX_MIS_ST); 99 + if (fwsm & WX_MIS_ST_MNG_INIT_DN) 100 + return 0; 101 + else 102 + return -EACCES; 103 + } 104 + EXPORT_SYMBOL(wx_mng_present); 105 + 106 + /* Software lock to be held while software semaphore is being accessed. */ 107 + static DEFINE_MUTEX(wx_sw_sync_lock); 108 + 109 + /** 110 + * wx_release_sw_sync - Release SW semaphore 111 + * @wxhw: pointer to hardware structure 112 + * @mask: Mask to specify which semaphore to release 113 + * 114 + * Releases the SW semaphore for the specified 115 + * function (CSR, PHY0, PHY1, EEPROM, Flash) 116 + **/ 117 + static void wx_release_sw_sync(struct wx_hw *wxhw, u32 mask) 118 + { 119 + mutex_lock(&wx_sw_sync_lock); 120 + wr32m(wxhw, WX_MNG_SWFW_SYNC, mask, 0); 121 + mutex_unlock(&wx_sw_sync_lock); 122 + } 123 + 124 + /** 125 + * wx_acquire_sw_sync - Acquire SW semaphore 126 + * @wxhw: pointer to hardware structure 127 + * @mask: Mask to specify which semaphore to acquire 128 + * 129 + * Acquires the SW semaphore for the specified 130 + * function (CSR, PHY0, PHY1, EEPROM, Flash) 131 + **/ 132 + static int wx_acquire_sw_sync(struct wx_hw *wxhw, u32 mask) 133 + { 134 + u32 sem = 0; 135 + int ret = 0; 136 + 137 + mutex_lock(&wx_sw_sync_lock); 138 + ret = read_poll_timeout(rd32, sem, !(sem & mask), 139 + 5000, 2000000, false, wxhw, WX_MNG_SWFW_SYNC); 140 + if (!ret) { 141 + sem |= mask; 142 + wr32(wxhw, WX_MNG_SWFW_SYNC, sem); 143 + } else { 144 + wx_err(wxhw, "SW Semaphore not granted: 0x%x.\n", sem); 145 + } 146 + mutex_unlock(&wx_sw_sync_lock); 147 + 148 + return ret; 149 + } 150 + 151 + /** 152 + * wx_host_interface_command - Issue command to manageability block 153 + * @wxhw: pointer to the HW structure 154 + * @buffer: contains the command to write and where the return status will 155 + * be placed 156 + * @length: length of buffer, must be multiple of 4 bytes 157 + * @timeout: time in ms to wait for command completion 158 + * @return_data: read and return data from the buffer (true) or not (false) 159 + * Needed because FW structures are big endian and decoding of 160 + * these fields can be 8 bit or 16 bit based on command. Decoding 161 + * is not easily understood without making a table of commands. 162 + * So we will leave this up to the caller to read back the data 163 + * in these cases. 164 + **/ 165 + int wx_host_interface_command(struct wx_hw *wxhw, u32 *buffer, 166 + u32 length, u32 timeout, bool return_data) 167 + { 168 + u32 hdr_size = sizeof(struct wx_hic_hdr); 169 + u32 hicr, i, bi, buf[64] = {}; 170 + int status = 0; 171 + u32 dword_len; 172 + u16 buf_len; 173 + 174 + if (length == 0 || length > WX_HI_MAX_BLOCK_BYTE_LENGTH) { 175 + wx_err(wxhw, "Buffer length failure buffersize=%d.\n", length); 176 + return -EINVAL; 177 + } 178 + 179 + status = wx_acquire_sw_sync(wxhw, WX_MNG_SWFW_SYNC_SW_MB); 180 + if (status != 0) 181 + return status; 182 + 183 + /* Calculate length in DWORDs. We must be DWORD aligned */ 184 + if ((length % (sizeof(u32))) != 0) { 185 + wx_err(wxhw, "Buffer length failure, not aligned to dword"); 186 + status = -EINVAL; 187 + goto rel_out; 188 + } 189 + 190 + dword_len = length >> 2; 191 + 192 + /* The device driver writes the relevant command block 193 + * into the ram area. 194 + */ 195 + for (i = 0; i < dword_len; i++) { 196 + wr32a(wxhw, WX_MNG_MBOX, i, (__force u32)cpu_to_le32(buffer[i])); 197 + /* write flush */ 198 + buf[i] = rd32a(wxhw, WX_MNG_MBOX, i); 199 + } 200 + /* Setting this bit tells the ARC that a new command is pending. */ 201 + wr32m(wxhw, WX_MNG_MBOX_CTL, 202 + WX_MNG_MBOX_CTL_SWRDY, WX_MNG_MBOX_CTL_SWRDY); 203 + 204 + status = read_poll_timeout(rd32, hicr, hicr & WX_MNG_MBOX_CTL_FWRDY, 1000, 205 + timeout * 1000, false, wxhw, WX_MNG_MBOX_CTL); 206 + if (status) 207 + goto rel_out; 208 + 209 + /* Check command completion */ 210 + if (status) { 211 + wx_dbg(wxhw, "Command has failed with no status valid.\n"); 212 + 213 + buf[0] = rd32(wxhw, WX_MNG_MBOX); 214 + if ((buffer[0] & 0xff) != (~buf[0] >> 24)) { 215 + status = -EINVAL; 216 + goto rel_out; 217 + } 218 + if ((buf[0] & 0xff0000) >> 16 == 0x80) { 219 + wx_dbg(wxhw, "It's unknown cmd.\n"); 220 + status = -EINVAL; 221 + goto rel_out; 222 + } 223 + 224 + wx_dbg(wxhw, "write value:\n"); 225 + for (i = 0; i < dword_len; i++) 226 + wx_dbg(wxhw, "%x ", buffer[i]); 227 + wx_dbg(wxhw, "read value:\n"); 228 + for (i = 0; i < dword_len; i++) 229 + wx_dbg(wxhw, "%x ", buf[i]); 230 + } 231 + 232 + if (!return_data) 233 + goto rel_out; 234 + 235 + /* Calculate length in DWORDs */ 236 + dword_len = hdr_size >> 2; 237 + 238 + /* first pull in the header so we know the buffer length */ 239 + for (bi = 0; bi < dword_len; bi++) { 240 + buffer[bi] = rd32a(wxhw, WX_MNG_MBOX, bi); 241 + le32_to_cpus(&buffer[bi]); 242 + } 243 + 244 + /* If there is any thing in data position pull it in */ 245 + buf_len = ((struct wx_hic_hdr *)buffer)->buf_len; 246 + if (buf_len == 0) 247 + goto rel_out; 248 + 249 + if (length < buf_len + hdr_size) { 250 + wx_err(wxhw, "Buffer not large enough for reply message.\n"); 251 + status = -EFAULT; 252 + goto rel_out; 253 + } 254 + 255 + /* Calculate length in DWORDs, add 3 for odd lengths */ 256 + dword_len = (buf_len + 3) >> 2; 257 + 258 + /* Pull in the rest of the buffer (bi is where we left off) */ 259 + for (; bi <= dword_len; bi++) { 260 + buffer[bi] = rd32a(wxhw, WX_MNG_MBOX, bi); 261 + le32_to_cpus(&buffer[bi]); 262 + } 263 + 264 + rel_out: 265 + wx_release_sw_sync(wxhw, WX_MNG_SWFW_SYNC_SW_MB); 266 + return status; 267 + } 268 + EXPORT_SYMBOL(wx_host_interface_command); 269 + 270 + /** 271 + * wx_read_ee_hostif_data - Read EEPROM word using a host interface cmd 272 + * assuming that the semaphore is already obtained. 273 + * @wxhw: pointer to hardware structure 274 + * @offset: offset of word in the EEPROM to read 275 + * @data: word read from the EEPROM 276 + * 277 + * Reads a 16 bit word from the EEPROM using the hostif. 278 + **/ 279 + static int wx_read_ee_hostif_data(struct wx_hw *wxhw, u16 offset, u16 *data) 280 + { 281 + struct wx_hic_read_shadow_ram buffer; 282 + int status; 283 + 284 + buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD; 285 + buffer.hdr.req.buf_lenh = 0; 286 + buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN; 287 + buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM; 288 + 289 + /* convert offset from words to bytes */ 290 + buffer.address = (__force u32)cpu_to_be32(offset * 2); 291 + /* one word */ 292 + buffer.length = (__force u16)cpu_to_be16(sizeof(u16)); 293 + 294 + status = wx_host_interface_command(wxhw, (u32 *)&buffer, sizeof(buffer), 295 + WX_HI_COMMAND_TIMEOUT, false); 296 + 297 + if (status != 0) 298 + return status; 299 + 300 + *data = (u16)rd32a(wxhw, WX_MNG_MBOX, FW_NVM_DATA_OFFSET); 301 + 302 + return status; 303 + } 304 + 305 + /** 306 + * wx_read_ee_hostif - Read EEPROM word using a host interface cmd 307 + * @wxhw: pointer to hardware structure 308 + * @offset: offset of word in the EEPROM to read 309 + * @data: word read from the EEPROM 310 + * 311 + * Reads a 16 bit word from the EEPROM using the hostif. 312 + **/ 313 + int wx_read_ee_hostif(struct wx_hw *wxhw, u16 offset, u16 *data) 314 + { 315 + int status = 0; 316 + 317 + status = wx_acquire_sw_sync(wxhw, WX_MNG_SWFW_SYNC_SW_FLASH); 318 + if (status == 0) { 319 + status = wx_read_ee_hostif_data(wxhw, offset, data); 320 + wx_release_sw_sync(wxhw, WX_MNG_SWFW_SYNC_SW_FLASH); 321 + } 322 + 323 + return status; 324 + } 325 + EXPORT_SYMBOL(wx_read_ee_hostif); 326 + 327 + /** 328 + * wx_read_ee_hostif_buffer- Read EEPROM word(s) using hostif 329 + * @wxhw: pointer to hardware structure 330 + * @offset: offset of word in the EEPROM to read 331 + * @words: number of words 332 + * @data: word(s) read from the EEPROM 333 + * 334 + * Reads a 16 bit word(s) from the EEPROM using the hostif. 335 + **/ 336 + int wx_read_ee_hostif_buffer(struct wx_hw *wxhw, 337 + u16 offset, u16 words, u16 *data) 338 + { 339 + struct wx_hic_read_shadow_ram buffer; 340 + u32 current_word = 0; 341 + u16 words_to_read; 342 + u32 value = 0; 343 + int status; 344 + u32 i; 345 + 346 + /* Take semaphore for the entire operation. */ 347 + status = wx_acquire_sw_sync(wxhw, WX_MNG_SWFW_SYNC_SW_FLASH); 348 + if (status != 0) 349 + return status; 350 + 351 + while (words) { 352 + if (words > FW_MAX_READ_BUFFER_SIZE / 2) 353 + words_to_read = FW_MAX_READ_BUFFER_SIZE / 2; 354 + else 355 + words_to_read = words; 356 + 357 + buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD; 358 + buffer.hdr.req.buf_lenh = 0; 359 + buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN; 360 + buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM; 361 + 362 + /* convert offset from words to bytes */ 363 + buffer.address = (__force u32)cpu_to_be32((offset + current_word) * 2); 364 + buffer.length = (__force u16)cpu_to_be16(words_to_read * 2); 365 + 366 + status = wx_host_interface_command(wxhw, (u32 *)&buffer, 367 + sizeof(buffer), 368 + WX_HI_COMMAND_TIMEOUT, 369 + false); 370 + 371 + if (status != 0) { 372 + wx_err(wxhw, "Host interface command failed\n"); 373 + goto out; 374 + } 375 + 376 + for (i = 0; i < words_to_read; i++) { 377 + u32 reg = WX_MNG_MBOX + (FW_NVM_DATA_OFFSET << 2) + 2 * i; 378 + 379 + value = rd32(wxhw, reg); 380 + data[current_word] = (u16)(value & 0xffff); 381 + current_word++; 382 + i++; 383 + if (i < words_to_read) { 384 + value >>= 16; 385 + data[current_word] = (u16)(value & 0xffff); 386 + current_word++; 387 + } 388 + } 389 + words -= words_to_read; 390 + } 391 + 392 + out: 393 + wx_release_sw_sync(wxhw, WX_MNG_SWFW_SYNC_SW_FLASH); 394 + return status; 395 + } 396 + EXPORT_SYMBOL(wx_read_ee_hostif_buffer); 397 + 398 + /** 399 + * wx_calculate_checksum - Calculate checksum for buffer 400 + * @buffer: pointer to EEPROM 401 + * @length: size of EEPROM to calculate a checksum for 402 + * Calculates the checksum for some buffer on a specified length. The 403 + * checksum calculated is returned. 404 + **/ 405 + static u8 wx_calculate_checksum(u8 *buffer, u32 length) 406 + { 407 + u8 sum = 0; 408 + u32 i; 409 + 410 + if (!buffer) 411 + return 0; 412 + 413 + for (i = 0; i < length; i++) 414 + sum += buffer[i]; 415 + 416 + return (u8)(0 - sum); 417 + } 418 + 419 + /** 420 + * wx_reset_hostif - send reset cmd to fw 421 + * @wxhw: pointer to hardware structure 422 + * 423 + * Sends reset cmd to firmware through the manageability 424 + * block. 425 + **/ 426 + int wx_reset_hostif(struct wx_hw *wxhw) 427 + { 428 + struct wx_hic_reset reset_cmd; 429 + int ret_val = 0; 430 + int i; 431 + 432 + reset_cmd.hdr.cmd = FW_RESET_CMD; 433 + reset_cmd.hdr.buf_len = FW_RESET_LEN; 434 + reset_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED; 435 + reset_cmd.lan_id = wxhw->bus.func; 436 + reset_cmd.reset_type = (u16)wxhw->reset_type; 437 + reset_cmd.hdr.checksum = 0; 438 + reset_cmd.hdr.checksum = wx_calculate_checksum((u8 *)&reset_cmd, 439 + (FW_CEM_HDR_LEN + 440 + reset_cmd.hdr.buf_len)); 441 + 442 + for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) { 443 + ret_val = wx_host_interface_command(wxhw, (u32 *)&reset_cmd, 444 + sizeof(reset_cmd), 445 + WX_HI_COMMAND_TIMEOUT, 446 + true); 447 + if (ret_val != 0) 448 + continue; 449 + 450 + if (reset_cmd.hdr.cmd_or_resp.ret_status == 451 + FW_CEM_RESP_STATUS_SUCCESS) 452 + ret_val = 0; 453 + else 454 + ret_val = -EFAULT; 455 + 456 + break; 457 + } 458 + 459 + return ret_val; 460 + } 461 + EXPORT_SYMBOL(wx_reset_hostif); 462 + 463 + /** 464 + * wx_init_eeprom_params - Initialize EEPROM params 465 + * @wxhw: pointer to hardware structure 466 + * 467 + * Initializes the EEPROM parameters wx_eeprom_info within the 468 + * wx_hw struct in order to set up EEPROM access. 469 + **/ 470 + void wx_init_eeprom_params(struct wx_hw *wxhw) 471 + { 472 + struct wx_eeprom_info *eeprom = &wxhw->eeprom; 473 + u16 eeprom_size; 474 + u16 data = 0x80; 475 + 476 + if (eeprom->type == wx_eeprom_uninitialized) { 477 + eeprom->semaphore_delay = 10; 478 + eeprom->type = wx_eeprom_none; 479 + 480 + if (!(rd32(wxhw, WX_SPI_STATUS) & 481 + WX_SPI_STATUS_FLASH_BYPASS)) { 482 + eeprom->type = wx_flash; 483 + 484 + eeprom_size = 4096; 485 + eeprom->word_size = eeprom_size >> 1; 486 + 487 + wx_dbg(wxhw, "Eeprom params: type = %d, size = %d\n", 488 + eeprom->type, eeprom->word_size); 489 + } 490 + } 491 + 492 + if (wxhw->mac.type == wx_mac_sp) { 493 + if (wx_read_ee_hostif(wxhw, WX_SW_REGION_PTR, &data)) { 494 + wx_err(wxhw, "NVM Read Error\n"); 495 + return; 496 + } 497 + data = data >> 1; 498 + } 499 + 500 + eeprom->sw_region_offset = data; 501 + } 502 + EXPORT_SYMBOL(wx_init_eeprom_params); 503 + 76 504 /** 77 505 * wx_get_mac_addr - Generic get MAC address 78 506 * @wxhw: pointer to hardware structure ··· 870 442 wr32(wxhw, WX_RDB_PFCMACDAH, 0x0180); 871 443 } 872 444 EXPORT_SYMBOL(wx_reset_misc); 445 + 446 + /** 447 + * wx_get_pcie_msix_counts - Gets MSI-X vector count 448 + * @wxhw: pointer to hardware structure 449 + * @msix_count: number of MSI interrupts that can be obtained 450 + * @max_msix_count: number of MSI interrupts that mac need 451 + * 452 + * Read PCIe configuration space, and get the MSI-X vector count from 453 + * the capabilities table. 454 + **/ 455 + int wx_get_pcie_msix_counts(struct wx_hw *wxhw, u16 *msix_count, u16 max_msix_count) 456 + { 457 + struct pci_dev *pdev = wxhw->pdev; 458 + struct device *dev = &pdev->dev; 459 + int pos; 460 + 461 + *msix_count = 1; 462 + pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); 463 + if (!pos) { 464 + dev_err(dev, "Unable to find MSI-X Capabilities\n"); 465 + return -EINVAL; 466 + } 467 + pci_read_config_word(pdev, 468 + pos + PCI_MSIX_FLAGS, 469 + msix_count); 470 + *msix_count &= WX_PCIE_MSIX_TBL_SZ_MASK; 471 + /* MSI-X count is zero-based in HW */ 472 + *msix_count += 1; 473 + 474 + if (*msix_count > max_msix_count) 475 + *msix_count = max_msix_count; 476 + 477 + return 0; 478 + } 479 + EXPORT_SYMBOL(wx_get_pcie_msix_counts); 873 480 874 481 int wx_sw_init(struct wx_hw *wxhw) 875 482 {
+10
drivers/net/ethernet/wangxun/libwx/wx_hw.h
··· 5 5 #define _WX_HW_H_ 6 6 7 7 int wx_check_flash_load(struct wx_hw *hw, u32 check_bit); 8 + void wx_control_hw(struct wx_hw *wxhw, bool drv); 9 + int wx_mng_present(struct wx_hw *wxhw); 10 + int wx_host_interface_command(struct wx_hw *wxhw, u32 *buffer, 11 + u32 length, u32 timeout, bool return_data); 12 + int wx_read_ee_hostif(struct wx_hw *wxhw, u16 offset, u16 *data); 13 + int wx_read_ee_hostif_buffer(struct wx_hw *wxhw, 14 + u16 offset, u16 words, u16 *data); 15 + int wx_reset_hostif(struct wx_hw *wxhw); 16 + void wx_init_eeprom_params(struct wx_hw *wxhw); 8 17 void wx_get_mac_addr(struct wx_hw *wxhw, u8 *mac_addr); 9 18 int wx_set_rar(struct wx_hw *wxhw, u32 index, u8 *addr, u64 pools, u32 enable_addr); 10 19 int wx_clear_rar(struct wx_hw *wxhw, u32 index); ··· 22 13 int wx_disable_pcie_master(struct wx_hw *wxhw); 23 14 int wx_stop_adapter(struct wx_hw *wxhw); 24 15 void wx_reset_misc(struct wx_hw *wxhw); 16 + int wx_get_pcie_msix_counts(struct wx_hw *wxhw, u16 *msix_count, u16 max_msix_count); 25 17 int wx_sw_init(struct wx_hw *wxhw); 26 18 27 19 #endif /* _WX_HW_H_ */
+115
drivers/net/ethernet/wangxun/libwx/wx_type.h
··· 14 14 #define WX_WOL_SUP 0x4000 15 15 #define WX_WOL_MASK 0x4000 16 16 17 + /* MSI-X capability fields masks */ 18 + #define WX_PCIE_MSIX_TBL_SZ_MASK 0x7FF 19 + #define WX_PCI_LINK_STATUS 0xB2 20 + 17 21 /**************** Global Registers ****************************/ 18 22 /* chip control Registers */ 19 23 #define WX_MIS_PWR 0x10000 20 24 #define WX_MIS_RST 0x1000C 21 25 #define WX_MIS_RST_LAN_RST(_i) BIT((_i) + 1) 26 + #define WX_MIS_RST_SW_RST BIT(0) 27 + #define WX_MIS_ST 0x10028 28 + #define WX_MIS_ST_MNG_INIT_DN BIT(0) 29 + #define WX_MIS_SWSM 0x1002C 30 + #define WX_MIS_SWSM_SMBI BIT(0) 22 31 #define WX_MIS_RST_ST 0x10030 23 32 #define WX_MIS_RST_ST_RST_INI_SHIFT 8 24 33 #define WX_MIS_RST_ST_RST_INIT (0xFF << WX_MIS_RST_ST_RST_INI_SHIFT) ··· 59 50 #define WX_TS_ALARM_ST 0x10318 60 51 #define WX_TS_ALARM_ST_DALARM BIT(1) 61 52 #define WX_TS_ALARM_ST_ALARM BIT(0) 53 + 54 + /************************* Port Registers ************************************/ 55 + /* port cfg Registers */ 56 + #define WX_CFG_PORT_CTL 0x14400 57 + #define WX_CFG_PORT_CTL_DRV_LOAD BIT(3) 62 58 63 59 /*********************** Transmit DMA registers **************************/ 64 60 /* transmit global control */ ··· 121 107 #define WX_PSR_MAC_SWC_IDX 0x16210 122 108 #define WX_CLEAR_VMDQ_ALL 0xFFFFFFFFU 123 109 110 + /************************************** MNG ********************************/ 111 + #define WX_MNG_SWFW_SYNC 0x1E008 112 + #define WX_MNG_SWFW_SYNC_SW_MB BIT(2) 113 + #define WX_MNG_SWFW_SYNC_SW_FLASH BIT(3) 114 + #define WX_MNG_MBOX 0x1E100 115 + #define WX_MNG_MBOX_CTL 0x1E044 116 + #define WX_MNG_MBOX_CTL_SWRDY BIT(0) 117 + #define WX_MNG_MBOX_CTL_FWRDY BIT(2) 118 + 124 119 /************************************* ETH MAC *****************************/ 125 120 #define WX_MAC_TX_CFG 0x11000 126 121 #define WX_MAC_TX_CFG_TE BIT(0) ··· 167 144 /* Number of 80 microseconds we wait for PCI Express master disable */ 168 145 #define WX_PCI_MASTER_DISABLE_TIMEOUT 80000 169 146 147 + /****************** Manageablility Host Interface defines ********************/ 148 + #define WX_HI_MAX_BLOCK_BYTE_LENGTH 256 /* Num of bytes in range */ 149 + #define WX_HI_COMMAND_TIMEOUT 1000 /* Process HI command limit */ 150 + 151 + #define FW_READ_SHADOW_RAM_CMD 0x31 152 + #define FW_READ_SHADOW_RAM_LEN 0x6 153 + #define FW_DEFAULT_CHECKSUM 0xFF /* checksum always 0xFF */ 154 + #define FW_NVM_DATA_OFFSET 3 155 + #define FW_MAX_READ_BUFFER_SIZE 244 156 + #define FW_RESET_CMD 0xDF 157 + #define FW_RESET_LEN 0x2 158 + #define FW_CEM_HDR_LEN 0x4 159 + #define FW_CEM_CMD_RESERVED 0X0 160 + #define FW_CEM_MAX_RETRIES 3 161 + #define FW_CEM_RESP_STATUS_SUCCESS 0x1 162 + 163 + #define WX_SW_REGION_PTR 0x1C 164 + 165 + /* Host Interface Command Structures */ 166 + struct wx_hic_hdr { 167 + u8 cmd; 168 + u8 buf_len; 169 + union { 170 + u8 cmd_resv; 171 + u8 ret_status; 172 + } cmd_or_resp; 173 + u8 checksum; 174 + }; 175 + 176 + struct wx_hic_hdr2_req { 177 + u8 cmd; 178 + u8 buf_lenh; 179 + u8 buf_lenl; 180 + u8 checksum; 181 + }; 182 + 183 + struct wx_hic_hdr2_rsp { 184 + u8 cmd; 185 + u8 buf_lenl; 186 + u8 buf_lenh_status; /* 7-5: high bits of buf_len, 4-0: status */ 187 + u8 checksum; 188 + }; 189 + 190 + union wx_hic_hdr2 { 191 + struct wx_hic_hdr2_req req; 192 + struct wx_hic_hdr2_rsp rsp; 193 + }; 194 + 195 + /* These need to be dword aligned */ 196 + struct wx_hic_read_shadow_ram { 197 + union wx_hic_hdr2 hdr; 198 + u32 address; 199 + u16 length; 200 + u16 pad2; 201 + u16 data; 202 + u16 pad3; 203 + }; 204 + 205 + struct wx_hic_reset { 206 + struct wx_hic_hdr hdr; 207 + u16 lan_id; 208 + u16 reset_type; 209 + }; 210 + 170 211 /* Bus parameters */ 171 212 struct wx_bus_info { 172 213 u8 func; ··· 259 172 u32 num_rar_entries; 260 173 u32 max_tx_queues; 261 174 u32 max_rx_queues; 175 + 176 + u16 max_msix_vectors; 262 177 struct wx_thermal_sensor_data sensor; 178 + }; 179 + 180 + enum wx_eeprom_type { 181 + wx_eeprom_uninitialized = 0, 182 + wx_eeprom_spi, 183 + wx_flash, 184 + wx_eeprom_none /* No NVM support */ 185 + }; 186 + 187 + struct wx_eeprom_info { 188 + enum wx_eeprom_type type; 189 + u32 semaphore_delay; 190 + u16 word_size; 191 + u16 sw_region_offset; 263 192 }; 264 193 265 194 struct wx_addr_filter_info { ··· 284 181 bool user_set_promisc; 285 182 }; 286 183 184 + enum wx_reset_type { 185 + WX_LAN_RESET = 0, 186 + WX_SW_RESET, 187 + WX_GLOBAL_RESET 188 + }; 189 + 287 190 struct wx_hw { 288 191 u8 __iomem *hw_addr; 289 192 struct pci_dev *pdev; 290 193 struct wx_bus_info bus; 291 194 struct wx_mac_info mac; 195 + struct wx_eeprom_info eeprom; 292 196 struct wx_addr_filter_info addr_ctrl; 293 197 u16 device_id; 294 198 u16 vendor_id; ··· 305 195 u16 oem_ssid; 306 196 u16 oem_svid; 307 197 bool adapter_stopped; 198 + enum wx_reset_type reset_type; 308 199 }; 309 200 310 201 #define WX_INTR_ALL (~0ULL) ··· 313 202 /* register operations */ 314 203 #define wr32(a, reg, value) writel((value), ((a)->hw_addr + (reg))) 315 204 #define rd32(a, reg) readl((a)->hw_addr + (reg)) 205 + #define rd32a(a, reg, offset) ( \ 206 + rd32((a), (reg) + ((offset) << 2))) 207 + #define wr32a(a, reg, off, val) \ 208 + wr32((a), (reg) + ((off) << 2), (val)) 316 209 317 210 static inline u32 318 211 rd32m(struct wx_hw *wxhw, u32 reg, u32 mask)
+1 -1
drivers/net/ethernet/wangxun/ngbe/Makefile
··· 6 6 7 7 obj-$(CONFIG_NGBE) += ngbe.o 8 8 9 - ngbe-objs := ngbe_main.o 9 + ngbe-objs := ngbe_main.o ngbe_hw.o
+55
drivers/net/ethernet/wangxun/ngbe/ngbe.h
··· 11 11 #define NGBE_MAX_RX_QUEUES (NGBE_MAX_FDIR_INDICES + 1) 12 12 #define NGBE_MAX_TX_QUEUES (NGBE_MAX_FDIR_INDICES + 1) 13 13 14 + #define NGBE_ETH_LENGTH_OF_ADDRESS 6 15 + #define NGBE_MAX_MSIX_VECTORS 0x09 16 + #define NGBE_RAR_ENTRIES 32 17 + 18 + /* TX/RX descriptor defines */ 19 + #define NGBE_DEFAULT_TXD 512 /* default ring size */ 20 + #define NGBE_DEFAULT_TX_WORK 256 21 + #define NGBE_MAX_TXD 8192 22 + #define NGBE_MIN_TXD 128 23 + 24 + #define NGBE_DEFAULT_RXD 512 /* default ring size */ 25 + #define NGBE_DEFAULT_RX_WORK 256 26 + #define NGBE_MAX_RXD 8192 27 + #define NGBE_MIN_RXD 128 28 + 29 + #define NGBE_MAC_STATE_DEFAULT 0x1 30 + #define NGBE_MAC_STATE_MODIFIED 0x2 31 + #define NGBE_MAC_STATE_IN_USE 0x4 32 + 33 + struct ngbe_mac_addr { 34 + u8 addr[ETH_ALEN]; 35 + u16 state; /* bitmask */ 36 + u64 pools; 37 + }; 38 + 14 39 /* board specific private data structure */ 15 40 struct ngbe_adapter { 16 41 u8 __iomem *io_addr; /* Mainly for iounmap use */ 17 42 /* OS defined structs */ 18 43 struct net_device *netdev; 19 44 struct pci_dev *pdev; 45 + 46 + /* structs defined in ngbe_hw.h */ 47 + struct ngbe_hw hw; 48 + struct ngbe_mac_addr *mac_table; 49 + u16 msg_enable; 50 + 51 + /* Tx fast path data */ 52 + int num_tx_queues; 53 + u16 tx_itr_setting; 54 + u16 tx_work_limit; 55 + 56 + /* Rx fast path data */ 57 + int num_rx_queues; 58 + u16 rx_itr_setting; 59 + u16 rx_work_limit; 60 + 61 + int num_q_vectors; /* current number of q_vectors for device */ 62 + int max_q_vectors; /* upper limit of q_vectors for device */ 63 + 64 + u32 tx_ring_count; 65 + u32 rx_ring_count; 66 + 67 + #define NGBE_MAX_RETA_ENTRIES 128 68 + u8 rss_indir_tbl[NGBE_MAX_RETA_ENTRIES]; 69 + 70 + #define NGBE_RSS_KEY_SIZE 40 /* size of RSS Hash Key in bytes */ 71 + u32 *rss_key; 72 + u32 wol; 73 + 74 + u16 bd_number; 20 75 }; 21 76 22 77 extern char ngbe_driver_name[];
+87
drivers/net/ethernet/wangxun/ngbe/ngbe_hw.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2019 - 2022 Beijing WangXun Technology Co., Ltd. */ 3 + 4 + #include <linux/etherdevice.h> 5 + #include <linux/iopoll.h> 6 + #include <linux/pci.h> 7 + 8 + #include "../libwx/wx_type.h" 9 + #include "../libwx/wx_hw.h" 10 + #include "ngbe_type.h" 11 + #include "ngbe_hw.h" 12 + #include "ngbe.h" 13 + 14 + int ngbe_eeprom_chksum_hostif(struct ngbe_hw *hw) 15 + { 16 + struct wx_hic_read_shadow_ram buffer; 17 + struct wx_hw *wxhw = &hw->wxhw; 18 + int status; 19 + int tmp; 20 + 21 + buffer.hdr.req.cmd = NGBE_FW_EEPROM_CHECKSUM_CMD; 22 + buffer.hdr.req.buf_lenh = 0; 23 + buffer.hdr.req.buf_lenl = 0; 24 + buffer.hdr.req.checksum = NGBE_FW_CMD_DEFAULT_CHECKSUM; 25 + /* convert offset from words to bytes */ 26 + buffer.address = 0; 27 + /* one word */ 28 + buffer.length = 0; 29 + 30 + status = wx_host_interface_command(wxhw, (u32 *)&buffer, sizeof(buffer), 31 + WX_HI_COMMAND_TIMEOUT, false); 32 + 33 + if (status < 0) 34 + return status; 35 + tmp = rd32a(wxhw, WX_MNG_MBOX, 1); 36 + if (tmp == NGBE_FW_CMD_ST_PASS) 37 + return 0; 38 + return -EIO; 39 + } 40 + 41 + static int ngbe_reset_misc(struct ngbe_hw *hw) 42 + { 43 + struct wx_hw *wxhw = &hw->wxhw; 44 + 45 + wx_reset_misc(wxhw); 46 + if (hw->mac_type == ngbe_mac_type_rgmii) 47 + wr32(wxhw, NGBE_MDIO_CLAUSE_SELECT, 0xF); 48 + if (hw->gpio_ctrl) { 49 + /* gpio0 is used to power on/off control*/ 50 + wr32(wxhw, NGBE_GPIO_DDR, 0x1); 51 + wr32(wxhw, NGBE_GPIO_DR, NGBE_GPIO_DR_0); 52 + } 53 + return 0; 54 + } 55 + 56 + /** 57 + * ngbe_reset_hw - Perform hardware reset 58 + * @hw: pointer to hardware structure 59 + * 60 + * Resets the hardware by resetting the transmit and receive units, masks 61 + * and clears all interrupts, perform a PHY reset, and perform a link (MAC) 62 + * reset. 63 + **/ 64 + int ngbe_reset_hw(struct ngbe_hw *hw) 65 + { 66 + struct wx_hw *wxhw = &hw->wxhw; 67 + int status = 0; 68 + u32 reset = 0; 69 + 70 + /* Call adapter stop to disable tx/rx and clear interrupts */ 71 + status = wx_stop_adapter(wxhw); 72 + if (status != 0) 73 + return status; 74 + reset = WX_MIS_RST_LAN_RST(wxhw->bus.func); 75 + wr32(wxhw, WX_MIS_RST, reset | rd32(wxhw, WX_MIS_RST)); 76 + ngbe_reset_misc(hw); 77 + 78 + /* Store the permanent mac address */ 79 + wx_get_mac_addr(wxhw, wxhw->mac.perm_addr); 80 + 81 + /* reset num_rar_entries to 128 */ 82 + wxhw->mac.num_rar_entries = NGBE_RAR_ENTRIES; 83 + wx_init_rx_addrs(wxhw); 84 + pci_set_master(wxhw->pdev); 85 + 86 + return 0; 87 + }
+12
drivers/net/ethernet/wangxun/ngbe/ngbe_hw.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * WangXun Gigabit PCI Express Linux driver 4 + * Copyright (c) 2019 - 2022 Beijing WangXun Technology Co., Ltd. 5 + */ 6 + 7 + #ifndef _NGBE_HW_H_ 8 + #define _NGBE_HW_H_ 9 + 10 + int ngbe_eeprom_chksum_hostif(struct ngbe_hw *hw); 11 + int ngbe_reset_hw(struct ngbe_hw *hw); 12 + #endif /* _NGBE_HW_H_ */
+368
drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
··· 8 8 #include <linux/string.h> 9 9 #include <linux/aer.h> 10 10 #include <linux/etherdevice.h> 11 + #include <net/ip.h> 11 12 13 + #include "../libwx/wx_type.h" 14 + #include "../libwx/wx_hw.h" 15 + #include "ngbe_type.h" 16 + #include "ngbe_hw.h" 12 17 #include "ngbe.h" 13 18 char ngbe_driver_name[] = "ngbe"; 14 19 ··· 39 34 { .device = 0 } 40 35 }; 41 36 37 + static void ngbe_mac_set_default_filter(struct ngbe_adapter *adapter, u8 *addr) 38 + { 39 + struct ngbe_hw *hw = &adapter->hw; 40 + 41 + memcpy(&adapter->mac_table[0].addr, addr, ETH_ALEN); 42 + adapter->mac_table[0].pools = 1ULL; 43 + adapter->mac_table[0].state = (NGBE_MAC_STATE_DEFAULT | 44 + NGBE_MAC_STATE_IN_USE); 45 + wx_set_rar(&hw->wxhw, 0, adapter->mac_table[0].addr, 46 + adapter->mac_table[0].pools, 47 + WX_PSR_MAC_SWC_AD_H_AV); 48 + } 49 + 50 + /** 51 + * ngbe_init_type_code - Initialize the shared code 52 + * @hw: pointer to hardware structure 53 + **/ 54 + static void ngbe_init_type_code(struct ngbe_hw *hw) 55 + { 56 + int wol_mask = 0, ncsi_mask = 0; 57 + struct wx_hw *wxhw = &hw->wxhw; 58 + u16 type_mask = 0; 59 + 60 + wxhw->mac.type = wx_mac_em; 61 + type_mask = (u16)(wxhw->subsystem_device_id & NGBE_OEM_MASK); 62 + ncsi_mask = wxhw->subsystem_device_id & NGBE_NCSI_MASK; 63 + wol_mask = wxhw->subsystem_device_id & NGBE_WOL_MASK; 64 + 65 + switch (type_mask) { 66 + case NGBE_SUBID_M88E1512_SFP: 67 + case NGBE_SUBID_LY_M88E1512_SFP: 68 + hw->phy.type = ngbe_phy_m88e1512_sfi; 69 + break; 70 + case NGBE_SUBID_M88E1512_RJ45: 71 + hw->phy.type = ngbe_phy_m88e1512; 72 + break; 73 + case NGBE_SUBID_M88E1512_MIX: 74 + hw->phy.type = ngbe_phy_m88e1512_unknown; 75 + break; 76 + case NGBE_SUBID_YT8521S_SFP: 77 + case NGBE_SUBID_YT8521S_SFP_GPIO: 78 + case NGBE_SUBID_LY_YT8521S_SFP: 79 + hw->phy.type = ngbe_phy_yt8521s_sfi; 80 + break; 81 + case NGBE_SUBID_INTERNAL_YT8521S_SFP: 82 + case NGBE_SUBID_INTERNAL_YT8521S_SFP_GPIO: 83 + hw->phy.type = ngbe_phy_internal_yt8521s_sfi; 84 + break; 85 + case NGBE_SUBID_RGMII_FPGA: 86 + case NGBE_SUBID_OCP_CARD: 87 + fallthrough; 88 + default: 89 + hw->phy.type = ngbe_phy_internal; 90 + break; 91 + } 92 + 93 + if (hw->phy.type == ngbe_phy_internal || 94 + hw->phy.type == ngbe_phy_internal_yt8521s_sfi) 95 + hw->mac_type = ngbe_mac_type_mdi; 96 + else 97 + hw->mac_type = ngbe_mac_type_rgmii; 98 + 99 + hw->wol_enabled = (wol_mask == NGBE_WOL_SUP) ? 1 : 0; 100 + hw->ncsi_enabled = (ncsi_mask == NGBE_NCSI_MASK || 101 + type_mask == NGBE_SUBID_OCP_CARD) ? 1 : 0; 102 + 103 + switch (type_mask) { 104 + case NGBE_SUBID_LY_YT8521S_SFP: 105 + case NGBE_SUBID_LY_M88E1512_SFP: 106 + case NGBE_SUBID_YT8521S_SFP_GPIO: 107 + case NGBE_SUBID_INTERNAL_YT8521S_SFP_GPIO: 108 + hw->gpio_ctrl = 1; 109 + break; 110 + default: 111 + hw->gpio_ctrl = 0; 112 + break; 113 + } 114 + } 115 + 116 + /** 117 + * ngbe_init_rss_key - Initialize adapter RSS key 118 + * @adapter: device handle 119 + * 120 + * Allocates and initializes the RSS key if it is not allocated. 121 + **/ 122 + static inline int ngbe_init_rss_key(struct ngbe_adapter *adapter) 123 + { 124 + u32 *rss_key; 125 + 126 + if (!adapter->rss_key) { 127 + rss_key = kzalloc(NGBE_RSS_KEY_SIZE, GFP_KERNEL); 128 + if (unlikely(!rss_key)) 129 + return -ENOMEM; 130 + 131 + netdev_rss_key_fill(rss_key, NGBE_RSS_KEY_SIZE); 132 + adapter->rss_key = rss_key; 133 + } 134 + 135 + return 0; 136 + } 137 + 138 + /** 139 + * ngbe_sw_init - Initialize general software structures 140 + * @adapter: board private structure to initialize 141 + **/ 142 + static int ngbe_sw_init(struct ngbe_adapter *adapter) 143 + { 144 + struct pci_dev *pdev = adapter->pdev; 145 + struct ngbe_hw *hw = &adapter->hw; 146 + struct wx_hw *wxhw = &hw->wxhw; 147 + u16 msix_count = 0; 148 + int err = 0; 149 + 150 + wxhw->hw_addr = adapter->io_addr; 151 + wxhw->pdev = pdev; 152 + 153 + /* PCI config space info */ 154 + err = wx_sw_init(wxhw); 155 + if (err < 0) { 156 + netif_err(adapter, probe, adapter->netdev, 157 + "Read of internal subsystem device id failed\n"); 158 + return err; 159 + } 160 + 161 + /* mac type, phy type , oem type */ 162 + ngbe_init_type_code(hw); 163 + 164 + wxhw->mac.max_rx_queues = NGBE_MAX_RX_QUEUES; 165 + wxhw->mac.max_tx_queues = NGBE_MAX_TX_QUEUES; 166 + wxhw->mac.num_rar_entries = NGBE_RAR_ENTRIES; 167 + /* Set common capability flags and settings */ 168 + adapter->max_q_vectors = NGBE_MAX_MSIX_VECTORS; 169 + 170 + err = wx_get_pcie_msix_counts(wxhw, &msix_count, NGBE_MAX_MSIX_VECTORS); 171 + if (err) 172 + dev_err(&pdev->dev, "Do not support MSI-X\n"); 173 + wxhw->mac.max_msix_vectors = msix_count; 174 + 175 + adapter->mac_table = kcalloc(wxhw->mac.num_rar_entries, 176 + sizeof(struct ngbe_mac_addr), 177 + GFP_KERNEL); 178 + if (!adapter->mac_table) { 179 + dev_err(&pdev->dev, "mac_table allocation failed: %d\n", err); 180 + return -ENOMEM; 181 + } 182 + 183 + if (ngbe_init_rss_key(adapter)) 184 + return -ENOMEM; 185 + 186 + /* enable itr by default in dynamic mode */ 187 + adapter->rx_itr_setting = 1; 188 + adapter->tx_itr_setting = 1; 189 + 190 + /* set default ring sizes */ 191 + adapter->tx_ring_count = NGBE_DEFAULT_TXD; 192 + adapter->rx_ring_count = NGBE_DEFAULT_RXD; 193 + 194 + /* set default work limits */ 195 + adapter->tx_work_limit = NGBE_DEFAULT_TX_WORK; 196 + adapter->rx_work_limit = NGBE_DEFAULT_RX_WORK; 197 + 198 + return 0; 199 + } 200 + 201 + static void ngbe_down(struct ngbe_adapter *adapter) 202 + { 203 + netif_carrier_off(adapter->netdev); 204 + netif_tx_disable(adapter->netdev); 205 + }; 206 + 207 + /** 208 + * ngbe_open - Called when a network interface is made active 209 + * @netdev: network interface device structure 210 + * 211 + * Returns 0 on success, negative value on failure 212 + * 213 + * The open entry point is called when a network interface is made 214 + * active by the system (IFF_UP). 215 + **/ 216 + static int ngbe_open(struct net_device *netdev) 217 + { 218 + struct ngbe_adapter *adapter = netdev_priv(netdev); 219 + struct ngbe_hw *hw = &adapter->hw; 220 + struct wx_hw *wxhw = &hw->wxhw; 221 + 222 + wx_control_hw(wxhw, true); 223 + 224 + return 0; 225 + } 226 + 227 + /** 228 + * ngbe_close - Disables a network interface 229 + * @netdev: network interface device structure 230 + * 231 + * Returns 0, this is not allowed to fail 232 + * 233 + * The close entry point is called when an interface is de-activated 234 + * by the OS. The hardware is still under the drivers control, but 235 + * needs to be disabled. A global MAC reset is issued to stop the 236 + * hardware, and all transmit and receive resources are freed. 237 + **/ 238 + static int ngbe_close(struct net_device *netdev) 239 + { 240 + struct ngbe_adapter *adapter = netdev_priv(netdev); 241 + 242 + ngbe_down(adapter); 243 + wx_control_hw(&adapter->hw.wxhw, false); 244 + 245 + return 0; 246 + } 247 + 248 + static netdev_tx_t ngbe_xmit_frame(struct sk_buff *skb, 249 + struct net_device *netdev) 250 + { 251 + return NETDEV_TX_OK; 252 + } 253 + 254 + /** 255 + * ngbe_set_mac - Change the Ethernet Address of the NIC 256 + * @netdev: network interface device structure 257 + * @p: pointer to an address structure 258 + * 259 + * Returns 0 on success, negative on failure 260 + **/ 261 + static int ngbe_set_mac(struct net_device *netdev, void *p) 262 + { 263 + struct ngbe_adapter *adapter = netdev_priv(netdev); 264 + struct wx_hw *wxhw = &adapter->hw.wxhw; 265 + struct sockaddr *addr = p; 266 + 267 + if (!is_valid_ether_addr(addr->sa_data)) 268 + return -EADDRNOTAVAIL; 269 + 270 + eth_hw_addr_set(netdev, addr->sa_data); 271 + memcpy(wxhw->mac.addr, addr->sa_data, netdev->addr_len); 272 + 273 + ngbe_mac_set_default_filter(adapter, wxhw->mac.addr); 274 + 275 + return 0; 276 + } 277 + 42 278 static void ngbe_dev_shutdown(struct pci_dev *pdev, bool *enable_wake) 43 279 { 44 280 struct ngbe_adapter *adapter = pci_get_drvdata(pdev); ··· 287 41 288 42 netif_device_detach(netdev); 289 43 44 + rtnl_lock(); 45 + if (netif_running(netdev)) 46 + ngbe_down(adapter); 47 + rtnl_unlock(); 48 + wx_control_hw(&adapter->hw.wxhw, false); 49 + 290 50 pci_disable_device(pdev); 291 51 } 292 52 293 53 static void ngbe_shutdown(struct pci_dev *pdev) 294 54 { 55 + struct ngbe_adapter *adapter = pci_get_drvdata(pdev); 295 56 bool wake; 57 + 58 + wake = !!adapter->wol; 296 59 297 60 ngbe_dev_shutdown(pdev, &wake); 298 61 ··· 310 55 pci_set_power_state(pdev, PCI_D3hot); 311 56 } 312 57 } 58 + 59 + static const struct net_device_ops ngbe_netdev_ops = { 60 + .ndo_open = ngbe_open, 61 + .ndo_stop = ngbe_close, 62 + .ndo_start_xmit = ngbe_xmit_frame, 63 + .ndo_validate_addr = eth_validate_addr, 64 + .ndo_set_mac_address = ngbe_set_mac, 65 + }; 313 66 314 67 /** 315 68 * ngbe_probe - Device Initialization Routine ··· 334 71 const struct pci_device_id __always_unused *ent) 335 72 { 336 73 struct ngbe_adapter *adapter = NULL; 74 + struct ngbe_hw *hw = NULL; 75 + struct wx_hw *wxhw = NULL; 337 76 struct net_device *netdev; 77 + u32 e2rom_cksum_cap = 0; 78 + static int func_nums; 79 + u16 e2rom_ver = 0; 80 + u32 etrack_id = 0; 81 + u32 saved_ver = 0; 338 82 int err; 339 83 340 84 err = pci_enable_device_mem(pdev); ··· 381 111 adapter = netdev_priv(netdev); 382 112 adapter->netdev = netdev; 383 113 adapter->pdev = pdev; 114 + hw = &adapter->hw; 115 + wxhw = &hw->wxhw; 116 + adapter->msg_enable = BIT(3) - 1; 384 117 385 118 adapter->io_addr = devm_ioremap(&pdev->dev, 386 119 pci_resource_start(pdev, 0), ··· 393 120 goto err_pci_release_regions; 394 121 } 395 122 123 + netdev->netdev_ops = &ngbe_netdev_ops; 124 + 396 125 netdev->features |= NETIF_F_HIGHDMA; 126 + 127 + adapter->bd_number = func_nums; 128 + /* setup the private structure */ 129 + err = ngbe_sw_init(adapter); 130 + if (err) 131 + goto err_free_mac_table; 132 + 133 + /* check if flash load is done after hw power up */ 134 + err = wx_check_flash_load(wxhw, NGBE_SPI_ILDR_STATUS_PERST); 135 + if (err) 136 + goto err_free_mac_table; 137 + err = wx_check_flash_load(wxhw, NGBE_SPI_ILDR_STATUS_PWRRST); 138 + if (err) 139 + goto err_free_mac_table; 140 + 141 + err = wx_mng_present(wxhw); 142 + if (err) { 143 + dev_err(&pdev->dev, "Management capability is not present\n"); 144 + goto err_free_mac_table; 145 + } 146 + 147 + err = ngbe_reset_hw(hw); 148 + if (err) { 149 + dev_err(&pdev->dev, "HW Init failed: %d\n", err); 150 + goto err_free_mac_table; 151 + } 152 + 153 + if (wxhw->bus.func == 0) { 154 + wr32(wxhw, NGBE_CALSUM_CAP_STATUS, 0x0); 155 + wr32(wxhw, NGBE_EEPROM_VERSION_STORE_REG, 0x0); 156 + } else { 157 + e2rom_cksum_cap = rd32(wxhw, NGBE_CALSUM_CAP_STATUS); 158 + saved_ver = rd32(wxhw, NGBE_EEPROM_VERSION_STORE_REG); 159 + } 160 + 161 + wx_init_eeprom_params(wxhw); 162 + if (wxhw->bus.func == 0 || e2rom_cksum_cap == 0) { 163 + /* make sure the EEPROM is ready */ 164 + err = ngbe_eeprom_chksum_hostif(hw); 165 + if (err) { 166 + dev_err(&pdev->dev, "The EEPROM Checksum Is Not Valid\n"); 167 + err = -EIO; 168 + goto err_free_mac_table; 169 + } 170 + } 171 + 172 + adapter->wol = 0; 173 + if (hw->wol_enabled) 174 + adapter->wol = NGBE_PSR_WKUP_CTL_MAG; 175 + 176 + hw->wol_enabled = !!(adapter->wol); 177 + wr32(wxhw, NGBE_PSR_WKUP_CTL, adapter->wol); 178 + 179 + device_set_wakeup_enable(&pdev->dev, adapter->wol); 180 + 181 + /* Save off EEPROM version number and Option Rom version which 182 + * together make a unique identify for the eeprom 183 + */ 184 + if (saved_ver) { 185 + etrack_id = saved_ver; 186 + } else { 187 + wx_read_ee_hostif(wxhw, 188 + wxhw->eeprom.sw_region_offset + NGBE_EEPROM_VERSION_H, 189 + &e2rom_ver); 190 + etrack_id = e2rom_ver << 16; 191 + wx_read_ee_hostif(wxhw, 192 + wxhw->eeprom.sw_region_offset + NGBE_EEPROM_VERSION_L, 193 + &e2rom_ver); 194 + etrack_id |= e2rom_ver; 195 + wr32(wxhw, NGBE_EEPROM_VERSION_STORE_REG, etrack_id); 196 + } 197 + 198 + eth_hw_addr_set(netdev, wxhw->mac.perm_addr); 199 + ngbe_mac_set_default_filter(adapter, wxhw->mac.perm_addr); 200 + 201 + err = register_netdev(netdev); 202 + if (err) 203 + goto err_register; 397 204 398 205 pci_set_drvdata(pdev, adapter); 399 206 207 + netif_info(adapter, probe, netdev, 208 + "PHY: %s, PBA No: Wang Xun GbE Family Controller\n", 209 + hw->phy.type == ngbe_phy_internal ? "Internal" : "External"); 210 + netif_info(adapter, probe, netdev, "%pM\n", netdev->dev_addr); 211 + 400 212 return 0; 401 213 214 + err_register: 215 + wx_control_hw(wxhw, false); 216 + err_free_mac_table: 217 + kfree(adapter->mac_table); 402 218 err_pci_release_regions: 403 219 pci_disable_pcie_error_reporting(pdev); 404 220 pci_release_selected_regions(pdev, ··· 508 146 **/ 509 147 static void ngbe_remove(struct pci_dev *pdev) 510 148 { 149 + struct ngbe_adapter *adapter = pci_get_drvdata(pdev); 150 + struct net_device *netdev; 151 + 152 + netdev = adapter->netdev; 153 + unregister_netdev(netdev); 511 154 pci_release_selected_regions(pdev, 512 155 pci_select_bars(pdev, IORESOURCE_MEM)); 513 156 157 + kfree(adapter->mac_table); 514 158 pci_disable_pcie_error_reporting(pdev); 515 159 516 160 pci_disable_device(pdev);
+94 -5
drivers/net/ethernet/wangxun/ngbe/ngbe_type.h
··· 8 8 #include <linux/netdevice.h> 9 9 10 10 /************ NGBE_register.h ************/ 11 - /* Vendor ID */ 12 - #ifndef PCI_VENDOR_ID_WANGXUN 13 - #define PCI_VENDOR_ID_WANGXUN 0x8088 14 - #endif 15 - 16 11 /* Device IDs */ 17 12 #define NGBE_DEV_ID_EM_WX1860AL_W 0x0100 18 13 #define NGBE_DEV_ID_EM_WX1860A2 0x0101 ··· 42 47 #define NGBE_WOL_SUP 0x4000 43 48 #define NGBE_WOL_MASK 0x4000 44 49 50 + /**************** EM Registers ****************************/ 51 + /* chip control Registers */ 52 + #define NGBE_MIS_PRB_CTL 0x10010 53 + /* FMGR Registers */ 54 + #define NGBE_SPI_ILDR_STATUS 0x10120 55 + #define NGBE_SPI_ILDR_STATUS_PERST BIT(0) /* PCIE_PERST is done */ 56 + #define NGBE_SPI_ILDR_STATUS_PWRRST BIT(1) /* Power on reset is done */ 57 + #define NGBE_SPI_ILDR_STATUS_LAN_SW_RST(_i) BIT((_i) + 9) /* lan soft reset done */ 58 + 59 + /* Checksum and EEPROM pointers */ 60 + #define NGBE_CALSUM_COMMAND 0xE9 61 + #define NGBE_CALSUM_CAP_STATUS 0x10224 62 + #define NGBE_EEPROM_VERSION_STORE_REG 0x1022C 63 + #define NGBE_SAN_MAC_ADDR_PTR 0x18 64 + #define NGBE_DEVICE_CAPS 0x1C 65 + #define NGBE_EEPROM_VERSION_L 0x1D 66 + #define NGBE_EEPROM_VERSION_H 0x1E 67 + 68 + /* Media-dependent registers. */ 69 + #define NGBE_MDIO_CLAUSE_SELECT 0x11220 70 + 71 + /* GPIO Registers */ 72 + #define NGBE_GPIO_DR 0x14800 73 + #define NGBE_GPIO_DDR 0x14804 74 + /*GPIO bit */ 75 + #define NGBE_GPIO_DR_0 BIT(0) /* SDP0 Data Value */ 76 + #define NGBE_GPIO_DR_1 BIT(1) /* SDP1 Data Value */ 77 + #define NGBE_GPIO_DDR_0 BIT(0) /* SDP0 IO direction */ 78 + #define NGBE_GPIO_DDR_1 BIT(1) /* SDP1 IO direction */ 79 + 80 + /* Wake up registers */ 81 + #define NGBE_PSR_WKUP_CTL 0x15B80 82 + /* Wake Up Filter Control Bit */ 83 + #define NGBE_PSR_WKUP_CTL_LNKC BIT(0) /* Link Status Change Wakeup Enable*/ 84 + #define NGBE_PSR_WKUP_CTL_MAG BIT(1) /* Magic Packet Wakeup Enable */ 85 + #define NGBE_PSR_WKUP_CTL_EX BIT(2) /* Directed Exact Wakeup Enable */ 86 + #define NGBE_PSR_WKUP_CTL_MC BIT(3) /* Directed Multicast Wakeup Enable*/ 87 + #define NGBE_PSR_WKUP_CTL_BC BIT(4) /* Broadcast Wakeup Enable */ 88 + #define NGBE_PSR_WKUP_CTL_ARP BIT(5) /* ARP Request Packet Wakeup Enable*/ 89 + #define NGBE_PSR_WKUP_CTL_IPV4 BIT(6) /* Directed IPv4 Pkt Wakeup Enable */ 90 + #define NGBE_PSR_WKUP_CTL_IPV6 BIT(7) /* Directed IPv6 Pkt Wakeup Enable */ 91 + 92 + #define NGBE_FW_EEPROM_CHECKSUM_CMD 0xE9 93 + #define NGBE_FW_NVM_DATA_OFFSET 3 94 + #define NGBE_FW_CMD_DEFAULT_CHECKSUM 0xFF /* checksum always 0xFF */ 95 + #define NGBE_FW_CMD_ST_PASS 0x80658383 96 + #define NGBE_FW_CMD_ST_FAIL 0x70657376 97 + 98 + enum ngbe_phy_type { 99 + ngbe_phy_unknown = 0, 100 + ngbe_phy_none, 101 + ngbe_phy_internal, 102 + ngbe_phy_m88e1512, 103 + ngbe_phy_m88e1512_sfi, 104 + ngbe_phy_m88e1512_unknown, 105 + ngbe_phy_yt8521s, 106 + ngbe_phy_yt8521s_sfi, 107 + ngbe_phy_internal_yt8521s_sfi, 108 + ngbe_phy_generic 109 + }; 110 + 111 + enum ngbe_media_type { 112 + ngbe_media_type_unknown = 0, 113 + ngbe_media_type_fiber, 114 + ngbe_media_type_copper, 115 + ngbe_media_type_backplane, 116 + }; 117 + 118 + enum ngbe_mac_type { 119 + ngbe_mac_type_unknown = 0, 120 + ngbe_mac_type_mdi, 121 + ngbe_mac_type_rgmii 122 + }; 123 + 124 + struct ngbe_phy_info { 125 + enum ngbe_phy_type type; 126 + enum ngbe_media_type media_type; 127 + 128 + u32 addr; 129 + u32 id; 130 + 131 + bool reset_if_overtemp; 132 + 133 + }; 134 + 135 + struct ngbe_hw { 136 + struct wx_hw wxhw; 137 + struct ngbe_phy_info phy; 138 + enum ngbe_mac_type mac_type; 139 + 140 + bool wol_enabled; 141 + bool ncsi_enabled; 142 + bool gpio_ctrl; 143 + }; 45 144 #endif /* _NGBE_TYPE_H_ */
+1
drivers/net/ethernet/wangxun/txgbe/txgbe.h
··· 35 35 struct txgbe_hw hw; 36 36 u16 msg_enable; 37 37 struct txgbe_mac_addr *mac_table; 38 + char eeprom_id[32]; 38 39 }; 39 40 40 41 extern char txgbe_driver_name[];
+215 -4
drivers/net/ethernet/wangxun/txgbe/txgbe_hw.c
··· 44 44 wr32(wxhw, WX_TS_DALARM_THRE, 614); 45 45 } 46 46 47 + /** 48 + * txgbe_read_pba_string - Reads part number string from EEPROM 49 + * @hw: pointer to hardware structure 50 + * @pba_num: stores the part number string from the EEPROM 51 + * @pba_num_size: part number string buffer length 52 + * 53 + * Reads the part number string from the EEPROM. 54 + **/ 55 + int txgbe_read_pba_string(struct txgbe_hw *hw, u8 *pba_num, u32 pba_num_size) 56 + { 57 + u16 pba_ptr, offset, length, data; 58 + struct wx_hw *wxhw = &hw->wxhw; 59 + int ret_val; 60 + 61 + if (!pba_num) { 62 + wx_err(wxhw, "PBA string buffer was null\n"); 63 + return -EINVAL; 64 + } 65 + 66 + ret_val = wx_read_ee_hostif(wxhw, 67 + wxhw->eeprom.sw_region_offset + TXGBE_PBANUM0_PTR, 68 + &data); 69 + if (ret_val != 0) { 70 + wx_err(wxhw, "NVM Read Error\n"); 71 + return ret_val; 72 + } 73 + 74 + ret_val = wx_read_ee_hostif(wxhw, 75 + wxhw->eeprom.sw_region_offset + TXGBE_PBANUM1_PTR, 76 + &pba_ptr); 77 + if (ret_val != 0) { 78 + wx_err(wxhw, "NVM Read Error\n"); 79 + return ret_val; 80 + } 81 + 82 + /* if data is not ptr guard the PBA must be in legacy format which 83 + * means pba_ptr is actually our second data word for the PBA number 84 + * and we can decode it into an ascii string 85 + */ 86 + if (data != TXGBE_PBANUM_PTR_GUARD) { 87 + wx_err(wxhw, "NVM PBA number is not stored as string\n"); 88 + 89 + /* we will need 11 characters to store the PBA */ 90 + if (pba_num_size < 11) { 91 + wx_err(wxhw, "PBA string buffer too small\n"); 92 + return -ENOMEM; 93 + } 94 + 95 + /* extract hex string from data and pba_ptr */ 96 + pba_num[0] = (data >> 12) & 0xF; 97 + pba_num[1] = (data >> 8) & 0xF; 98 + pba_num[2] = (data >> 4) & 0xF; 99 + pba_num[3] = data & 0xF; 100 + pba_num[4] = (pba_ptr >> 12) & 0xF; 101 + pba_num[5] = (pba_ptr >> 8) & 0xF; 102 + pba_num[6] = '-'; 103 + pba_num[7] = 0; 104 + pba_num[8] = (pba_ptr >> 4) & 0xF; 105 + pba_num[9] = pba_ptr & 0xF; 106 + 107 + /* put a null character on the end of our string */ 108 + pba_num[10] = '\0'; 109 + 110 + /* switch all the data but the '-' to hex char */ 111 + for (offset = 0; offset < 10; offset++) { 112 + if (pba_num[offset] < 0xA) 113 + pba_num[offset] += '0'; 114 + else if (pba_num[offset] < 0x10) 115 + pba_num[offset] += 'A' - 0xA; 116 + } 117 + 118 + return 0; 119 + } 120 + 121 + ret_val = wx_read_ee_hostif(wxhw, pba_ptr, &length); 122 + if (ret_val != 0) { 123 + wx_err(wxhw, "NVM Read Error\n"); 124 + return ret_val; 125 + } 126 + 127 + if (length == 0xFFFF || length == 0) { 128 + wx_err(wxhw, "NVM PBA number section invalid length\n"); 129 + return -EINVAL; 130 + } 131 + 132 + /* check if pba_num buffer is big enough */ 133 + if (pba_num_size < (((u32)length * 2) - 1)) { 134 + wx_err(wxhw, "PBA string buffer too small\n"); 135 + return -ENOMEM; 136 + } 137 + 138 + /* trim pba length from start of string */ 139 + pba_ptr++; 140 + length--; 141 + 142 + for (offset = 0; offset < length; offset++) { 143 + ret_val = wx_read_ee_hostif(wxhw, pba_ptr + offset, &data); 144 + if (ret_val != 0) { 145 + wx_err(wxhw, "NVM Read Error\n"); 146 + return ret_val; 147 + } 148 + pba_num[offset * 2] = (u8)(data >> 8); 149 + pba_num[(offset * 2) + 1] = (u8)(data & 0xFF); 150 + } 151 + pba_num[offset * 2] = '\0'; 152 + 153 + return 0; 154 + } 155 + 156 + /** 157 + * txgbe_calc_eeprom_checksum - Calculates and returns the checksum 158 + * @hw: pointer to hardware structure 159 + * @checksum: pointer to cheksum 160 + * 161 + * Returns a negative error code on error 162 + **/ 163 + static int txgbe_calc_eeprom_checksum(struct txgbe_hw *hw, u16 *checksum) 164 + { 165 + struct wx_hw *wxhw = &hw->wxhw; 166 + u16 *eeprom_ptrs = NULL; 167 + u32 buffer_size = 0; 168 + u16 *buffer = NULL; 169 + u16 *local_buffer; 170 + int status; 171 + u16 i; 172 + 173 + wx_init_eeprom_params(wxhw); 174 + 175 + if (!buffer) { 176 + eeprom_ptrs = kvmalloc_array(TXGBE_EEPROM_LAST_WORD, sizeof(u16), 177 + GFP_KERNEL); 178 + if (!eeprom_ptrs) 179 + return -ENOMEM; 180 + /* Read pointer area */ 181 + status = wx_read_ee_hostif_buffer(wxhw, 0, 182 + TXGBE_EEPROM_LAST_WORD, 183 + eeprom_ptrs); 184 + if (status != 0) { 185 + wx_err(wxhw, "Failed to read EEPROM image\n"); 186 + return status; 187 + } 188 + local_buffer = eeprom_ptrs; 189 + } else { 190 + if (buffer_size < TXGBE_EEPROM_LAST_WORD) 191 + return -EFAULT; 192 + local_buffer = buffer; 193 + } 194 + 195 + for (i = 0; i < TXGBE_EEPROM_LAST_WORD; i++) 196 + if (i != wxhw->eeprom.sw_region_offset + TXGBE_EEPROM_CHECKSUM) 197 + *checksum += local_buffer[i]; 198 + 199 + *checksum = TXGBE_EEPROM_SUM - *checksum; 200 + if (*checksum < 0) 201 + return -EINVAL; 202 + 203 + if (eeprom_ptrs) 204 + kvfree(eeprom_ptrs); 205 + 206 + return 0; 207 + } 208 + 209 + /** 210 + * txgbe_validate_eeprom_checksum - Validate EEPROM checksum 211 + * @hw: pointer to hardware structure 212 + * @checksum_val: calculated checksum 213 + * 214 + * Performs checksum calculation and validates the EEPROM checksum. If the 215 + * caller does not need checksum_val, the value can be NULL. 216 + **/ 217 + int txgbe_validate_eeprom_checksum(struct txgbe_hw *hw, u16 *checksum_val) 218 + { 219 + struct wx_hw *wxhw = &hw->wxhw; 220 + u16 read_checksum = 0; 221 + u16 checksum; 222 + int status; 223 + 224 + /* Read the first word from the EEPROM. If this times out or fails, do 225 + * not continue or we could be in for a very long wait while every 226 + * EEPROM read fails 227 + */ 228 + status = wx_read_ee_hostif(wxhw, 0, &checksum); 229 + if (status) { 230 + wx_err(wxhw, "EEPROM read failed\n"); 231 + return status; 232 + } 233 + 234 + checksum = 0; 235 + status = txgbe_calc_eeprom_checksum(hw, &checksum); 236 + if (status != 0) 237 + return status; 238 + 239 + status = wx_read_ee_hostif(wxhw, wxhw->eeprom.sw_region_offset + 240 + TXGBE_EEPROM_CHECKSUM, &read_checksum); 241 + if (status != 0) 242 + return status; 243 + 244 + /* Verify read checksum from EEPROM is the same as 245 + * calculated checksum 246 + */ 247 + if (read_checksum != checksum) { 248 + status = -EIO; 249 + wx_err(wxhw, "Invalid EEPROM checksum\n"); 250 + } 251 + 252 + /* If the user cares, return the calculated checksum */ 253 + if (checksum_val) 254 + *checksum_val = checksum; 255 + 256 + return status; 257 + } 258 + 47 259 static void txgbe_reset_misc(struct txgbe_hw *hw) 48 260 { 49 261 struct wx_hw *wxhw = &hw->wxhw; ··· 275 63 int txgbe_reset_hw(struct txgbe_hw *hw) 276 64 { 277 65 struct wx_hw *wxhw = &hw->wxhw; 278 - u32 reset = 0; 279 66 int status; 280 67 281 68 /* Call adapter stop to disable tx/rx and clear interrupts */ ··· 282 71 if (status != 0) 283 72 return status; 284 73 285 - reset = WX_MIS_RST_LAN_RST(wxhw->bus.func); 286 - wr32(wxhw, WX_MIS_RST, reset | rd32(wxhw, WX_MIS_RST)); 74 + if (!(((wxhw->subsystem_device_id & WX_NCSI_MASK) == WX_NCSI_SUP) || 75 + ((wxhw->subsystem_device_id & WX_WOL_MASK) == WX_WOL_SUP))) 76 + wx_reset_hostif(wxhw); 287 77 288 - WX_WRITE_FLUSH(wxhw); 289 78 usleep_range(10, 100); 290 79 291 80 status = wx_check_flash_load(wxhw, TXGBE_SPI_ILDR_STATUS_LAN_SW_RST(wxhw->bus.func));
+2
drivers/net/ethernet/wangxun/txgbe/txgbe_hw.h
··· 4 4 #ifndef _TXGBE_HW_H_ 5 5 #define _TXGBE_HW_H_ 6 6 7 + int txgbe_read_pba_string(struct txgbe_hw *hw, u8 *pba_num, u32 pba_num_size); 8 + int txgbe_validate_eeprom_checksum(struct txgbe_hw *hw, u16 *checksum_val); 7 9 int txgbe_reset_hw(struct txgbe_hw *hw); 8 10 9 11 #endif /* _TXGBE_HW_H_ */
+84 -1
drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
··· 158 158 return -ENOMEM; 159 159 } 160 160 161 + static void txgbe_up_complete(struct txgbe_adapter *adapter) 162 + { 163 + struct txgbe_hw *hw = &adapter->hw; 164 + struct wx_hw *wxhw = &hw->wxhw; 165 + 166 + wx_control_hw(wxhw, true); 167 + } 168 + 161 169 static void txgbe_reset(struct txgbe_adapter *adapter) 162 170 { 163 171 struct net_device *netdev = adapter->netdev; ··· 278 270 **/ 279 271 static int txgbe_open(struct net_device *netdev) 280 272 { 273 + struct txgbe_adapter *adapter = netdev_priv(netdev); 274 + 275 + txgbe_up_complete(adapter); 276 + 281 277 return 0; 282 278 } 283 279 ··· 313 301 struct txgbe_adapter *adapter = netdev_priv(netdev); 314 302 315 303 txgbe_down(adapter); 304 + wx_control_hw(&adapter->hw.wxhw, false); 316 305 317 306 return 0; 318 307 } ··· 322 309 { 323 310 struct txgbe_adapter *adapter = pci_get_drvdata(pdev); 324 311 struct net_device *netdev = adapter->netdev; 312 + struct txgbe_hw *hw = &adapter->hw; 313 + struct wx_hw *wxhw = &hw->wxhw; 325 314 326 315 netif_device_detach(netdev); 327 316 ··· 331 316 if (netif_running(netdev)) 332 317 txgbe_close_suspend(adapter); 333 318 rtnl_unlock(); 319 + 320 + wx_control_hw(wxhw, false); 334 321 335 322 pci_disable_device(pdev); 336 323 } ··· 410 393 struct net_device *netdev; 411 394 int err, expected_gts; 412 395 396 + u16 eeprom_verh = 0, eeprom_verl = 0, offset = 0; 397 + u16 eeprom_cfg_blkh = 0, eeprom_cfg_blkl = 0; 398 + u16 build = 0, major = 0, patch = 0; 399 + u8 part_str[TXGBE_PBANUM_LENGTH]; 400 + u32 etrack_id = 0; 401 + 413 402 err = pci_enable_device_mem(pdev); 414 403 if (err) 415 404 return err; ··· 480 457 if (err) 481 458 goto err_free_mac_table; 482 459 460 + err = wx_mng_present(wxhw); 461 + if (err) { 462 + dev_err(&pdev->dev, "Management capability is not present\n"); 463 + goto err_free_mac_table; 464 + } 465 + 483 466 err = txgbe_reset_hw(hw); 484 467 if (err) { 485 468 dev_err(&pdev->dev, "HW Init failed: %d\n", err); ··· 494 465 495 466 netdev->features |= NETIF_F_HIGHDMA; 496 467 468 + /* make sure the EEPROM is good */ 469 + err = txgbe_validate_eeprom_checksum(hw, NULL); 470 + if (err != 0) { 471 + dev_err(&pdev->dev, "The EEPROM Checksum Is Not Valid\n"); 472 + wr32(wxhw, WX_MIS_RST, WX_MIS_RST_SW_RST); 473 + err = -EIO; 474 + goto err_free_mac_table; 475 + } 476 + 497 477 eth_hw_addr_set(netdev, wxhw->mac.perm_addr); 498 478 txgbe_mac_set_default_filter(adapter, wxhw->mac.perm_addr); 499 479 480 + /* Save off EEPROM version number and Option Rom version which 481 + * together make a unique identify for the eeprom 482 + */ 483 + wx_read_ee_hostif(wxhw, 484 + wxhw->eeprom.sw_region_offset + TXGBE_EEPROM_VERSION_H, 485 + &eeprom_verh); 486 + wx_read_ee_hostif(wxhw, 487 + wxhw->eeprom.sw_region_offset + TXGBE_EEPROM_VERSION_L, 488 + &eeprom_verl); 489 + etrack_id = (eeprom_verh << 16) | eeprom_verl; 490 + 491 + wx_read_ee_hostif(wxhw, 492 + wxhw->eeprom.sw_region_offset + TXGBE_ISCSI_BOOT_CONFIG, 493 + &offset); 494 + 495 + /* Make sure offset to SCSI block is valid */ 496 + if (!(offset == 0x0) && !(offset == 0xffff)) { 497 + wx_read_ee_hostif(wxhw, offset + 0x84, &eeprom_cfg_blkh); 498 + wx_read_ee_hostif(wxhw, offset + 0x83, &eeprom_cfg_blkl); 499 + 500 + /* Only display Option Rom if exist */ 501 + if (eeprom_cfg_blkl && eeprom_cfg_blkh) { 502 + major = eeprom_cfg_blkl >> 8; 503 + build = (eeprom_cfg_blkl << 8) | (eeprom_cfg_blkh >> 8); 504 + patch = eeprom_cfg_blkh & 0x00ff; 505 + 506 + snprintf(adapter->eeprom_id, sizeof(adapter->eeprom_id), 507 + "0x%08x, %d.%d.%d", etrack_id, major, build, 508 + patch); 509 + } else { 510 + snprintf(adapter->eeprom_id, sizeof(adapter->eeprom_id), 511 + "0x%08x", etrack_id); 512 + } 513 + } else { 514 + snprintf(adapter->eeprom_id, sizeof(adapter->eeprom_id), 515 + "0x%08x", etrack_id); 516 + } 517 + 500 518 err = register_netdev(netdev); 501 519 if (err) 502 - goto err_free_mac_table; 520 + goto err_release_hw; 503 521 504 522 pci_set_drvdata(pdev, adapter); 505 523 ··· 564 488 else 565 489 dev_warn(&pdev->dev, "Failed to enumerate PF devices.\n"); 566 490 491 + /* First try to read PBA as a string */ 492 + err = txgbe_read_pba_string(hw, part_str, TXGBE_PBANUM_LENGTH); 493 + if (err) 494 + strncpy(part_str, "Unknown", TXGBE_PBANUM_LENGTH); 495 + 567 496 netif_info(adapter, probe, netdev, "%pM\n", netdev->dev_addr); 568 497 569 498 return 0; 570 499 500 + err_release_hw: 501 + wx_control_hw(wxhw, false); 571 502 err_free_mac_table: 572 503 kfree(adapter->mac_table); 573 504 err_pci_release_regions:
+14
drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
··· 53 53 #define TXGBE_TS_CTL 0x10300 54 54 #define TXGBE_TS_CTL_EVAL_MD BIT(31) 55 55 56 + /* Part Number String Length */ 57 + #define TXGBE_PBANUM_LENGTH 32 58 + 59 + /* Checksum and EEPROM pointers */ 60 + #define TXGBE_EEPROM_LAST_WORD 0x800 61 + #define TXGBE_EEPROM_CHECKSUM 0x2F 62 + #define TXGBE_EEPROM_SUM 0xBABA 63 + #define TXGBE_EEPROM_VERSION_L 0x1D 64 + #define TXGBE_EEPROM_VERSION_H 0x1E 65 + #define TXGBE_ISCSI_BOOT_CONFIG 0x07 66 + #define TXGBE_PBANUM0_PTR 0x05 67 + #define TXGBE_PBANUM1_PTR 0x06 68 + #define TXGBE_PBANUM_PTR_GUARD 0xFAFA 69 + 56 70 struct txgbe_hw { 57 71 struct wx_hw wxhw; 58 72 };