e1000: update copyright
[dpdk.git] / lib / librte_pmd_e1000 / e1000 / e1000_manage.c
1 /*******************************************************************************
2
3 Copyright (c) 2001-2012, 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
9  1. Redistributions of source code must retain the above copyright notice,
10     this list of conditions and the following disclaimer.
11
12  2. Redistributions in binary form must reproduce the above copyright
13     notice, this list of conditions and the following disclaimer in the
14     documentation and/or other materials provided with the distribution.
15
16  3. Neither the name of the Intel Corporation nor the names of its
17     contributors may be used to endorse or promote products derived from
18     this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
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
34 #include "e1000_api.h"
35
36 /**
37  *  e1000_calculate_checksum - Calculate checksum for buffer
38  *  @buffer: pointer to EEPROM
39  *  @length: size of EEPROM to calculate a checksum for
40  *
41  *  Calculates the checksum for some buffer on a specified length.  The
42  *  checksum calculated is returned.
43  **/
44 u8 e1000_calculate_checksum(u8 *buffer, u32 length)
45 {
46         u32 i;
47         u8 sum = 0;
48
49         DEBUGFUNC("e1000_calculate_checksum");
50
51         if (!buffer)
52                 return 0;
53
54         for (i = 0; i < length; i++)
55                 sum += buffer[i];
56
57         return (u8) (0 - sum);
58 }
59
60 /**
61  *  e1000_mng_enable_host_if_generic - Checks host interface is enabled
62  *  @hw: pointer to the HW structure
63  *
64  *  Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
65  *
66  *  This function checks whether the HOST IF is enabled for command operation
67  *  and also checks whether the previous command is completed.  It busy waits
68  *  in case of previous command is not completed.
69  **/
70 s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw)
71 {
72         u32 hicr;
73         s32 ret_val = E1000_SUCCESS;
74         u8 i;
75
76         DEBUGFUNC("e1000_mng_enable_host_if_generic");
77
78         if (!(hw->mac.arc_subsystem_valid)) {
79                 DEBUGOUT("ARC subsystem not valid.\n");
80                 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
81                 goto out;
82         }
83
84         /* Check that the host interface is enabled. */
85         hicr = E1000_READ_REG(hw, E1000_HICR);
86         if ((hicr & E1000_HICR_EN) == 0) {
87                 DEBUGOUT("E1000_HOST_EN bit disabled.\n");
88                 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
89                 goto out;
90         }
91         /* check the previous command is completed */
92         for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
93                 hicr = E1000_READ_REG(hw, E1000_HICR);
94                 if (!(hicr & E1000_HICR_C))
95                         break;
96                 msec_delay_irq(1);
97         }
98
99         if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
100                 DEBUGOUT("Previous command timeout failed .\n");
101                 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
102                 goto out;
103         }
104
105 out:
106         return ret_val;
107 }
108
109 /**
110  *  e1000_check_mng_mode_generic - Generic check management mode
111  *  @hw: pointer to the HW structure
112  *
113  *  Reads the firmware semaphore register and returns TRUE (>0) if
114  *  manageability is enabled, else FALSE (0).
115  **/
116 bool e1000_check_mng_mode_generic(struct e1000_hw *hw)
117 {
118         u32 fwsm = E1000_READ_REG(hw, E1000_FWSM);
119
120         DEBUGFUNC("e1000_check_mng_mode_generic");
121
122
123         return (fwsm & E1000_FWSM_MODE_MASK) ==
124                 (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT);
125 }
126
127 /**
128  *  e1000_enable_tx_pkt_filtering_generic - Enable packet filtering on Tx
129  *  @hw: pointer to the HW structure
130  *
131  *  Enables packet filtering on transmit packets if manageability is enabled
132  *  and host interface is enabled.
133  **/
134 bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
135 {
136         struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie;
137         u32 *buffer = (u32 *)&hw->mng_cookie;
138         u32 offset;
139         s32 ret_val, hdr_csum, csum;
140         u8 i, len;
141
142         DEBUGFUNC("e1000_enable_tx_pkt_filtering_generic");
143
144         hw->mac.tx_pkt_filtering = TRUE;
145
146         /* No manageability, no filtering */
147         if (!hw->mac.ops.check_mng_mode(hw)) {
148                 hw->mac.tx_pkt_filtering = FALSE;
149                 goto out;
150         }
151
152         /*
153          * If we can't read from the host interface for whatever
154          * reason, disable filtering.
155          */
156         ret_val = hw->mac.ops.mng_enable_host_if(hw);
157         if (ret_val != E1000_SUCCESS) {
158                 hw->mac.tx_pkt_filtering = FALSE;
159                 goto out;
160         }
161
162         /* Read in the header.  Length and offset are in dwords. */
163         len    = E1000_MNG_DHCP_COOKIE_LENGTH >> 2;
164         offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2;
165         for (i = 0; i < len; i++)
166                 *(buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF,
167                                                            offset + i);
168         hdr_csum = hdr->checksum;
169         hdr->checksum = 0;
170         csum = e1000_calculate_checksum((u8 *)hdr,
171                                         E1000_MNG_DHCP_COOKIE_LENGTH);
172         /*
173          * If either the checksums or signature don't match, then
174          * the cookie area isn't considered valid, in which case we
175          * take the safe route of assuming Tx filtering is enabled.
176          */
177         if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) {
178                 hw->mac.tx_pkt_filtering = TRUE;
179                 goto out;
180         }
181
182         /* Cookie area is valid, make the final check for filtering. */
183         if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) {
184                 hw->mac.tx_pkt_filtering = FALSE;
185                 goto out;
186         }
187
188 out:
189         return hw->mac.tx_pkt_filtering;
190 }
191
192 /**
193  *  e1000_mng_write_dhcp_info_generic - Writes DHCP info to host interface
194  *  @hw: pointer to the HW structure
195  *  @buffer: pointer to the host interface
196  *  @length: size of the buffer
197  *
198  *  Writes the DHCP information to the host interface.
199  **/
200 s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, u8 *buffer,
201                                       u16 length)
202 {
203         struct e1000_host_mng_command_header hdr;
204         s32 ret_val;
205         u32 hicr;
206
207         DEBUGFUNC("e1000_mng_write_dhcp_info_generic");
208
209         hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
210         hdr.command_length = length;
211         hdr.reserved1 = 0;
212         hdr.reserved2 = 0;
213         hdr.checksum = 0;
214
215         /* Enable the host interface */
216         ret_val = hw->mac.ops.mng_enable_host_if(hw);
217         if (ret_val)
218                 goto out;
219
220         /* Populate the host interface with the contents of "buffer". */
221         ret_val = hw->mac.ops.mng_host_if_write(hw, buffer, length,
222                                           sizeof(hdr), &(hdr.checksum));
223         if (ret_val)
224                 goto out;
225
226         /* Write the manageability command header */
227         ret_val = hw->mac.ops.mng_write_cmd_header(hw, &hdr);
228         if (ret_val)
229                 goto out;
230
231         /* Tell the ARC a new command is pending. */
232         hicr = E1000_READ_REG(hw, E1000_HICR);
233         E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
234
235 out:
236         return ret_val;
237 }
238
239 /**
240  *  e1000_mng_write_cmd_header_generic - Writes manageability command header
241  *  @hw: pointer to the HW structure
242  *  @hdr: pointer to the host interface command header
243  *
244  *  Writes the command header after does the checksum calculation.
245  **/
246 s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw,
247                                     struct e1000_host_mng_command_header *hdr)
248 {
249         u16 i, length = sizeof(struct e1000_host_mng_command_header);
250
251         DEBUGFUNC("e1000_mng_write_cmd_header_generic");
252
253         /* Write the whole command header structure with new checksum. */
254
255         hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length);
256
257         length >>= 2;
258         /* Write the relevant command block into the ram area. */
259         for (i = 0; i < length; i++) {
260                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i,
261                                             *((u32 *) hdr + i));
262                 E1000_WRITE_FLUSH(hw);
263         }
264
265         return E1000_SUCCESS;
266 }
267
268 /**
269  *  e1000_mng_host_if_write_generic - Write to the manageability host interface
270  *  @hw: pointer to the HW structure
271  *  @buffer: pointer to the host interface buffer
272  *  @length: size of the buffer
273  *  @offset: location in the buffer to write to
274  *  @sum: sum of the data (not checksum)
275  *
276  *  This function writes the buffer content at the offset given on the host if.
277  *  It also does alignment considerations to do the writes in most efficient
278  *  way.  Also fills up the sum of the buffer in *buffer parameter.
279  **/
280 s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
281                                     u16 length, u16 offset, u8 *sum)
282 {
283         u8 *tmp;
284         u8 *bufptr = buffer;
285         u32 data = 0;
286         s32 ret_val = E1000_SUCCESS;
287         u16 remaining, i, j, prev_bytes;
288
289         DEBUGFUNC("e1000_mng_host_if_write_generic");
290
291         /* sum = only sum of the data and it is not checksum */
292
293         if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) {
294                 ret_val = -E1000_ERR_PARAM;
295                 goto out;
296         }
297
298         tmp = (u8 *)&data;
299         prev_bytes = offset & 0x3;
300         offset >>= 2;
301
302         if (prev_bytes) {
303                 data = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset);
304                 for (j = prev_bytes; j < sizeof(u32); j++) {
305                         *(tmp + j) = *bufptr++;
306                         *sum += *(tmp + j);
307                 }
308                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset, data);
309                 length -= j - prev_bytes;
310                 offset++;
311         }
312
313         remaining = length & 0x3;
314         length -= remaining;
315
316         /* Calculate length in DWORDs */
317         length >>= 2;
318
319         /*
320          * The device driver writes the relevant command block into the
321          * ram area.
322          */
323         for (i = 0; i < length; i++) {
324                 for (j = 0; j < sizeof(u32); j++) {
325                         *(tmp + j) = *bufptr++;
326                         *sum += *(tmp + j);
327                 }
328
329                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i,
330                                             data);
331         }
332         if (remaining) {
333                 for (j = 0; j < sizeof(u32); j++) {
334                         if (j < remaining)
335                                 *(tmp + j) = *bufptr++;
336                         else
337                                 *(tmp + j) = 0;
338
339                         *sum += *(tmp + j);
340                 }
341                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, data);
342         }
343
344 out:
345         return ret_val;
346 }
347
348 /**
349  *  e1000_enable_mng_pass_thru - Check if management passthrough is needed
350  *  @hw: pointer to the HW structure
351  *
352  *  Verifies the hardware needs to leave interface enabled so that frames can
353  *  be directed to and from the management interface.
354  **/
355 bool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
356 {
357         u32 manc;
358         u32 fwsm, factps;
359         bool ret_val = FALSE;
360
361         DEBUGFUNC("e1000_enable_mng_pass_thru");
362
363         if (!hw->mac.asf_firmware_present)
364                 goto out;
365
366         manc = E1000_READ_REG(hw, E1000_MANC);
367
368         if (!(manc & E1000_MANC_RCV_TCO_EN))
369                 goto out;
370
371         if (hw->mac.has_fwsm) {
372                 fwsm = E1000_READ_REG(hw, E1000_FWSM);
373                 factps = E1000_READ_REG(hw, E1000_FACTPS);
374
375                 if (!(factps & E1000_FACTPS_MNGCG) &&
376                     ((fwsm & E1000_FWSM_MODE_MASK) ==
377                      (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) {
378                         ret_val = TRUE;
379                         goto out;
380                 }
381         } else if ((manc & E1000_MANC_SMBUS_EN) &&
382                     !(manc & E1000_MANC_ASF_EN)) {
383                         ret_val = TRUE;
384                         goto out;
385         }
386
387 out:
388         return ret_val;
389 }
390
391 /**
392  *  e1000_host_interface_command - Writes buffer to host interface
393  *  @hw: pointer to the HW structure
394  *  @buffer: contains a command to write
395  *  @length: the byte length of the buffer, must be multiple of 4 bytes
396  *
397  *  Writes a buffer to the Host Interface.  Upon success, returns E1000_SUCCESS
398  *  else returns E1000_ERR_HOST_INTERFACE_COMMAND.
399  **/
400 s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length)
401 {
402         u32 hicr, i;
403         s32 ret_val = E1000_SUCCESS;
404
405         DEBUGFUNC("e1000_host_interface_command");
406
407         if (!(hw->mac.arc_subsystem_valid)) {
408                 DEBUGOUT("Hardware doesn't support host interface command.\n");
409                 goto out;
410         }
411
412         if (!hw->mac.asf_firmware_present) {
413                 DEBUGOUT("Firmware is not present.\n");
414                 goto out;
415         }
416
417         if (length == 0 || length & 0x3 ||
418             length > E1000_HI_MAX_BLOCK_BYTE_LENGTH) {
419                 DEBUGOUT("Buffer length failure.\n");
420                 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
421                 goto out;
422         }
423
424         /* Check that the host interface is enabled. */
425         hicr = E1000_READ_REG(hw, E1000_HICR);
426         if ((hicr & E1000_HICR_EN) == 0) {
427                 DEBUGOUT("E1000_HOST_EN bit disabled.\n");
428                 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
429                 goto out;
430         }
431
432         /* Calculate length in DWORDs */
433         length >>= 2;
434
435         /*
436          * The device driver writes the relevant command block
437          * into the ram area.
438          */
439         for (i = 0; i < length; i++)
440                 E1000_WRITE_REG_ARRAY_DWORD(hw,
441                                             E1000_HOST_IF,
442                                             i,
443                                             *((u32 *)buffer + i));
444
445         /* Setting this bit tells the ARC that a new command is pending. */
446         E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
447
448         for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
449                 hicr = E1000_READ_REG(hw, E1000_HICR);
450                 if (!(hicr & E1000_HICR_C))
451                         break;
452                 msec_delay(1);
453         }
454
455         /* Check command successful completion. */
456         if (i == E1000_HI_COMMAND_TIMEOUT ||
457             (!(E1000_READ_REG(hw, E1000_HICR) & E1000_HICR_SV))) {
458                 DEBUGOUT("Command has failed with no status valid.\n");
459                 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
460                 goto out;
461         }
462
463         for (i = 0; i < length; i++)
464                 *((u32 *)buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw,
465                                                                   E1000_HOST_IF,
466                                                                   i);
467
468 out:
469         return ret_val;
470 }
471