aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
diff options
context:
space:
mode:
authorShannon Nelson <shannon.nelson@intel.com>2014-07-09 03:46:09 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-07-24 06:32:40 -0400
commitcd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86c (patch)
treef83278a853151b9370e542d5092df9c2862982b8 /drivers/net/ethernet/intel/i40e/i40e_ethtool.c
parentefe1ac25d084fd56c5b809634a0444606c2a5cd3 (diff)
i40e/i40evf: Add nvmupdate support
This implements a state machine intended to support the userland tool for updating the device eeprom. The state machine implements one-shot reads, writes, multi-step write sessions, and checksum requests. If we're in the middle of a multi-step write session, no one should fire off other writes, however, one shot reads are valid. The userland tool is expected to keep track of its session status, arrange the placement and ordering of the writes, and deal with the checksum requirement. This patch also adds nvmupdate support to ethtool callbacks. The get_eeprom() and set_eeprom() services in ethtool are used here to facilitate the userland NVMUpdate tool. The 'magic' value in the get and set commands is used to pass additional control information for managing the read and write steps. The read operation works both as normally expected in the standard ethtool method, as well as with the extra NVM controls. The write operation works only for the expanded NVM functions - the normal ethtool method is not allowed because of the NVM semaphore management needed for multipart writes, as well as the checksum requirement. Change-ID: I1d84a170153a9f437906744e2e350fd68fe7563d Signed-off-by: Shannon Nelson <shannon.nelson@intel.com> Tested-by: Jim Young <jamesx.m.young@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/i40e/i40e_ethtool.c')
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_ethtool.c61
1 files changed, 59 insertions, 2 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index 3abd3cbab75f..f1d241ec1fc3 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -759,10 +759,33 @@ static int i40e_get_eeprom(struct net_device *netdev,
759 u8 *eeprom_buff; 759 u8 *eeprom_buff;
760 u16 i, sectors; 760 u16 i, sectors;
761 bool last; 761 bool last;
762 u32 magic;
763
762#define I40E_NVM_SECTOR_SIZE 4096 764#define I40E_NVM_SECTOR_SIZE 4096
763 if (eeprom->len == 0) 765 if (eeprom->len == 0)
764 return -EINVAL; 766 return -EINVAL;
765 767
768 /* check for NVMUpdate access method */
769 magic = hw->vendor_id | (hw->device_id << 16);
770 if (eeprom->magic && eeprom->magic != magic) {
771 int errno;
772
773 /* make sure it is the right magic for NVMUpdate */
774 if ((eeprom->magic >> 16) != hw->device_id)
775 return -EINVAL;
776
777 ret_val = i40e_nvmupd_command(hw,
778 (struct i40e_nvm_access *)eeprom,
779 bytes, &errno);
780 if (ret_val)
781 dev_info(&pf->pdev->dev,
782 "NVMUpdate read failed err=%d status=0x%x\n",
783 ret_val, hw->aq.asq_last_status);
784
785 return errno;
786 }
787
788 /* normal ethtool get_eeprom support */
766 eeprom->magic = hw->vendor_id | (hw->device_id << 16); 789 eeprom->magic = hw->vendor_id | (hw->device_id << 16);
767 790
768 eeprom_buff = kzalloc(eeprom->len, GFP_KERNEL); 791 eeprom_buff = kzalloc(eeprom->len, GFP_KERNEL);
@@ -789,7 +812,7 @@ static int i40e_get_eeprom(struct net_device *netdev,
789 ret_val = i40e_aq_read_nvm(hw, 0x0, 812 ret_val = i40e_aq_read_nvm(hw, 0x0,
790 eeprom->offset + (I40E_NVM_SECTOR_SIZE * i), 813 eeprom->offset + (I40E_NVM_SECTOR_SIZE * i),
791 len, 814 len,
792 eeprom_buff + (I40E_NVM_SECTOR_SIZE * i), 815 (u8 *)eeprom_buff + (I40E_NVM_SECTOR_SIZE * i),
793 last, NULL); 816 last, NULL);
794 if (ret_val) { 817 if (ret_val) {
795 dev_info(&pf->pdev->dev, 818 dev_info(&pf->pdev->dev,
@@ -801,7 +824,7 @@ static int i40e_get_eeprom(struct net_device *netdev,
801 824
802release_nvm: 825release_nvm:
803 i40e_release_nvm(hw); 826 i40e_release_nvm(hw);
804 memcpy(bytes, eeprom_buff, eeprom->len); 827 memcpy(bytes, (u8 *)eeprom_buff, eeprom->len);
805free_buff: 828free_buff:
806 kfree(eeprom_buff); 829 kfree(eeprom_buff);
807 return ret_val; 830 return ret_val;
@@ -821,6 +844,39 @@ static int i40e_get_eeprom_len(struct net_device *netdev)
821 return val; 844 return val;
822} 845}
823 846
847static int i40e_set_eeprom(struct net_device *netdev,
848 struct ethtool_eeprom *eeprom, u8 *bytes)
849{
850 struct i40e_netdev_priv *np = netdev_priv(netdev);
851 struct i40e_hw *hw = &np->vsi->back->hw;
852 struct i40e_pf *pf = np->vsi->back;
853 int ret_val = 0;
854 int errno;
855 u32 magic;
856
857 /* normal ethtool set_eeprom is not supported */
858 magic = hw->vendor_id | (hw->device_id << 16);
859 if (eeprom->magic == magic)
860 return -EOPNOTSUPP;
861
862 /* check for NVMUpdate access method */
863 if (!eeprom->magic || (eeprom->magic >> 16) != hw->device_id)
864 return -EINVAL;
865
866 if (test_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state) ||
867 test_bit(__I40E_RESET_INTR_RECEIVED, &pf->state))
868 return -EBUSY;
869
870 ret_val = i40e_nvmupd_command(hw, (struct i40e_nvm_access *)eeprom,
871 bytes, &errno);
872 if (ret_val)
873 dev_info(&pf->pdev->dev,
874 "NVMUpdate write failed err=%d status=0x%x\n",
875 ret_val, hw->aq.asq_last_status);
876
877 return errno;
878}
879
824static void i40e_get_drvinfo(struct net_device *netdev, 880static void i40e_get_drvinfo(struct net_device *netdev,
825 struct ethtool_drvinfo *drvinfo) 881 struct ethtool_drvinfo *drvinfo)
826{ 882{
@@ -2094,6 +2150,7 @@ static const struct ethtool_ops i40e_ethtool_ops = {
2094 .get_link = ethtool_op_get_link, 2150 .get_link = ethtool_op_get_link,
2095 .get_wol = i40e_get_wol, 2151 .get_wol = i40e_get_wol,
2096 .set_wol = i40e_set_wol, 2152 .set_wol = i40e_set_wol,
2153 .set_eeprom = i40e_set_eeprom,
2097 .get_eeprom_len = i40e_get_eeprom_len, 2154 .get_eeprom_len = i40e_get_eeprom_len,
2098 .get_eeprom = i40e_get_eeprom, 2155 .get_eeprom = i40e_get_eeprom,
2099 .get_ringparam = i40e_get_ringparam, 2156 .get_ringparam = i40e_get_ringparam,