diff options
Diffstat (limited to 'drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c')
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 135 |
1 files changed, 83 insertions, 52 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index 0913c623a67e..9d4bb7f83904 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | |||
@@ -228,17 +228,17 @@ static int __qlcnic_set_win_base(struct qlcnic_adapter *adapter, u32 addr) | |||
228 | return 0; | 228 | return 0; |
229 | } | 229 | } |
230 | 230 | ||
231 | int qlcnic_83xx_rd_reg_indirect(struct qlcnic_adapter *adapter, ulong addr) | 231 | int qlcnic_83xx_rd_reg_indirect(struct qlcnic_adapter *adapter, ulong addr, |
232 | int *err) | ||
232 | { | 233 | { |
233 | int ret; | ||
234 | struct qlcnic_hardware_context *ahw = adapter->ahw; | 234 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
235 | 235 | ||
236 | ret = __qlcnic_set_win_base(adapter, (u32) addr); | 236 | *err = __qlcnic_set_win_base(adapter, (u32) addr); |
237 | if (!ret) { | 237 | if (!*err) { |
238 | return QLCRDX(ahw, QLCNIC_WILDCARD); | 238 | return QLCRDX(ahw, QLCNIC_WILDCARD); |
239 | } else { | 239 | } else { |
240 | dev_err(&adapter->pdev->dev, | 240 | dev_err(&adapter->pdev->dev, |
241 | "%s failed, addr = 0x%x\n", __func__, (int)addr); | 241 | "%s failed, addr = 0x%lx\n", __func__, addr); |
242 | return -EIO; | 242 | return -EIO; |
243 | } | 243 | } |
244 | } | 244 | } |
@@ -561,7 +561,7 @@ void qlcnic_83xx_cam_unlock(struct qlcnic_adapter *adapter) | |||
561 | void qlcnic_83xx_read_crb(struct qlcnic_adapter *adapter, char *buf, | 561 | void qlcnic_83xx_read_crb(struct qlcnic_adapter *adapter, char *buf, |
562 | loff_t offset, size_t size) | 562 | loff_t offset, size_t size) |
563 | { | 563 | { |
564 | int ret; | 564 | int ret = 0; |
565 | u32 data; | 565 | u32 data; |
566 | 566 | ||
567 | if (qlcnic_api_lock(adapter)) { | 567 | if (qlcnic_api_lock(adapter)) { |
@@ -571,7 +571,7 @@ void qlcnic_83xx_read_crb(struct qlcnic_adapter *adapter, char *buf, | |||
571 | return; | 571 | return; |
572 | } | 572 | } |
573 | 573 | ||
574 | ret = qlcnic_83xx_rd_reg_indirect(adapter, (u32) offset); | 574 | data = QLCRD32(adapter, (u32) offset, &ret); |
575 | qlcnic_api_unlock(adapter); | 575 | qlcnic_api_unlock(adapter); |
576 | 576 | ||
577 | if (ret == -EIO) { | 577 | if (ret == -EIO) { |
@@ -580,7 +580,6 @@ void qlcnic_83xx_read_crb(struct qlcnic_adapter *adapter, char *buf, | |||
580 | __func__, (u32)offset); | 580 | __func__, (u32)offset); |
581 | return; | 581 | return; |
582 | } | 582 | } |
583 | data = ret; | ||
584 | memcpy(buf, &data, size); | 583 | memcpy(buf, &data, size); |
585 | } | 584 | } |
586 | 585 | ||
@@ -2075,18 +2074,25 @@ void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter) | |||
2075 | static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter, | 2074 | static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter, |
2076 | u32 data[]) | 2075 | u32 data[]) |
2077 | { | 2076 | { |
2077 | struct qlcnic_hardware_context *ahw = adapter->ahw; | ||
2078 | u8 link_status, duplex; | 2078 | u8 link_status, duplex; |
2079 | /* link speed */ | 2079 | /* link speed */ |
2080 | link_status = LSB(data[3]) & 1; | 2080 | link_status = LSB(data[3]) & 1; |
2081 | adapter->ahw->link_speed = MSW(data[2]); | 2081 | if (link_status) { |
2082 | adapter->ahw->link_autoneg = MSB(MSW(data[3])); | 2082 | ahw->link_speed = MSW(data[2]); |
2083 | adapter->ahw->module_type = MSB(LSW(data[3])); | 2083 | duplex = LSB(MSW(data[3])); |
2084 | duplex = LSB(MSW(data[3])); | 2084 | if (duplex) |
2085 | if (duplex) | 2085 | ahw->link_duplex = DUPLEX_FULL; |
2086 | adapter->ahw->link_duplex = DUPLEX_FULL; | 2086 | else |
2087 | else | 2087 | ahw->link_duplex = DUPLEX_HALF; |
2088 | adapter->ahw->link_duplex = DUPLEX_HALF; | 2088 | } else { |
2089 | adapter->ahw->has_link_events = 1; | 2089 | ahw->link_speed = SPEED_UNKNOWN; |
2090 | ahw->link_duplex = DUPLEX_UNKNOWN; | ||
2091 | } | ||
2092 | |||
2093 | ahw->link_autoneg = MSB(MSW(data[3])); | ||
2094 | ahw->module_type = MSB(LSW(data[3])); | ||
2095 | ahw->has_link_events = 1; | ||
2090 | qlcnic_advert_link_change(adapter, link_status); | 2096 | qlcnic_advert_link_change(adapter, link_status); |
2091 | } | 2097 | } |
2092 | 2098 | ||
@@ -2384,9 +2390,9 @@ int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *adapter, | |||
2384 | u32 flash_addr, u8 *p_data, | 2390 | u32 flash_addr, u8 *p_data, |
2385 | int count) | 2391 | int count) |
2386 | { | 2392 | { |
2387 | int i, ret; | 2393 | u32 word, range, flash_offset, addr = flash_addr, ret; |
2388 | u32 word, range, flash_offset, addr = flash_addr; | ||
2389 | ulong indirect_add, direct_window; | 2394 | ulong indirect_add, direct_window; |
2395 | int i, err = 0; | ||
2390 | 2396 | ||
2391 | flash_offset = addr & (QLCNIC_FLASH_SECTOR_SIZE - 1); | 2397 | flash_offset = addr & (QLCNIC_FLASH_SECTOR_SIZE - 1); |
2392 | if (addr & 0x3) { | 2398 | if (addr & 0x3) { |
@@ -2404,10 +2410,9 @@ int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *adapter, | |||
2404 | /* Multi sector read */ | 2410 | /* Multi sector read */ |
2405 | for (i = 0; i < count; i++) { | 2411 | for (i = 0; i < count; i++) { |
2406 | indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr); | 2412 | indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr); |
2407 | ret = qlcnic_83xx_rd_reg_indirect(adapter, | 2413 | ret = QLCRD32(adapter, indirect_add, &err); |
2408 | indirect_add); | 2414 | if (err == -EIO) |
2409 | if (ret == -EIO) | 2415 | return err; |
2410 | return -EIO; | ||
2411 | 2416 | ||
2412 | word = ret; | 2417 | word = ret; |
2413 | *(u32 *)p_data = word; | 2418 | *(u32 *)p_data = word; |
@@ -2428,10 +2433,9 @@ int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *adapter, | |||
2428 | /* Single sector read */ | 2433 | /* Single sector read */ |
2429 | for (i = 0; i < count; i++) { | 2434 | for (i = 0; i < count; i++) { |
2430 | indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr); | 2435 | indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr); |
2431 | ret = qlcnic_83xx_rd_reg_indirect(adapter, | 2436 | ret = QLCRD32(adapter, indirect_add, &err); |
2432 | indirect_add); | 2437 | if (err == -EIO) |
2433 | if (ret == -EIO) | 2438 | return err; |
2434 | return -EIO; | ||
2435 | 2439 | ||
2436 | word = ret; | 2440 | word = ret; |
2437 | *(u32 *)p_data = word; | 2441 | *(u32 *)p_data = word; |
@@ -2447,10 +2451,13 @@ static int qlcnic_83xx_poll_flash_status_reg(struct qlcnic_adapter *adapter) | |||
2447 | { | 2451 | { |
2448 | u32 status; | 2452 | u32 status; |
2449 | int retries = QLC_83XX_FLASH_READ_RETRY_COUNT; | 2453 | int retries = QLC_83XX_FLASH_READ_RETRY_COUNT; |
2454 | int err = 0; | ||
2450 | 2455 | ||
2451 | do { | 2456 | do { |
2452 | status = qlcnic_83xx_rd_reg_indirect(adapter, | 2457 | status = QLCRD32(adapter, QLC_83XX_FLASH_STATUS, &err); |
2453 | QLC_83XX_FLASH_STATUS); | 2458 | if (err == -EIO) |
2459 | return err; | ||
2460 | |||
2454 | if ((status & QLC_83XX_FLASH_STATUS_READY) == | 2461 | if ((status & QLC_83XX_FLASH_STATUS_READY) == |
2455 | QLC_83XX_FLASH_STATUS_READY) | 2462 | QLC_83XX_FLASH_STATUS_READY) |
2456 | break; | 2463 | break; |
@@ -2502,7 +2509,8 @@ int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *adapter) | |||
2502 | 2509 | ||
2503 | int qlcnic_83xx_read_flash_mfg_id(struct qlcnic_adapter *adapter) | 2510 | int qlcnic_83xx_read_flash_mfg_id(struct qlcnic_adapter *adapter) |
2504 | { | 2511 | { |
2505 | int ret, mfg_id; | 2512 | int ret, err = 0; |
2513 | u32 mfg_id; | ||
2506 | 2514 | ||
2507 | if (qlcnic_83xx_lock_flash(adapter)) | 2515 | if (qlcnic_83xx_lock_flash(adapter)) |
2508 | return -EIO; | 2516 | return -EIO; |
@@ -2517,9 +2525,11 @@ int qlcnic_83xx_read_flash_mfg_id(struct qlcnic_adapter *adapter) | |||
2517 | return -EIO; | 2525 | return -EIO; |
2518 | } | 2526 | } |
2519 | 2527 | ||
2520 | mfg_id = qlcnic_83xx_rd_reg_indirect(adapter, QLC_83XX_FLASH_RDDATA); | 2528 | mfg_id = QLCRD32(adapter, QLC_83XX_FLASH_RDDATA, &err); |
2521 | if (mfg_id == -EIO) | 2529 | if (err == -EIO) { |
2522 | return -EIO; | 2530 | qlcnic_83xx_unlock_flash(adapter); |
2531 | return err; | ||
2532 | } | ||
2523 | 2533 | ||
2524 | adapter->flash_mfg_id = (mfg_id & 0xFF); | 2534 | adapter->flash_mfg_id = (mfg_id & 0xFF); |
2525 | qlcnic_83xx_unlock_flash(adapter); | 2535 | qlcnic_83xx_unlock_flash(adapter); |
@@ -2636,7 +2646,7 @@ int qlcnic_83xx_flash_bulk_write(struct qlcnic_adapter *adapter, u32 addr, | |||
2636 | u32 *p_data, int count) | 2646 | u32 *p_data, int count) |
2637 | { | 2647 | { |
2638 | u32 temp; | 2648 | u32 temp; |
2639 | int ret = -EIO; | 2649 | int ret = -EIO, err = 0; |
2640 | 2650 | ||
2641 | if ((count < QLC_83XX_FLASH_WRITE_MIN) || | 2651 | if ((count < QLC_83XX_FLASH_WRITE_MIN) || |
2642 | (count > QLC_83XX_FLASH_WRITE_MAX)) { | 2652 | (count > QLC_83XX_FLASH_WRITE_MAX)) { |
@@ -2645,8 +2655,10 @@ int qlcnic_83xx_flash_bulk_write(struct qlcnic_adapter *adapter, u32 addr, | |||
2645 | return -EIO; | 2655 | return -EIO; |
2646 | } | 2656 | } |
2647 | 2657 | ||
2648 | temp = qlcnic_83xx_rd_reg_indirect(adapter, | 2658 | temp = QLCRD32(adapter, QLC_83XX_FLASH_SPI_CONTROL, &err); |
2649 | QLC_83XX_FLASH_SPI_CONTROL); | 2659 | if (err == -EIO) |
2660 | return err; | ||
2661 | |||
2650 | qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_SPI_CONTROL, | 2662 | qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_SPI_CONTROL, |
2651 | (temp | QLC_83XX_FLASH_SPI_CTRL)); | 2663 | (temp | QLC_83XX_FLASH_SPI_CTRL)); |
2652 | qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR, | 2664 | qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR, |
@@ -2695,13 +2707,18 @@ int qlcnic_83xx_flash_bulk_write(struct qlcnic_adapter *adapter, u32 addr, | |||
2695 | return -EIO; | 2707 | return -EIO; |
2696 | } | 2708 | } |
2697 | 2709 | ||
2698 | ret = qlcnic_83xx_rd_reg_indirect(adapter, QLC_83XX_FLASH_SPI_STATUS); | 2710 | ret = QLCRD32(adapter, QLC_83XX_FLASH_SPI_STATUS, &err); |
2711 | if (err == -EIO) | ||
2712 | return err; | ||
2713 | |||
2699 | if ((ret & QLC_83XX_FLASH_SPI_CTRL) == QLC_83XX_FLASH_SPI_CTRL) { | 2714 | if ((ret & QLC_83XX_FLASH_SPI_CTRL) == QLC_83XX_FLASH_SPI_CTRL) { |
2700 | dev_err(&adapter->pdev->dev, "%s: failed at %d\n", | 2715 | dev_err(&adapter->pdev->dev, "%s: failed at %d\n", |
2701 | __func__, __LINE__); | 2716 | __func__, __LINE__); |
2702 | /* Operation failed, clear error bit */ | 2717 | /* Operation failed, clear error bit */ |
2703 | temp = qlcnic_83xx_rd_reg_indirect(adapter, | 2718 | temp = QLCRD32(adapter, QLC_83XX_FLASH_SPI_CONTROL, &err); |
2704 | QLC_83XX_FLASH_SPI_CONTROL); | 2719 | if (err == -EIO) |
2720 | return err; | ||
2721 | |||
2705 | qlcnic_83xx_wrt_reg_indirect(adapter, | 2722 | qlcnic_83xx_wrt_reg_indirect(adapter, |
2706 | QLC_83XX_FLASH_SPI_CONTROL, | 2723 | QLC_83XX_FLASH_SPI_CONTROL, |
2707 | (temp | QLC_83XX_FLASH_SPI_CTRL)); | 2724 | (temp | QLC_83XX_FLASH_SPI_CTRL)); |
@@ -2823,6 +2840,7 @@ int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr, | |||
2823 | { | 2840 | { |
2824 | int i, j, ret = 0; | 2841 | int i, j, ret = 0; |
2825 | u32 temp; | 2842 | u32 temp; |
2843 | int err = 0; | ||
2826 | 2844 | ||
2827 | /* Check alignment */ | 2845 | /* Check alignment */ |
2828 | if (addr & 0xF) | 2846 | if (addr & 0xF) |
@@ -2855,8 +2873,12 @@ int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr, | |||
2855 | QLCNIC_TA_WRITE_START); | 2873 | QLCNIC_TA_WRITE_START); |
2856 | 2874 | ||
2857 | for (j = 0; j < MAX_CTL_CHECK; j++) { | 2875 | for (j = 0; j < MAX_CTL_CHECK; j++) { |
2858 | temp = qlcnic_83xx_rd_reg_indirect(adapter, | 2876 | temp = QLCRD32(adapter, QLCNIC_MS_CTRL, &err); |
2859 | QLCNIC_MS_CTRL); | 2877 | if (err == -EIO) { |
2878 | mutex_unlock(&adapter->ahw->mem_lock); | ||
2879 | return err; | ||
2880 | } | ||
2881 | |||
2860 | if ((temp & TA_CTL_BUSY) == 0) | 2882 | if ((temp & TA_CTL_BUSY) == 0) |
2861 | break; | 2883 | break; |
2862 | } | 2884 | } |
@@ -2878,9 +2900,9 @@ int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr, | |||
2878 | int qlcnic_83xx_flash_read32(struct qlcnic_adapter *adapter, u32 flash_addr, | 2900 | int qlcnic_83xx_flash_read32(struct qlcnic_adapter *adapter, u32 flash_addr, |
2879 | u8 *p_data, int count) | 2901 | u8 *p_data, int count) |
2880 | { | 2902 | { |
2881 | int i, ret; | 2903 | u32 word, addr = flash_addr, ret; |
2882 | u32 word, addr = flash_addr; | ||
2883 | ulong indirect_addr; | 2904 | ulong indirect_addr; |
2905 | int i, err = 0; | ||
2884 | 2906 | ||
2885 | if (qlcnic_83xx_lock_flash(adapter) != 0) | 2907 | if (qlcnic_83xx_lock_flash(adapter) != 0) |
2886 | return -EIO; | 2908 | return -EIO; |
@@ -2900,10 +2922,10 @@ int qlcnic_83xx_flash_read32(struct qlcnic_adapter *adapter, u32 flash_addr, | |||
2900 | } | 2922 | } |
2901 | 2923 | ||
2902 | indirect_addr = QLC_83XX_FLASH_DIRECT_DATA(addr); | 2924 | indirect_addr = QLC_83XX_FLASH_DIRECT_DATA(addr); |
2903 | ret = qlcnic_83xx_rd_reg_indirect(adapter, | 2925 | ret = QLCRD32(adapter, indirect_addr, &err); |
2904 | indirect_addr); | 2926 | if (err == -EIO) |
2905 | if (ret == -EIO) | 2927 | return err; |
2906 | return -EIO; | 2928 | |
2907 | word = ret; | 2929 | word = ret; |
2908 | *(u32 *)p_data = word; | 2930 | *(u32 *)p_data = word; |
2909 | p_data = p_data + 4; | 2931 | p_data = p_data + 4; |
@@ -3014,8 +3036,8 @@ int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter, | |||
3014 | } | 3036 | } |
3015 | 3037 | ||
3016 | if (ahw->port_type == QLCNIC_XGBE) { | 3038 | if (ahw->port_type == QLCNIC_XGBE) { |
3017 | ecmd->supported = SUPPORTED_1000baseT_Full; | 3039 | ecmd->supported = SUPPORTED_10000baseT_Full; |
3018 | ecmd->advertising = ADVERTISED_1000baseT_Full; | 3040 | ecmd->advertising = ADVERTISED_10000baseT_Full; |
3019 | } else { | 3041 | } else { |
3020 | ecmd->supported = (SUPPORTED_10baseT_Half | | 3042 | ecmd->supported = (SUPPORTED_10baseT_Half | |
3021 | SUPPORTED_10baseT_Full | | 3043 | SUPPORTED_10baseT_Full | |
@@ -3244,6 +3266,11 @@ int qlcnic_83xx_interrupt_test(struct net_device *netdev) | |||
3244 | u8 val; | 3266 | u8 val; |
3245 | int ret, max_sds_rings = adapter->max_sds_rings; | 3267 | int ret, max_sds_rings = adapter->max_sds_rings; |
3246 | 3268 | ||
3269 | if (test_bit(__QLCNIC_RESETTING, &adapter->state)) { | ||
3270 | netdev_info(netdev, "Device is resetting\n"); | ||
3271 | return -EBUSY; | ||
3272 | } | ||
3273 | |||
3247 | if (qlcnic_get_diag_lock(adapter)) { | 3274 | if (qlcnic_get_diag_lock(adapter)) { |
3248 | netdev_info(netdev, "Device in diagnostics mode\n"); | 3275 | netdev_info(netdev, "Device in diagnostics mode\n"); |
3249 | return -EBUSY; | 3276 | return -EBUSY; |
@@ -3369,7 +3396,8 @@ int qlcnic_83xx_set_pauseparam(struct qlcnic_adapter *adapter, | |||
3369 | 3396 | ||
3370 | static int qlcnic_83xx_read_flash_status_reg(struct qlcnic_adapter *adapter) | 3397 | static int qlcnic_83xx_read_flash_status_reg(struct qlcnic_adapter *adapter) |
3371 | { | 3398 | { |
3372 | int ret; | 3399 | int ret, err = 0; |
3400 | u32 temp; | ||
3373 | 3401 | ||
3374 | qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR, | 3402 | qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR, |
3375 | QLC_83XX_FLASH_OEM_READ_SIG); | 3403 | QLC_83XX_FLASH_OEM_READ_SIG); |
@@ -3379,8 +3407,11 @@ static int qlcnic_83xx_read_flash_status_reg(struct qlcnic_adapter *adapter) | |||
3379 | if (ret) | 3407 | if (ret) |
3380 | return -EIO; | 3408 | return -EIO; |
3381 | 3409 | ||
3382 | ret = qlcnic_83xx_rd_reg_indirect(adapter, QLC_83XX_FLASH_RDDATA); | 3410 | temp = QLCRD32(adapter, QLC_83XX_FLASH_RDDATA, &err); |
3383 | return ret & 0xFF; | 3411 | if (err == -EIO) |
3412 | return err; | ||
3413 | |||
3414 | return temp & 0xFF; | ||
3384 | } | 3415 | } |
3385 | 3416 | ||
3386 | int qlcnic_83xx_flash_test(struct qlcnic_adapter *adapter) | 3417 | int qlcnic_83xx_flash_test(struct qlcnic_adapter *adapter) |