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

[PATCH] S2io: Offline diagnostics fixes

This patch fixes the following bugs with offline diagnostics
code(run with "ethtool -t").

1. After running offline diagnostics, adapter would report
corrupted packets on receive. This was because of adapter not
being brought out of "RLDRAM test mode".
2. Current EEPROM test works only for Xframe I. Since Xframe II
uses different interface(SPI), support for this interface has
been added. Also, since SPI supports write access to all areas
of EEPROM, negative testing is done only for Xframe I.
3. Return values from subfunctions of offline diagnostics have
been corrected.
4. In register test, expected value from rx_queue_cfg register
is made to depend on adapter type.
5. After the test, need to restore values at EEPROM offsets
0x4F0 and 0x7F0. These locations were modified as part of test.
6. Use macro SPECIAL_REG_WRITE for write access to mc_rldram_test_ctrl
register. Also, couple of unnecessary writes to mc_rldram_test_ctrl
have been removed.

Signed-off-by: Ravinandan Arakali <ravinandan.arakali@neterion.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>

authored by

ravinandan.arakali@neterion.com and committed by
Jeff Garzik
ad4ebed0 59aee3c2

+164 -82
+11
drivers/net/s2io-regs.h
··· 814 814 u64 rxgxs_ber_0; /* CHANGED */ 815 815 u64 rxgxs_ber_1; /* CHANGED */ 816 816 817 + u64 spi_control; 818 + #define SPI_CONTROL_KEY(key) vBIT(key,0,4) 819 + #define SPI_CONTROL_BYTECNT(cnt) vBIT(cnt,29,3) 820 + #define SPI_CONTROL_CMD(cmd) vBIT(cmd,32,8) 821 + #define SPI_CONTROL_ADDR(addr) vBIT(addr,40,24) 822 + #define SPI_CONTROL_SEL1 BIT(4) 823 + #define SPI_CONTROL_REQ BIT(7) 824 + #define SPI_CONTROL_NACK BIT(5) 825 + #define SPI_CONTROL_DONE BIT(6) 826 + u64 spi_data; 827 + #define SPI_DATA_WRITE(data,len) vBIT(data,0,len) 817 828 } XENA_dev_config_t; 818 829 819 830 #define XENA_REG_SPACE sizeof(XENA_dev_config_t)
+153 -82
drivers/net/s2io.c
··· 4378 4378 */ 4379 4379 4380 4380 #define S2IO_DEV_ID 5 4381 - static int read_eeprom(nic_t * sp, int off, u32 * data) 4381 + static int read_eeprom(nic_t * sp, int off, u64 * data) 4382 4382 { 4383 4383 int ret = -1; 4384 4384 u32 exit_cnt = 0; 4385 4385 u64 val64; 4386 4386 XENA_dev_config_t __iomem *bar0 = sp->bar0; 4387 4387 4388 - val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) | 4389 - I2C_CONTROL_BYTE_CNT(0x3) | I2C_CONTROL_READ | 4390 - I2C_CONTROL_CNTL_START; 4391 - SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF); 4388 + if (sp->device_type == XFRAME_I_DEVICE) { 4389 + val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) | 4390 + I2C_CONTROL_BYTE_CNT(0x3) | I2C_CONTROL_READ | 4391 + I2C_CONTROL_CNTL_START; 4392 + SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF); 4392 4393 4393 - while (exit_cnt < 5) { 4394 - val64 = readq(&bar0->i2c_control); 4395 - if (I2C_CONTROL_CNTL_END(val64)) { 4396 - *data = I2C_CONTROL_GET_DATA(val64); 4397 - ret = 0; 4398 - break; 4394 + while (exit_cnt < 5) { 4395 + val64 = readq(&bar0->i2c_control); 4396 + if (I2C_CONTROL_CNTL_END(val64)) { 4397 + *data = I2C_CONTROL_GET_DATA(val64); 4398 + ret = 0; 4399 + break; 4400 + } 4401 + msleep(50); 4402 + exit_cnt++; 4399 4403 } 4400 - msleep(50); 4401 - exit_cnt++; 4402 4404 } 4403 4405 4406 + if (sp->device_type == XFRAME_II_DEVICE) { 4407 + val64 = SPI_CONTROL_KEY(0x9) | SPI_CONTROL_SEL1 | 4408 + SPI_CONTROL_BYTECNT(0x3) | 4409 + SPI_CONTROL_CMD(0x3) | SPI_CONTROL_ADDR(off); 4410 + SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF); 4411 + val64 |= SPI_CONTROL_REQ; 4412 + SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF); 4413 + while (exit_cnt < 5) { 4414 + val64 = readq(&bar0->spi_control); 4415 + if (val64 & SPI_CONTROL_NACK) { 4416 + ret = 1; 4417 + break; 4418 + } else if (val64 & SPI_CONTROL_DONE) { 4419 + *data = readq(&bar0->spi_data); 4420 + *data &= 0xffffff; 4421 + ret = 0; 4422 + break; 4423 + } 4424 + msleep(50); 4425 + exit_cnt++; 4426 + } 4427 + } 4404 4428 return ret; 4405 4429 } 4406 4430 ··· 4443 4419 * 0 on success, -1 on failure. 4444 4420 */ 4445 4421 4446 - static int write_eeprom(nic_t * sp, int off, u32 data, int cnt) 4422 + static int write_eeprom(nic_t * sp, int off, u64 data, int cnt) 4447 4423 { 4448 4424 int exit_cnt = 0, ret = -1; 4449 4425 u64 val64; 4450 4426 XENA_dev_config_t __iomem *bar0 = sp->bar0; 4451 4427 4452 - val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) | 4453 - I2C_CONTROL_BYTE_CNT(cnt) | I2C_CONTROL_SET_DATA(data) | 4454 - I2C_CONTROL_CNTL_START; 4455 - SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF); 4428 + if (sp->device_type == XFRAME_I_DEVICE) { 4429 + val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) | 4430 + I2C_CONTROL_BYTE_CNT(cnt) | I2C_CONTROL_SET_DATA((u32)data) | 4431 + I2C_CONTROL_CNTL_START; 4432 + SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF); 4456 4433 4457 - while (exit_cnt < 5) { 4458 - val64 = readq(&bar0->i2c_control); 4459 - if (I2C_CONTROL_CNTL_END(val64)) { 4460 - if (!(val64 & I2C_CONTROL_NACK)) 4461 - ret = 0; 4462 - break; 4434 + while (exit_cnt < 5) { 4435 + val64 = readq(&bar0->i2c_control); 4436 + if (I2C_CONTROL_CNTL_END(val64)) { 4437 + if (!(val64 & I2C_CONTROL_NACK)) 4438 + ret = 0; 4439 + break; 4440 + } 4441 + msleep(50); 4442 + exit_cnt++; 4463 4443 } 4464 - msleep(50); 4465 - exit_cnt++; 4466 4444 } 4467 4445 4446 + if (sp->device_type == XFRAME_II_DEVICE) { 4447 + int write_cnt = (cnt == 8) ? 0 : cnt; 4448 + writeq(SPI_DATA_WRITE(data,(cnt<<3)), &bar0->spi_data); 4449 + 4450 + val64 = SPI_CONTROL_KEY(0x9) | SPI_CONTROL_SEL1 | 4451 + SPI_CONTROL_BYTECNT(write_cnt) | 4452 + SPI_CONTROL_CMD(0x2) | SPI_CONTROL_ADDR(off); 4453 + SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF); 4454 + val64 |= SPI_CONTROL_REQ; 4455 + SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF); 4456 + while (exit_cnt < 5) { 4457 + val64 = readq(&bar0->spi_control); 4458 + if (val64 & SPI_CONTROL_NACK) { 4459 + ret = 1; 4460 + break; 4461 + } else if (val64 & SPI_CONTROL_DONE) { 4462 + ret = 0; 4463 + break; 4464 + } 4465 + msleep(50); 4466 + exit_cnt++; 4467 + } 4468 + } 4468 4469 return ret; 4469 4470 } 4470 4471 ··· 4509 4460 static int s2io_ethtool_geeprom(struct net_device *dev, 4510 4461 struct ethtool_eeprom *eeprom, u8 * data_buf) 4511 4462 { 4512 - u32 data, i, valid; 4463 + u32 i, valid; 4464 + u64 data; 4513 4465 nic_t *sp = dev->priv; 4514 4466 4515 4467 eeprom->magic = sp->pdev->vendor | (sp->pdev->device << 16); ··· 4548 4498 u8 * data_buf) 4549 4499 { 4550 4500 int len = eeprom->len, cnt = 0; 4551 - u32 valid = 0, data; 4501 + u64 valid = 0, data; 4552 4502 nic_t *sp = dev->priv; 4553 4503 4554 4504 if (eeprom->magic != (sp->pdev->vendor | (sp->pdev->device << 16))) { ··· 4596 4546 static int s2io_register_test(nic_t * sp, uint64_t * data) 4597 4547 { 4598 4548 XENA_dev_config_t __iomem *bar0 = sp->bar0; 4599 - u64 val64 = 0; 4549 + u64 val64 = 0, exp_val; 4600 4550 int fail = 0; 4601 4551 4602 4552 val64 = readq(&bar0->pif_rd_swapper_fb); ··· 4612 4562 } 4613 4563 4614 4564 val64 = readq(&bar0->rx_queue_cfg); 4615 - if (val64 != 0x0808080808080808ULL) { 4565 + if (sp->device_type == XFRAME_II_DEVICE) 4566 + exp_val = 0x0404040404040404ULL; 4567 + else 4568 + exp_val = 0x0808080808080808ULL; 4569 + if (val64 != exp_val) { 4616 4570 fail = 1; 4617 4571 DBG_PRINT(INFO_DBG, "Read Test level 3 fails\n"); 4618 4572 } ··· 4644 4590 } 4645 4591 4646 4592 *data = fail; 4647 - return 0; 4593 + return fail; 4648 4594 } 4649 4595 4650 4596 /** ··· 4663 4609 static int s2io_eeprom_test(nic_t * sp, uint64_t * data) 4664 4610 { 4665 4611 int fail = 0; 4666 - u32 ret_data; 4612 + u64 ret_data, org_4F0, org_7F0; 4613 + u8 saved_4F0 = 0, saved_7F0 = 0; 4614 + struct net_device *dev = sp->dev; 4667 4615 4668 4616 /* Test Write Error at offset 0 */ 4669 - if (!write_eeprom(sp, 0, 0, 3)) 4670 - fail = 1; 4617 + /* Note that SPI interface allows write access to all areas 4618 + * of EEPROM. Hence doing all negative testing only for Xframe I. 4619 + */ 4620 + if (sp->device_type == XFRAME_I_DEVICE) 4621 + if (!write_eeprom(sp, 0, 0, 3)) 4622 + fail = 1; 4623 + 4624 + /* Save current values at offsets 0x4F0 and 0x7F0 */ 4625 + if (!read_eeprom(sp, 0x4F0, &org_4F0)) 4626 + saved_4F0 = 1; 4627 + if (!read_eeprom(sp, 0x7F0, &org_7F0)) 4628 + saved_7F0 = 1; 4671 4629 4672 4630 /* Test Write at offset 4f0 */ 4673 - if (write_eeprom(sp, 0x4F0, 0x01234567, 3)) 4631 + if (write_eeprom(sp, 0x4F0, 0x012345, 3)) 4674 4632 fail = 1; 4675 4633 if (read_eeprom(sp, 0x4F0, &ret_data)) 4676 4634 fail = 1; 4677 4635 4678 - if (ret_data != 0x01234567) 4636 + if (ret_data != 0x012345) { 4637 + DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x4F0. Data written %llx Data read %llx\n", dev->name, (u64)0x12345, ret_data); 4679 4638 fail = 1; 4639 + } 4680 4640 4681 4641 /* Reset the EEPROM data go FFFF */ 4682 - write_eeprom(sp, 0x4F0, 0xFFFFFFFF, 3); 4642 + write_eeprom(sp, 0x4F0, 0xFFFFFF, 3); 4683 4643 4684 4644 /* Test Write Request Error at offset 0x7c */ 4685 - if (!write_eeprom(sp, 0x07C, 0, 3)) 4645 + if (sp->device_type == XFRAME_I_DEVICE) 4646 + if (!write_eeprom(sp, 0x07C, 0, 3)) 4647 + fail = 1; 4648 + 4649 + /* Test Write Request at offset 0x7f0 */ 4650 + if (write_eeprom(sp, 0x7F0, 0x012345, 3)) 4651 + fail = 1; 4652 + if (read_eeprom(sp, 0x7F0, &ret_data)) 4686 4653 fail = 1; 4687 4654 4688 - /* Test Write Request at offset 0x7fc */ 4689 - if (write_eeprom(sp, 0x7FC, 0x01234567, 3)) 4655 + if (ret_data != 0x012345) { 4656 + DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x7F0. Data written %llx Data read %llx\n", dev->name, (u64)0x12345, ret_data); 4690 4657 fail = 1; 4691 - if (read_eeprom(sp, 0x7FC, &ret_data)) 4692 - fail = 1; 4693 - 4694 - if (ret_data != 0x01234567) 4695 - fail = 1; 4658 + } 4696 4659 4697 4660 /* Reset the EEPROM data go FFFF */ 4698 - write_eeprom(sp, 0x7FC, 0xFFFFFFFF, 3); 4661 + write_eeprom(sp, 0x7F0, 0xFFFFFF, 3); 4699 4662 4700 - /* Test Write Error at offset 0x80 */ 4701 - if (!write_eeprom(sp, 0x080, 0, 3)) 4702 - fail = 1; 4663 + if (sp->device_type == XFRAME_I_DEVICE) { 4664 + /* Test Write Error at offset 0x80 */ 4665 + if (!write_eeprom(sp, 0x080, 0, 3)) 4666 + fail = 1; 4703 4667 4704 - /* Test Write Error at offset 0xfc */ 4705 - if (!write_eeprom(sp, 0x0FC, 0, 3)) 4706 - fail = 1; 4668 + /* Test Write Error at offset 0xfc */ 4669 + if (!write_eeprom(sp, 0x0FC, 0, 3)) 4670 + fail = 1; 4707 4671 4708 - /* Test Write Error at offset 0x100 */ 4709 - if (!write_eeprom(sp, 0x100, 0, 3)) 4710 - fail = 1; 4672 + /* Test Write Error at offset 0x100 */ 4673 + if (!write_eeprom(sp, 0x100, 0, 3)) 4674 + fail = 1; 4711 4675 4712 - /* Test Write Error at offset 4ec */ 4713 - if (!write_eeprom(sp, 0x4EC, 0, 3)) 4714 - fail = 1; 4676 + /* Test Write Error at offset 4ec */ 4677 + if (!write_eeprom(sp, 0x4EC, 0, 3)) 4678 + fail = 1; 4679 + } 4680 + 4681 + /* Restore values at offsets 0x4F0 and 0x7F0 */ 4682 + if (saved_4F0) 4683 + write_eeprom(sp, 0x4F0, org_4F0, 3); 4684 + if (saved_7F0) 4685 + write_eeprom(sp, 0x7F0, org_7F0, 3); 4715 4686 4716 4687 *data = fail; 4717 - return 0; 4688 + return fail; 4718 4689 } 4719 4690 4720 4691 /** ··· 4821 4742 { 4822 4743 XENA_dev_config_t __iomem *bar0 = sp->bar0; 4823 4744 u64 val64; 4824 - int cnt, iteration = 0, test_pass = 0; 4745 + int cnt, iteration = 0, test_fail = 0; 4825 4746 4826 4747 val64 = readq(&bar0->adapter_control); 4827 4748 val64 &= ~ADAPTER_ECC_EN; ··· 4829 4750 4830 4751 val64 = readq(&bar0->mc_rldram_test_ctrl); 4831 4752 val64 |= MC_RLDRAM_TEST_MODE; 4832 - writeq(val64, &bar0->mc_rldram_test_ctrl); 4753 + SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF); 4833 4754 4834 4755 val64 = readq(&bar0->mc_rldram_mrs); 4835 4756 val64 |= MC_RLDRAM_QUEUE_SIZE_ENABLE; ··· 4857 4778 } 4858 4779 writeq(val64, &bar0->mc_rldram_test_d2); 4859 4780 4860 - val64 = (u64) (0x0000003fffff0000ULL); 4781 + val64 = (u64) (0x0000003ffffe0100ULL); 4861 4782 writeq(val64, &bar0->mc_rldram_test_add); 4862 4783 4863 - 4864 - val64 = MC_RLDRAM_TEST_MODE; 4865 - writeq(val64, &bar0->mc_rldram_test_ctrl); 4866 - 4867 - val64 |= 4868 - MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_WRITE | 4869 - MC_RLDRAM_TEST_GO; 4870 - writeq(val64, &bar0->mc_rldram_test_ctrl); 4784 + val64 = MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_WRITE | 4785 + MC_RLDRAM_TEST_GO; 4786 + SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF); 4871 4787 4872 4788 for (cnt = 0; cnt < 5; cnt++) { 4873 4789 val64 = readq(&bar0->mc_rldram_test_ctrl); ··· 4874 4800 if (cnt == 5) 4875 4801 break; 4876 4802 4877 - val64 = MC_RLDRAM_TEST_MODE; 4878 - writeq(val64, &bar0->mc_rldram_test_ctrl); 4879 - 4880 - val64 |= MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_GO; 4881 - writeq(val64, &bar0->mc_rldram_test_ctrl); 4803 + val64 = MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_GO; 4804 + SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF); 4882 4805 4883 4806 for (cnt = 0; cnt < 5; cnt++) { 4884 4807 val64 = readq(&bar0->mc_rldram_test_ctrl); ··· 4888 4817 break; 4889 4818 4890 4819 val64 = readq(&bar0->mc_rldram_test_ctrl); 4891 - if (val64 & MC_RLDRAM_TEST_PASS) 4892 - test_pass = 1; 4820 + if (!(val64 & MC_RLDRAM_TEST_PASS)) 4821 + test_fail = 1; 4893 4822 4894 4823 iteration++; 4895 4824 } 4896 4825 4897 - if (!test_pass) 4898 - *data = 1; 4899 - else 4900 - *data = 0; 4826 + *data = test_fail; 4901 4827 4902 - return 0; 4828 + /* Bring the adapter out of test mode */ 4829 + SPECIAL_REG_WRITE(0, &bar0->mc_rldram_test_ctrl, LF); 4830 + 4831 + return test_fail; 4903 4832 } 4904 4833 4905 4834 /**