i40e_lan_hmc.c (266423) | i40e_lan_hmc.c (269198) |
---|---|
1/****************************************************************************** 2 3 Copyright (c) 2013-2014, Intel Corporation 4 All rights reserved. 5 6 Redistribution and use in source and binary forms, with or without 7 modification, are permitted provided that the following conditions are met: 8 --- 16 unchanged lines hidden (view full) --- 25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 POSSIBILITY OF SUCH DAMAGE. 31 32******************************************************************************/ | 1/****************************************************************************** 2 3 Copyright (c) 2013-2014, Intel Corporation 4 All rights reserved. 5 6 Redistribution and use in source and binary forms, with or without 7 modification, are permitted provided that the following conditions are met: 8 --- 16 unchanged lines hidden (view full) --- 25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 POSSIBILITY OF SUCH DAMAGE. 31 32******************************************************************************/ |
33/*$FreeBSD: head/sys/dev/i40e/i40e_lan_hmc.c 266423 2014-05-19 01:21:02Z jfv $*/ | 33/*$FreeBSD: head/sys/dev/i40e/i40e_lan_hmc.c 269198 2014-07-28 21:57:09Z jfv $*/ |
34 35#include "i40e_osdep.h" 36#include "i40e_register.h" 37#include "i40e_type.h" 38#include "i40e_hmc.h" 39#include "i40e_lan_hmc.h" 40#include "i40e_prototype.h" 41 --- 378 unchanged lines hidden (view full) --- 420 break; 421 case I40E_SD_TYPE_DIRECT: 422 I40E_SET_PF_SD_ENTRY(hw, sd_entry->u.bp.addr.pa, 423 j, sd_entry->entry_type); 424 break; 425 default: 426 ret_code = I40E_ERR_INVALID_SD_TYPE; 427 goto exit; | 34 35#include "i40e_osdep.h" 36#include "i40e_register.h" 37#include "i40e_type.h" 38#include "i40e_hmc.h" 39#include "i40e_lan_hmc.h" 40#include "i40e_prototype.h" 41 --- 378 unchanged lines hidden (view full) --- 420 break; 421 case I40E_SD_TYPE_DIRECT: 422 I40E_SET_PF_SD_ENTRY(hw, sd_entry->u.bp.addr.pa, 423 j, sd_entry->entry_type); 424 break; 425 default: 426 ret_code = I40E_ERR_INVALID_SD_TYPE; 427 goto exit; |
428 break; | |
429 } 430 } 431 } 432 goto exit; 433 434exit_sd_error: 435 /* cleanup for sd entries from j to sd_idx */ 436 while (j && (j > sd_idx)) { --- 68 unchanged lines hidden (view full) --- 505 goto configure_lan_hmc_out; 506 break; 507 default: 508 /* unsupported type */ 509 ret_code = I40E_ERR_INVALID_SD_TYPE; 510 DEBUGOUT1("i40e_configure_lan_hmc: Unknown SD type: %d\n", 511 ret_code); 512 goto configure_lan_hmc_out; | 428 } 429 } 430 } 431 goto exit; 432 433exit_sd_error: 434 /* cleanup for sd entries from j to sd_idx */ 435 while (j && (j > sd_idx)) { --- 68 unchanged lines hidden (view full) --- 504 goto configure_lan_hmc_out; 505 break; 506 default: 507 /* unsupported type */ 508 ret_code = I40E_ERR_INVALID_SD_TYPE; 509 DEBUGOUT1("i40e_configure_lan_hmc: Unknown SD type: %d\n", 510 ret_code); 511 goto configure_lan_hmc_out; |
513 break; | |
514 } 515 516 /* Configure and program the FPM registers so objects can be created */ 517 518 /* Tx contexts */ 519 obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_TX]; 520 wr32(hw, I40E_GLHMC_LANTXBASE(hmc_fn_id), 521 (u32)((obj->base & I40E_GLHMC_LANTXBASE_FPMLANTXBASE_MASK) / 512)); --- 228 unchanged lines hidden (view full) --- 750 { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphdata_ena), 1, 195 }, 751 { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphhead_ena), 1, 196 }, 752 { I40E_HMC_STORE(i40e_hmc_obj_rxq, lrxqthresh), 3, 198 }, 753 { I40E_HMC_STORE(i40e_hmc_obj_rxq, prefena), 1, 201 }, 754 { 0 } 755}; 756 757/** | 512 } 513 514 /* Configure and program the FPM registers so objects can be created */ 515 516 /* Tx contexts */ 517 obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_TX]; 518 wr32(hw, I40E_GLHMC_LANTXBASE(hmc_fn_id), 519 (u32)((obj->base & I40E_GLHMC_LANTXBASE_FPMLANTXBASE_MASK) / 512)); --- 228 unchanged lines hidden (view full) --- 748 { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphdata_ena), 1, 195 }, 749 { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphhead_ena), 1, 196 }, 750 { I40E_HMC_STORE(i40e_hmc_obj_rxq, lrxqthresh), 3, 198 }, 751 { I40E_HMC_STORE(i40e_hmc_obj_rxq, prefena), 1, 201 }, 752 { 0 } 753}; 754 755/** |
758 * i40e_get_hmc_context - extract HMC context bits 759 * @context_bytes: pointer to the context bit array | 756 * i40e_write_byte - replace HMC context byte 757 * @hmc_bits: pointer to the HMC memory 758 * @ce_info: a description of the struct to be read from 759 * @src: the struct to be read from 760 **/ 761static void i40e_write_byte(u8 *hmc_bits, 762 struct i40e_context_ele *ce_info, 763 u8 *src) 764{ 765 u8 src_byte, dest_byte, mask; 766 u8 *from, *dest; 767 u16 shift_width; 768 769 /* copy from the next struct field */ 770 from = src + ce_info->offset; 771 772 /* prepare the bits and mask */ 773 shift_width = ce_info->lsb % 8; 774 mask = ((u8)1 << ce_info->width) - 1; 775 776 src_byte = *from; 777 src_byte &= mask; 778 779 /* shift to correct alignment */ 780 mask <<= shift_width; 781 src_byte <<= shift_width; 782 783 /* get the current bits from the target bit string */ 784 dest = hmc_bits + (ce_info->lsb / 8); 785 786 i40e_memcpy(&dest_byte, dest, sizeof(dest_byte), I40E_DMA_TO_NONDMA); 787 788 dest_byte &= ~mask; /* get the bits not changing */ 789 dest_byte |= src_byte; /* add in the new bits */ 790 791 /* put it all back */ 792 i40e_memcpy(dest, &dest_byte, sizeof(dest_byte), I40E_NONDMA_TO_DMA); 793} 794 795/** 796 * i40e_write_word - replace HMC context word 797 * @hmc_bits: pointer to the HMC memory 798 * @ce_info: a description of the struct to be read from 799 * @src: the struct to be read from 800 **/ 801static void i40e_write_word(u8 *hmc_bits, 802 struct i40e_context_ele *ce_info, 803 u8 *src) 804{ 805 u16 src_word, mask; 806 u8 *from, *dest; 807 u16 shift_width; 808 __le16 dest_word; 809 810 /* copy from the next struct field */ 811 from = src + ce_info->offset; 812 813 /* prepare the bits and mask */ 814 shift_width = ce_info->lsb % 8; 815 mask = ((u16)1 << ce_info->width) - 1; 816 817 /* don't swizzle the bits until after the mask because the mask bits 818 * will be in a different bit position on big endian machines 819 */ 820 src_word = *(u16 *)from; 821 src_word &= mask; 822 823 /* shift to correct alignment */ 824 mask <<= shift_width; 825 src_word <<= shift_width; 826 827 /* get the current bits from the target bit string */ 828 dest = hmc_bits + (ce_info->lsb / 8); 829 830 i40e_memcpy(&dest_word, dest, sizeof(dest_word), I40E_DMA_TO_NONDMA); 831 832 dest_word &= ~(CPU_TO_LE16(mask)); /* get the bits not changing */ 833 dest_word |= CPU_TO_LE16(src_word); /* add in the new bits */ 834 835 /* put it all back */ 836 i40e_memcpy(dest, &dest_word, sizeof(dest_word), I40E_NONDMA_TO_DMA); 837} 838 839/** 840 * i40e_write_dword - replace HMC context dword 841 * @hmc_bits: pointer to the HMC memory 842 * @ce_info: a description of the struct to be read from 843 * @src: the struct to be read from 844 **/ 845static void i40e_write_dword(u8 *hmc_bits, 846 struct i40e_context_ele *ce_info, 847 u8 *src) 848{ 849 u32 src_dword, mask; 850 u8 *from, *dest; 851 u16 shift_width; 852 __le32 dest_dword; 853 854 /* copy from the next struct field */ 855 from = src + ce_info->offset; 856 857 /* prepare the bits and mask */ 858 shift_width = ce_info->lsb % 8; 859 860 /* if the field width is exactly 32 on an x86 machine, then the shift 861 * operation will not work because the SHL instructions count is masked 862 * to 5 bits so the shift will do nothing 863 */ 864 if (ce_info->width < 32) 865 mask = ((u32)1 << ce_info->width) - 1; 866 else 867 mask = 0xFFFFFFFF; 868 869 /* don't swizzle the bits until after the mask because the mask bits 870 * will be in a different bit position on big endian machines 871 */ 872 src_dword = *(u32 *)from; 873 src_dword &= mask; 874 875 /* shift to correct alignment */ 876 mask <<= shift_width; 877 src_dword <<= shift_width; 878 879 /* get the current bits from the target bit string */ 880 dest = hmc_bits + (ce_info->lsb / 8); 881 882 i40e_memcpy(&dest_dword, dest, sizeof(dest_dword), I40E_DMA_TO_NONDMA); 883 884 dest_dword &= ~(CPU_TO_LE32(mask)); /* get the bits not changing */ 885 dest_dword |= CPU_TO_LE32(src_dword); /* add in the new bits */ 886 887 /* put it all back */ 888 i40e_memcpy(dest, &dest_dword, sizeof(dest_dword), I40E_NONDMA_TO_DMA); 889} 890 891/** 892 * i40e_write_qword - replace HMC context qword 893 * @hmc_bits: pointer to the HMC memory 894 * @ce_info: a description of the struct to be read from 895 * @src: the struct to be read from 896 **/ 897static void i40e_write_qword(u8 *hmc_bits, 898 struct i40e_context_ele *ce_info, 899 u8 *src) 900{ 901 u64 src_qword, mask; 902 u8 *from, *dest; 903 u16 shift_width; 904 __le64 dest_qword; 905 906 /* copy from the next struct field */ 907 from = src + ce_info->offset; 908 909 /* prepare the bits and mask */ 910 shift_width = ce_info->lsb % 8; 911 912 /* if the field width is exactly 64 on an x86 machine, then the shift 913 * operation will not work because the SHL instructions count is masked 914 * to 6 bits so the shift will do nothing 915 */ 916 if (ce_info->width < 64) 917 mask = ((u64)1 << ce_info->width) - 1; 918 else 919 mask = 0xFFFFFFFFFFFFFFFFUL; 920 921 /* don't swizzle the bits until after the mask because the mask bits 922 * will be in a different bit position on big endian machines 923 */ 924 src_qword = *(u64 *)from; 925 src_qword &= mask; 926 927 /* shift to correct alignment */ 928 mask <<= shift_width; 929 src_qword <<= shift_width; 930 931 /* get the current bits from the target bit string */ 932 dest = hmc_bits + (ce_info->lsb / 8); 933 934 i40e_memcpy(&dest_qword, dest, sizeof(dest_qword), I40E_DMA_TO_NONDMA); 935 936 dest_qword &= ~(CPU_TO_LE64(mask)); /* get the bits not changing */ 937 dest_qword |= CPU_TO_LE64(src_qword); /* add in the new bits */ 938 939 /* put it all back */ 940 i40e_memcpy(dest, &dest_qword, sizeof(dest_qword), I40E_NONDMA_TO_DMA); 941} 942 943/** 944 * i40e_read_byte - read HMC context byte into struct 945 * @hmc_bits: pointer to the HMC memory |
760 * @ce_info: a description of the struct to be filled 761 * @dest: the struct to be filled 762 **/ | 946 * @ce_info: a description of the struct to be filled 947 * @dest: the struct to be filled 948 **/ |
763static enum i40e_status_code i40e_get_hmc_context(u8 *context_bytes, 764 struct i40e_context_ele *ce_info, 765 u8 *dest) | 949static void i40e_read_byte(u8 *hmc_bits, 950 struct i40e_context_ele *ce_info, 951 u8 *dest) |
766{ | 952{ |
953 u8 dest_byte, mask; 954 u8 *src, *target; |
|
767 u16 shift_width; | 955 u16 shift_width; |
768 u8 bitfield[8]; 769 int i, f; 770 u64 mask; 771 u8 *p; | |
772 | 956 |
773 for (f = 0; ce_info[f].width != 0; f++) { 774 *(u64 *)bitfield = 0; | 957 /* prepare the bits and mask */ 958 shift_width = ce_info->lsb % 8; 959 mask = ((u8)1 << ce_info->width) - 1; |
775 | 960 |
776 /* copy the bytes that contain the desired bits */ 777 p = context_bytes + (ce_info[f].lsb / 8); 778 for (i = 0; i < ce_info[f].size_of; i++) 779 bitfield[i] = p[i]; | 961 /* shift to correct alignment */ 962 mask <<= shift_width; |
780 | 963 |
781 /* shift the bits to the right */ 782 shift_width = ce_info[f].lsb % 8; 783 *(u64 *)bitfield >>= shift_width; | 964 /* get the current bits from the src bit string */ 965 src = hmc_bits + (ce_info->lsb / 8); |
784 | 966 |
785 /* some fields might overlap into one more byte, so grab 786 * the one more byte if needed and stick the extra bits 787 * onto the top of the value 788 * example: 62 bit field that starts in bit 5 of first byte 789 * will overlap 3 bits into byte 9 790 */ 791 if ((shift_width + ce_info[f].width) > 792 (ce_info[f].size_of * 8)) { 793 u8 byte = p[ce_info[f].size_of]; 794 byte <<= (8 - shift_width); 795 bitfield[ce_info[f].size_of - 1] |= byte; 796 } | 967 i40e_memcpy(&dest_byte, src, sizeof(dest_byte), I40E_DMA_TO_NONDMA); |
797 | 968 |
798 /* mask for the target bits */ 799 mask = ((u64)1 << ce_info[f].width) - 1; 800 *(u64 *)bitfield &= mask; | 969 dest_byte &= ~(mask); |
801 | 970 |
802 /* copy into the appropriate struct field */ 803 p = dest + ce_info[f].offset; | 971 dest_byte >>= shift_width; 972 973 /* get the address from the struct field */ 974 target = dest + ce_info->offset; 975 976 /* put it back in the struct */ 977 i40e_memcpy(target, &dest_byte, sizeof(dest_byte), I40E_NONDMA_TO_DMA); 978} 979 980/** 981 * i40e_read_word - read HMC context word into struct 982 * @hmc_bits: pointer to the HMC memory 983 * @ce_info: a description of the struct to be filled 984 * @dest: the struct to be filled 985 **/ 986static void i40e_read_word(u8 *hmc_bits, 987 struct i40e_context_ele *ce_info, 988 u8 *dest) 989{ 990 u16 dest_word, mask; 991 u8 *src, *target; 992 u16 shift_width; 993 __le16 src_word; 994 995 /* prepare the bits and mask */ 996 shift_width = ce_info->lsb % 8; 997 mask = ((u16)1 << ce_info->width) - 1; 998 999 /* shift to correct alignment */ 1000 mask <<= shift_width; 1001 1002 /* get the current bits from the src bit string */ 1003 src = hmc_bits + (ce_info->lsb / 8); 1004 1005 i40e_memcpy(&src_word, src, sizeof(src_word), I40E_DMA_TO_NONDMA); 1006 1007 /* the data in the memory is stored as little endian so mask it 1008 * correctly 1009 */ 1010 src_word &= ~(CPU_TO_LE16(mask)); 1011 1012 /* get the data back into host order before shifting */ 1013 dest_word = LE16_TO_CPU(src_word); 1014 1015 dest_word >>= shift_width; 1016 1017 /* get the address from the struct field */ 1018 target = dest + ce_info->offset; 1019 1020 /* put it back in the struct */ 1021 i40e_memcpy(target, &dest_word, sizeof(dest_word), I40E_NONDMA_TO_DMA); 1022} 1023 1024/** 1025 * i40e_read_dword - read HMC context dword into struct 1026 * @hmc_bits: pointer to the HMC memory 1027 * @ce_info: a description of the struct to be filled 1028 * @dest: the struct to be filled 1029 **/ 1030static void i40e_read_dword(u8 *hmc_bits, 1031 struct i40e_context_ele *ce_info, 1032 u8 *dest) 1033{ 1034 u32 dest_dword, mask; 1035 u8 *src, *target; 1036 u16 shift_width; 1037 __le32 src_dword; 1038 1039 /* prepare the bits and mask */ 1040 shift_width = ce_info->lsb % 8; 1041 1042 /* if the field width is exactly 32 on an x86 machine, then the shift 1043 * operation will not work because the SHL instructions count is masked 1044 * to 5 bits so the shift will do nothing 1045 */ 1046 if (ce_info->width < 32) 1047 mask = ((u32)1 << ce_info->width) - 1; 1048 else 1049 mask = 0xFFFFFFFF; 1050 1051 /* shift to correct alignment */ 1052 mask <<= shift_width; 1053 1054 /* get the current bits from the src bit string */ 1055 src = hmc_bits + (ce_info->lsb / 8); 1056 1057 i40e_memcpy(&src_dword, src, sizeof(src_dword), I40E_DMA_TO_NONDMA); 1058 1059 /* the data in the memory is stored as little endian so mask it 1060 * correctly 1061 */ 1062 src_dword &= ~(CPU_TO_LE32(mask)); 1063 1064 /* get the data back into host order before shifting */ 1065 dest_dword = LE32_TO_CPU(src_dword); 1066 1067 dest_dword >>= shift_width; 1068 1069 /* get the address from the struct field */ 1070 target = dest + ce_info->offset; 1071 1072 /* put it back in the struct */ 1073 i40e_memcpy(target, &dest_dword, sizeof(dest_dword), 1074 I40E_NONDMA_TO_DMA); 1075} 1076 1077/** 1078 * i40e_read_qword - read HMC context qword into struct 1079 * @hmc_bits: pointer to the HMC memory 1080 * @ce_info: a description of the struct to be filled 1081 * @dest: the struct to be filled 1082 **/ 1083static void i40e_read_qword(u8 *hmc_bits, 1084 struct i40e_context_ele *ce_info, 1085 u8 *dest) 1086{ 1087 u64 dest_qword, mask; 1088 u8 *src, *target; 1089 u16 shift_width; 1090 __le64 src_qword; 1091 1092 /* prepare the bits and mask */ 1093 shift_width = ce_info->lsb % 8; 1094 1095 /* if the field width is exactly 64 on an x86 machine, then the shift 1096 * operation will not work because the SHL instructions count is masked 1097 * to 6 bits so the shift will do nothing 1098 */ 1099 if (ce_info->width < 64) 1100 mask = ((u64)1 << ce_info->width) - 1; 1101 else 1102 mask = 0xFFFFFFFFFFFFFFFFUL; 1103 1104 /* shift to correct alignment */ 1105 mask <<= shift_width; 1106 1107 /* get the current bits from the src bit string */ 1108 src = hmc_bits + (ce_info->lsb / 8); 1109 1110 i40e_memcpy(&src_qword, src, sizeof(src_qword), I40E_DMA_TO_NONDMA); 1111 1112 /* the data in the memory is stored as little endian so mask it 1113 * correctly 1114 */ 1115 src_qword &= ~(CPU_TO_LE64(mask)); 1116 1117 /* get the data back into host order before shifting */ 1118 dest_qword = LE64_TO_CPU(src_qword); 1119 1120 dest_qword >>= shift_width; 1121 1122 /* get the address from the struct field */ 1123 target = dest + ce_info->offset; 1124 1125 /* put it back in the struct */ 1126 i40e_memcpy(target, &dest_qword, sizeof(dest_qword), 1127 I40E_NONDMA_TO_DMA); 1128} 1129 1130/** 1131 * i40e_get_hmc_context - extract HMC context bits 1132 * @context_bytes: pointer to the context bit array 1133 * @ce_info: a description of the struct to be filled 1134 * @dest: the struct to be filled 1135 **/ 1136static enum i40e_status_code i40e_get_hmc_context(u8 *context_bytes, 1137 struct i40e_context_ele *ce_info, 1138 u8 *dest) 1139{ 1140 int f; 1141 1142 for (f = 0; ce_info[f].width != 0; f++) { |
804 switch (ce_info[f].size_of) { 805 case 1: | 1143 switch (ce_info[f].size_of) { 1144 case 1: |
806 *p = *(u8 *)&bitfield; | 1145 i40e_read_byte(context_bytes, &ce_info[f], dest); |
807 break; 808 case 2: | 1146 break; 1147 case 2: |
809 *(u16 *)p = LE16_TO_CPU(*(u16 *)&bitfield); | 1148 i40e_read_word(context_bytes, &ce_info[f], dest); |
810 break; 811 case 4: | 1149 break; 1150 case 4: |
812 *(u32 *)p = LE32_TO_CPU(*(u32 *)&bitfield); | 1151 i40e_read_dword(context_bytes, &ce_info[f], dest); |
813 break; 814 case 8: | 1152 break; 1153 case 8: |
815 *(u64 *)p = LE64_TO_CPU(*(u64 *)&bitfield); | 1154 i40e_read_qword(context_bytes, &ce_info[f], dest); |
816 break; 817 default: 818 /* nothing to do, just keep going */ 819 break; 820 } 821 } 822 823 return I40E_SUCCESS; --- 21 unchanged lines hidden (view full) --- 845 * @context_bytes: pointer to the context bit array 846 * @ce_info: a description of the struct to be filled 847 * @dest: the struct to be filled 848 **/ 849static enum i40e_status_code i40e_set_hmc_context(u8 *context_bytes, 850 struct i40e_context_ele *ce_info, 851 u8 *dest) 852{ | 1155 break; 1156 default: 1157 /* nothing to do, just keep going */ 1158 break; 1159 } 1160 } 1161 1162 return I40E_SUCCESS; --- 21 unchanged lines hidden (view full) --- 1184 * @context_bytes: pointer to the context bit array 1185 * @ce_info: a description of the struct to be filled 1186 * @dest: the struct to be filled 1187 **/ 1188static enum i40e_status_code i40e_set_hmc_context(u8 *context_bytes, 1189 struct i40e_context_ele *ce_info, 1190 u8 *dest) 1191{ |
853 u16 shift_width; 854 u64 bitfield; 855 u8 hi_byte; 856 u8 hi_mask; 857 u64 t_bits; 858 u64 mask; 859 u8 *p; | |
860 int f; 861 862 for (f = 0; ce_info[f].width != 0; f++) { | 1192 int f; 1193 1194 for (f = 0; ce_info[f].width != 0; f++) { |
863 /* clear out the field */ 864 bitfield = 0; | |
865 | 1195 |
866 /* copy from the next struct field */ 867 p = dest + ce_info[f].offset; | 1196 /* we have to deal with each element of the HMC using the 1197 * correct size so that we are correct regardless of the 1198 * endianness of the machine 1199 */ |
868 switch (ce_info[f].size_of) { 869 case 1: | 1200 switch (ce_info[f].size_of) { 1201 case 1: |
870 bitfield = *p; | 1202 i40e_write_byte(context_bytes, &ce_info[f], dest); |
871 break; 872 case 2: | 1203 break; 1204 case 2: |
873 bitfield = CPU_TO_LE16(*(u16 *)p); | 1205 i40e_write_word(context_bytes, &ce_info[f], dest); |
874 break; 875 case 4: | 1206 break; 1207 case 4: |
876 bitfield = CPU_TO_LE32(*(u32 *)p); | 1208 i40e_write_dword(context_bytes, &ce_info[f], dest); |
877 break; 878 case 8: | 1209 break; 1210 case 8: |
879 bitfield = CPU_TO_LE64(*(u64 *)p); | 1211 i40e_write_qword(context_bytes, &ce_info[f], dest); |
880 break; 881 } | 1212 break; 1213 } |
882 883 /* prepare the bits and mask */ 884 shift_width = ce_info[f].lsb % 8; 885 mask = ((u64)1 << ce_info[f].width) - 1; 886 887 /* save upper bytes for special case */ 888 hi_mask = (u8)((mask >> 56) & 0xff); 889 hi_byte = (u8)((bitfield >> 56) & 0xff); 890 891 /* shift to correct alignment */ 892 mask <<= shift_width; 893 bitfield <<= shift_width; 894 895 /* get the current bits from the target bit string */ 896 p = context_bytes + (ce_info[f].lsb / 8); 897 i40e_memcpy(&t_bits, p, sizeof(u64), I40E_DMA_TO_NONDMA); 898 899 t_bits &= ~mask; /* get the bits not changing */ 900 t_bits |= bitfield; /* add in the new bits */ 901 902 /* put it all back */ 903 i40e_memcpy(p, &t_bits, sizeof(u64), I40E_NONDMA_TO_DMA); 904 905 /* deal with the special case if needed 906 * example: 62 bit field that starts in bit 5 of first byte 907 * will overlap 3 bits into byte 9 908 */ 909 if ((shift_width + ce_info[f].width) > 64) { 910 u8 byte; 911 912 hi_mask >>= (8 - shift_width); 913 hi_byte >>= (8 - shift_width); 914 byte = p[8] & ~hi_mask; /* get the bits not changing */ 915 byte |= hi_byte; /* add in the new bits */ 916 p[8] = byte; /* put it back */ 917 } | |
918 } 919 920 return I40E_SUCCESS; 921} 922 923/** 924 * i40e_hmc_get_object_va - retrieves an object's virtual address 925 * @hmc_info: pointer to i40e_hmc_info struct --- 197 unchanged lines hidden --- | 1214 } 1215 1216 return I40E_SUCCESS; 1217} 1218 1219/** 1220 * i40e_hmc_get_object_va - retrieves an object's virtual address 1221 * @hmc_info: pointer to i40e_hmc_info struct --- 197 unchanged lines hidden --- |