diff options
-rw-r--r-- | drivers/net/qlge/qlge.h | 8 | ||||
-rw-r--r-- | drivers/net/qlge/qlge_main.c | 9 | ||||
-rw-r--r-- | drivers/net/qlge/qlge_mpi.c | 89 |
3 files changed, 106 insertions, 0 deletions
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 567b5d6e3413..e7285f01bd04 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h | |||
@@ -803,6 +803,12 @@ enum { | |||
803 | MB_CMD_SET_PORT_CFG = 0x00000122, | 803 | MB_CMD_SET_PORT_CFG = 0x00000122, |
804 | MB_CMD_GET_PORT_CFG = 0x00000123, | 804 | MB_CMD_GET_PORT_CFG = 0x00000123, |
805 | MB_CMD_GET_LINK_STS = 0x00000124, | 805 | MB_CMD_GET_LINK_STS = 0x00000124, |
806 | MB_CMD_SET_MGMNT_TFK_CTL = 0x00000160, /* Set Mgmnt Traffic Control */ | ||
807 | MB_SET_MPI_TFK_STOP = (1 << 0), | ||
808 | MB_SET_MPI_TFK_RESUME = (1 << 1), | ||
809 | MB_CMD_GET_MGMNT_TFK_CTL = 0x00000161, /* Get Mgmnt Traffic Control */ | ||
810 | MB_GET_MPI_TFK_STOPPED = (1 << 0), | ||
811 | MB_GET_MPI_TFK_FIFO_EMPTY = (1 << 1), | ||
806 | 812 | ||
807 | /* Mailbox Command Status. */ | 813 | /* Mailbox Command Status. */ |
808 | MB_CMD_STS_GOOD = 0x00004000, /* Success. */ | 814 | MB_CMD_STS_GOOD = 0x00004000, /* Success. */ |
@@ -1606,6 +1612,8 @@ int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data); | |||
1606 | int ql_mb_about_fw(struct ql_adapter *qdev); | 1612 | int ql_mb_about_fw(struct ql_adapter *qdev); |
1607 | void ql_link_on(struct ql_adapter *qdev); | 1613 | void ql_link_on(struct ql_adapter *qdev); |
1608 | void ql_link_off(struct ql_adapter *qdev); | 1614 | void ql_link_off(struct ql_adapter *qdev); |
1615 | int ql_mb_set_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 control); | ||
1616 | int ql_wait_fifo_empty(struct ql_adapter *qdev); | ||
1609 | 1617 | ||
1610 | #if 1 | 1618 | #if 1 |
1611 | #define QL_ALL_DUMP | 1619 | #define QL_ALL_DUMP |
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index e1203bf08058..fe13006b4249 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c | |||
@@ -3349,6 +3349,13 @@ static int ql_adapter_reset(struct ql_adapter *qdev) | |||
3349 | 3349 | ||
3350 | end_jiffies = jiffies + | 3350 | end_jiffies = jiffies + |
3351 | max((unsigned long)1, usecs_to_jiffies(30)); | 3351 | max((unsigned long)1, usecs_to_jiffies(30)); |
3352 | |||
3353 | /* Stop management traffic. */ | ||
3354 | ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_STOP); | ||
3355 | |||
3356 | /* Wait for the NIC and MGMNT FIFOs to empty. */ | ||
3357 | ql_wait_fifo_empty(qdev); | ||
3358 | |||
3352 | ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR); | 3359 | ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR); |
3353 | 3360 | ||
3354 | do { | 3361 | do { |
@@ -3364,6 +3371,8 @@ static int ql_adapter_reset(struct ql_adapter *qdev) | |||
3364 | status = -ETIMEDOUT; | 3371 | status = -ETIMEDOUT; |
3365 | } | 3372 | } |
3366 | 3373 | ||
3374 | /* Resume management traffic. */ | ||
3375 | ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_RESUME); | ||
3367 | return status; | 3376 | return status; |
3368 | } | 3377 | } |
3369 | 3378 | ||
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c index c2e43073047e..8810f5be7862 100644 --- a/drivers/net/qlge/qlge_mpi.c +++ b/drivers/net/qlge/qlge_mpi.c | |||
@@ -768,6 +768,95 @@ static int ql_idc_wait(struct ql_adapter *qdev) | |||
768 | return status; | 768 | return status; |
769 | } | 769 | } |
770 | 770 | ||
771 | int ql_mb_set_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 control) | ||
772 | { | ||
773 | struct mbox_params mbc; | ||
774 | struct mbox_params *mbcp = &mbc; | ||
775 | int status; | ||
776 | |||
777 | memset(mbcp, 0, sizeof(struct mbox_params)); | ||
778 | |||
779 | mbcp->in_count = 1; | ||
780 | mbcp->out_count = 2; | ||
781 | |||
782 | mbcp->mbox_in[0] = MB_CMD_SET_MGMNT_TFK_CTL; | ||
783 | mbcp->mbox_in[1] = control; | ||
784 | |||
785 | status = ql_mailbox_command(qdev, mbcp); | ||
786 | if (status) | ||
787 | return status; | ||
788 | |||
789 | if (mbcp->mbox_out[0] == MB_CMD_STS_GOOD) | ||
790 | return status; | ||
791 | |||
792 | if (mbcp->mbox_out[0] == MB_CMD_STS_INVLD_CMD) { | ||
793 | QPRINTK(qdev, DRV, ERR, | ||
794 | "Command not supported by firmware.\n"); | ||
795 | status = -EINVAL; | ||
796 | } else if (mbcp->mbox_out[0] == MB_CMD_STS_ERR) { | ||
797 | /* This indicates that the firmware is | ||
798 | * already in the state we are trying to | ||
799 | * change it to. | ||
800 | */ | ||
801 | QPRINTK(qdev, DRV, ERR, | ||
802 | "Command parameters make no change.\n"); | ||
803 | } | ||
804 | return status; | ||
805 | } | ||
806 | |||
807 | /* Returns a negative error code or the mailbox command status. */ | ||
808 | static int ql_mb_get_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 *control) | ||
809 | { | ||
810 | struct mbox_params mbc; | ||
811 | struct mbox_params *mbcp = &mbc; | ||
812 | int status; | ||
813 | |||
814 | memset(mbcp, 0, sizeof(struct mbox_params)); | ||
815 | *control = 0; | ||
816 | |||
817 | mbcp->in_count = 1; | ||
818 | mbcp->out_count = 1; | ||
819 | |||
820 | mbcp->mbox_in[0] = MB_CMD_GET_MGMNT_TFK_CTL; | ||
821 | |||
822 | status = ql_mailbox_command(qdev, mbcp); | ||
823 | if (status) | ||
824 | return status; | ||
825 | |||
826 | if (mbcp->mbox_out[0] == MB_CMD_STS_GOOD) { | ||
827 | *control = mbcp->mbox_in[1]; | ||
828 | return status; | ||
829 | } | ||
830 | |||
831 | if (mbcp->mbox_out[0] == MB_CMD_STS_INVLD_CMD) { | ||
832 | QPRINTK(qdev, DRV, ERR, | ||
833 | "Command not supported by firmware.\n"); | ||
834 | status = -EINVAL; | ||
835 | } else if (mbcp->mbox_out[0] == MB_CMD_STS_ERR) { | ||
836 | QPRINTK(qdev, DRV, ERR, | ||
837 | "Failed to get MPI traffic control.\n"); | ||
838 | status = -EIO; | ||
839 | } | ||
840 | return status; | ||
841 | } | ||
842 | |||
843 | int ql_wait_fifo_empty(struct ql_adapter *qdev) | ||
844 | { | ||
845 | int count = 5; | ||
846 | u32 mgmnt_fifo_empty; | ||
847 | u32 nic_fifo_empty; | ||
848 | |||
849 | do { | ||
850 | nic_fifo_empty = ql_read32(qdev, STS) & STS_NFE; | ||
851 | ql_mb_get_mgmnt_traffic_ctl(qdev, &mgmnt_fifo_empty); | ||
852 | mgmnt_fifo_empty &= MB_GET_MPI_TFK_FIFO_EMPTY; | ||
853 | if (nic_fifo_empty && mgmnt_fifo_empty) | ||
854 | return 0; | ||
855 | msleep(100); | ||
856 | } while (count-- > 0); | ||
857 | return -ETIMEDOUT; | ||
858 | } | ||
859 | |||
771 | /* API called in work thread context to set new TX/RX | 860 | /* API called in work thread context to set new TX/RX |
772 | * maximum frame size values to match MTU. | 861 | * maximum frame size values to match MTU. |
773 | */ | 862 | */ |