aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2011-08-26 03:45:52 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-10-08 01:45:46 -0400
commit4be000c874576541cd1d4d0498a0a72a1c60bf0b (patch)
tree31b4e5467e9189a5475df028d0211b3540bff7a9 /drivers/net/ethernet/intel
parent0ba829943c5180d458cd8fc37c37fa08773209e1 (diff)
igb: cleanup IVAR configuration
This change is meant to cleanup some of the IVAR register configuration. igb_assign_vector had become pretty large with multiple copies of the same general code for setting the IVAR. This change consolidates most of that code by adding the igb_write_ivar function which allows us just to compute the index and offset and then use that information to setup the IVAR. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel')
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c120
1 files changed, 56 insertions, 64 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 8dc04e0e0a04..ec715f45a449 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -754,15 +754,40 @@ err:
754 return -ENOMEM; 754 return -ENOMEM;
755} 755}
756 756
757/**
758 * igb_write_ivar - configure ivar for given MSI-X vector
759 * @hw: pointer to the HW structure
760 * @msix_vector: vector number we are allocating to a given ring
761 * @index: row index of IVAR register to write within IVAR table
762 * @offset: column offset of in IVAR, should be multiple of 8
763 *
764 * This function is intended to handle the writing of the IVAR register
765 * for adapters 82576 and newer. The IVAR table consists of 2 columns,
766 * each containing an cause allocation for an Rx and Tx ring, and a
767 * variable number of rows depending on the number of queues supported.
768 **/
769static void igb_write_ivar(struct e1000_hw *hw, int msix_vector,
770 int index, int offset)
771{
772 u32 ivar = array_rd32(E1000_IVAR0, index);
773
774 /* clear any bits that are currently set */
775 ivar &= ~((u32)0xFF << offset);
776
777 /* write vector and valid bit */
778 ivar |= (msix_vector | E1000_IVAR_VALID) << offset;
779
780 array_wr32(E1000_IVAR0, index, ivar);
781}
782
757#define IGB_N0_QUEUE -1 783#define IGB_N0_QUEUE -1
758static void igb_assign_vector(struct igb_q_vector *q_vector, int msix_vector) 784static void igb_assign_vector(struct igb_q_vector *q_vector, int msix_vector)
759{ 785{
760 u32 msixbm = 0;
761 struct igb_adapter *adapter = q_vector->adapter; 786 struct igb_adapter *adapter = q_vector->adapter;
762 struct e1000_hw *hw = &adapter->hw; 787 struct e1000_hw *hw = &adapter->hw;
763 u32 ivar, index;
764 int rx_queue = IGB_N0_QUEUE; 788 int rx_queue = IGB_N0_QUEUE;
765 int tx_queue = IGB_N0_QUEUE; 789 int tx_queue = IGB_N0_QUEUE;
790 u32 msixbm = 0;
766 791
767 if (q_vector->rx.ring) 792 if (q_vector->rx.ring)
768 rx_queue = q_vector->rx.ring->reg_idx; 793 rx_queue = q_vector->rx.ring->reg_idx;
@@ -785,72 +810,39 @@ static void igb_assign_vector(struct igb_q_vector *q_vector, int msix_vector)
785 q_vector->eims_value = msixbm; 810 q_vector->eims_value = msixbm;
786 break; 811 break;
787 case e1000_82576: 812 case e1000_82576:
788 /* 82576 uses a table-based method for assigning vectors. 813 /*
789 Each queue has a single entry in the table to which we write 814 * 82576 uses a table that essentially consists of 2 columns
790 a vector number along with a "valid" bit. Sadly, the layout 815 * with 8 rows. The ordering is column-major so we use the
791 of the table is somewhat counterintuitive. */ 816 * lower 3 bits as the row index, and the 4th bit as the
792 if (rx_queue > IGB_N0_QUEUE) { 817 * column offset.
793 index = (rx_queue & 0x7); 818 */
794 ivar = array_rd32(E1000_IVAR0, index); 819 if (rx_queue > IGB_N0_QUEUE)
795 if (rx_queue < 8) { 820 igb_write_ivar(hw, msix_vector,
796 /* vector goes into low byte of register */ 821 rx_queue & 0x7,
797 ivar = ivar & 0xFFFFFF00; 822 (rx_queue & 0x8) << 1);
798 ivar |= msix_vector | E1000_IVAR_VALID; 823 if (tx_queue > IGB_N0_QUEUE)
799 } else { 824 igb_write_ivar(hw, msix_vector,
800 /* vector goes into third byte of register */ 825 tx_queue & 0x7,
801 ivar = ivar & 0xFF00FFFF; 826 ((tx_queue & 0x8) << 1) + 8);
802 ivar |= (msix_vector | E1000_IVAR_VALID) << 16;
803 }
804 array_wr32(E1000_IVAR0, index, ivar);
805 }
806 if (tx_queue > IGB_N0_QUEUE) {
807 index = (tx_queue & 0x7);
808 ivar = array_rd32(E1000_IVAR0, index);
809 if (tx_queue < 8) {
810 /* vector goes into second byte of register */
811 ivar = ivar & 0xFFFF00FF;
812 ivar |= (msix_vector | E1000_IVAR_VALID) << 8;
813 } else {
814 /* vector goes into high byte of register */
815 ivar = ivar & 0x00FFFFFF;
816 ivar |= (msix_vector | E1000_IVAR_VALID) << 24;
817 }
818 array_wr32(E1000_IVAR0, index, ivar);
819 }
820 q_vector->eims_value = 1 << msix_vector; 827 q_vector->eims_value = 1 << msix_vector;
821 break; 828 break;
822 case e1000_82580: 829 case e1000_82580:
823 case e1000_i350: 830 case e1000_i350:
824 /* 82580 uses the same table-based approach as 82576 but has fewer 831 /*
825 entries as a result we carry over for queues greater than 4. */ 832 * On 82580 and newer adapters the scheme is similar to 82576
826 if (rx_queue > IGB_N0_QUEUE) { 833 * however instead of ordering column-major we have things
827 index = (rx_queue >> 1); 834 * ordered row-major. So we traverse the table by using
828 ivar = array_rd32(E1000_IVAR0, index); 835 * bit 0 as the column offset, and the remaining bits as the
829 if (rx_queue & 0x1) { 836 * row index.
830 /* vector goes into third byte of register */ 837 */
831 ivar = ivar & 0xFF00FFFF; 838 if (rx_queue > IGB_N0_QUEUE)
832 ivar |= (msix_vector | E1000_IVAR_VALID) << 16; 839 igb_write_ivar(hw, msix_vector,
833 } else { 840 rx_queue >> 1,
834 /* vector goes into low byte of register */ 841 (rx_queue & 0x1) << 4);
835 ivar = ivar & 0xFFFFFF00; 842 if (tx_queue > IGB_N0_QUEUE)
836 ivar |= msix_vector | E1000_IVAR_VALID; 843 igb_write_ivar(hw, msix_vector,
837 } 844 tx_queue >> 1,
838 array_wr32(E1000_IVAR0, index, ivar); 845 ((tx_queue & 0x1) << 4) + 8);
839 }
840 if (tx_queue > IGB_N0_QUEUE) {
841 index = (tx_queue >> 1);
842 ivar = array_rd32(E1000_IVAR0, index);
843 if (tx_queue & 0x1) {
844 /* vector goes into high byte of register */
845 ivar = ivar & 0x00FFFFFF;
846 ivar |= (msix_vector | E1000_IVAR_VALID) << 24;
847 } else {
848 /* vector goes into second byte of register */
849 ivar = ivar & 0xFFFF00FF;
850 ivar |= (msix_vector | E1000_IVAR_VALID) << 8;
851 }
852 array_wr32(E1000_IVAR0, index, ivar);
853 }
854 q_vector->eims_value = 1 << msix_vector; 846 q_vector->eims_value = 1 << msix_vector;
855 break; 847 break;
856 default: 848 default: