e1000e_manage.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 FILE_LICENCE ( GPL2_OR_LATER );
00030
00031 #if 0
00032
00033 #include "e1000e.h"
00034
00035 static u8 e1000e_calculate_checksum(u8 *buffer, u32 length);
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 static u8 e1000e_calculate_checksum(u8 *buffer, u32 length)
00046 {
00047 u32 i;
00048 u8 sum = 0;
00049
00050 if (!buffer)
00051 return 0;
00052 for (i = 0; i < length; i++)
00053 sum += buffer[i];
00054
00055 return (u8) (0 - sum);
00056 }
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 s32 e1000e_mng_enable_host_if_generic(struct e1000_hw *hw)
00069 {
00070 u32 hicr;
00071 s32 ret_val = E1000_SUCCESS;
00072 u8 i;
00073
00074
00075 hicr = er32(HICR);
00076 if ((hicr & E1000_HICR_EN) == 0) {
00077 e_dbg("E1000_HOST_EN bit disabled.\n");
00078 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
00079 goto out;
00080 }
00081
00082 for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
00083 hicr = er32(HICR);
00084 if (!(hicr & E1000_HICR_C))
00085 break;
00086 mdelay(1);
00087 }
00088
00089 if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
00090 e_dbg("Previous command timeout failed .\n");
00091 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
00092 goto out;
00093 }
00094
00095 out:
00096 return ret_val;
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106 bool e1000e_check_mng_mode_generic(struct e1000_hw *hw)
00107 {
00108 u32 fwsm;
00109
00110 fwsm = er32(FWSM);
00111 return (fwsm & E1000_FWSM_MODE_MASK) ==
00112 (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT);
00113 }
00114
00115
00116
00117
00118
00119
00120
00121
00122 bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw)
00123 {
00124 struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie;
00125 u32 *buffer = (u32 *)&hw->mng_cookie;
00126 u32 offset;
00127 s32 ret_val, hdr_csum, csum;
00128 u8 i, len;
00129 bool tx_filter = true;
00130
00131
00132 if (!hw->mac.ops.check_mng_mode(hw)) {
00133 tx_filter = false;
00134 goto out;
00135 }
00136
00137
00138
00139
00140
00141 ret_val = hw->mac.ops.mng_enable_host_if(hw);
00142 if (ret_val != E1000_SUCCESS) {
00143 tx_filter = false;
00144 goto out;
00145 }
00146
00147
00148 len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2;
00149 offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2;
00150 for (i = 0; i < len; i++) {
00151 *(buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw,
00152 E1000_HOST_IF,
00153 offset + i);
00154 }
00155 hdr_csum = hdr->checksum;
00156 hdr->checksum = 0;
00157 csum = e1000e_calculate_checksum((u8 *)hdr,
00158 E1000_MNG_DHCP_COOKIE_LENGTH);
00159
00160
00161
00162
00163
00164 if (hdr_csum != csum)
00165 goto out;
00166 if (hdr->signature != E1000_IAMT_SIGNATURE)
00167 goto out;
00168
00169
00170 if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING))
00171 tx_filter = false;
00172
00173 out:
00174 hw->mac.tx_pkt_filtering = tx_filter;
00175 return tx_filter;
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer,
00187 u16 length)
00188 {
00189 struct e1000_host_mng_command_header hdr;
00190 s32 ret_val;
00191 u32 hicr;
00192
00193 hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
00194 hdr.command_length = length;
00195 hdr.reserved1 = 0;
00196 hdr.reserved2 = 0;
00197 hdr.checksum = 0;
00198
00199
00200 ret_val = hw->mac.ops.mng_enable_host_if(hw);
00201 if (ret_val)
00202 goto out;
00203
00204
00205 ret_val = hw->mac.ops.mng_host_if_write(hw, buffer, length,
00206 sizeof(hdr), &(hdr.checksum));
00207 if (ret_val)
00208 goto out;
00209
00210
00211 ret_val = hw->mac.ops.mng_write_cmd_header(hw, &hdr);
00212 if (ret_val)
00213 goto out;
00214
00215
00216 hicr = er32(HICR);
00217 ew32(HICR, hicr | E1000_HICR_C);
00218
00219 out:
00220 return ret_val;
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230 s32 e1000e_mng_write_cmd_header_generic(struct e1000_hw *hw,
00231 struct e1000_host_mng_command_header *hdr)
00232 {
00233 u16 i, length = sizeof(struct e1000_host_mng_command_header);
00234
00235
00236
00237 hdr->checksum = e1000e_calculate_checksum((u8 *)hdr, length);
00238
00239 length >>= 2;
00240
00241 for (i = 0; i < length; i++) {
00242 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i,
00243 *((u32 *) hdr + i));
00244 e1e_flush();
00245 }
00246
00247 return E1000_SUCCESS;
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 s32 e1000e_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
00263 u16 length, u16 offset, u8 *sum)
00264 {
00265 u8 *tmp;
00266 u8 *bufptr = buffer;
00267 u32 data = 0;
00268 s32 ret_val = E1000_SUCCESS;
00269 u16 remaining, i, j, prev_bytes;
00270
00271
00272
00273 if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) {
00274 ret_val = -E1000_ERR_PARAM;
00275 goto out;
00276 }
00277
00278 tmp = (u8 *)&data;
00279 prev_bytes = offset & 0x3;
00280 offset >>= 2;
00281
00282 if (prev_bytes) {
00283 data = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset);
00284 for (j = prev_bytes; j < sizeof(u32); j++) {
00285 *(tmp + j) = *bufptr++;
00286 *sum += *(tmp + j);
00287 }
00288 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset, data);
00289 length -= j - prev_bytes;
00290 offset++;
00291 }
00292
00293 remaining = length & 0x3;
00294 length -= remaining;
00295
00296
00297 length >>= 2;
00298
00299
00300
00301
00302
00303 for (i = 0; i < length; i++) {
00304 for (j = 0; j < sizeof(u32); j++) {
00305 *(tmp + j) = *bufptr++;
00306 *sum += *(tmp + j);
00307 }
00308
00309 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i,
00310 data);
00311 }
00312 if (remaining) {
00313 for (j = 0; j < sizeof(u32); j++) {
00314 if (j < remaining)
00315 *(tmp + j) = *bufptr++;
00316 else
00317 *(tmp + j) = 0;
00318
00319 *sum += *(tmp + j);
00320 }
00321 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, data);
00322 }
00323
00324 out:
00325 return ret_val;
00326 }
00327
00328
00329
00330
00331
00332
00333
00334 bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw)
00335 {
00336 u32 manc;
00337 u32 fwsm, factps;
00338 bool ret_val = false;
00339
00340 if (!hw->mac.asf_firmware_present)
00341 goto out;
00342
00343 manc = er32(MANC);
00344
00345 if (!(manc & E1000_MANC_RCV_TCO_EN) ||
00346 !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
00347 goto out;
00348
00349 if (hw->mac.arc_subsystem_valid) {
00350 fwsm = er32(FWSM);
00351 factps = er32(FACTPS);
00352
00353 if (!(factps & E1000_FACTPS_MNGCG) &&
00354 ((fwsm & E1000_FWSM_MODE_MASK) ==
00355 (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) {
00356 ret_val = true;
00357 goto out;
00358 }
00359 } else {
00360 if ((manc & E1000_MANC_SMBUS_EN) &&
00361 !(manc & E1000_MANC_ASF_EN)) {
00362 ret_val = true;
00363 goto out;
00364 }
00365 }
00366
00367 out:
00368 return ret_val;
00369 }
00370
00371 #endif
00372