Merge branch 'vendor/DHCPCD'
[dragonfly.git] / sys / dev / netif / ig_hal / e1000_manage.c
1 /******************************************************************************
2
3   Copyright (c) 2001-2016, 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 /*$FreeBSD$*/
34
35 #include "e1000_api.h"
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         u8 i;
74
75         DEBUGFUNC("e1000_mng_enable_host_if_generic");
76
77         if (!hw->mac.arc_subsystem_valid) {
78                 DEBUGOUT("ARC subsystem not valid.\n");
79                 return -E1000_ERR_HOST_INTERFACE_COMMAND;
80         }
81
82         /* Check that the host interface is enabled. */
83         hicr = E1000_READ_REG(hw, E1000_HICR);
84         if (!(hicr & E1000_HICR_EN)) {
85                 DEBUGOUT("E1000_HOST_EN bit disabled.\n");
86                 return -E1000_ERR_HOST_INTERFACE_COMMAND;
87         }
88         /* check the previous command is completed */
89         for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
90                 hicr = E1000_READ_REG(hw, E1000_HICR);
91                 if (!(hicr & E1000_HICR_C))
92                         break;
93                 msec_delay_irq(1);
94         }
95
96         if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
97                 DEBUGOUT("Previous command timeout failed .\n");
98                 return -E1000_ERR_HOST_INTERFACE_COMMAND;
99         }
100
101         return E1000_SUCCESS;
102 }
103
104 /**
105  *  e1000_check_mng_mode_generic - Generic check management mode
106  *  @hw: pointer to the HW structure
107  *
108  *  Reads the firmware semaphore register and returns TRUE (>0) if
109  *  manageability is enabled, else FALSE (0).
110  **/
111 bool e1000_check_mng_mode_generic(struct e1000_hw *hw)
112 {
113         u32 fwsm = E1000_READ_REG(hw, E1000_FWSM);
114
115         DEBUGFUNC("e1000_check_mng_mode_generic");
116
117
118         return (fwsm & E1000_FWSM_MODE_MASK) ==
119                 (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT);
120 }
121
122 /**
123  *  e1000_enable_tx_pkt_filtering_generic - Enable packet filtering on Tx
124  *  @hw: pointer to the HW structure
125  *
126  *  Enables packet filtering on transmit packets if manageability is enabled
127  *  and host interface is enabled.
128  **/
129 bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
130 {
131         struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie;
132         u32 *buffer = (u32 *)&hw->mng_cookie;
133         u32 offset;
134         s32 ret_val, hdr_csum, csum;
135         u8 i, len;
136
137         DEBUGFUNC("e1000_enable_tx_pkt_filtering_generic");
138
139         hw->mac.tx_pkt_filtering = TRUE;
140
141         /* No manageability, no filtering */
142         if (!hw->mac.ops.check_mng_mode(hw)) {
143                 hw->mac.tx_pkt_filtering = FALSE;
144                 return hw->mac.tx_pkt_filtering;
145         }
146
147         /* If we can't read from the host interface for whatever
148          * reason, disable filtering.
149          */
150         ret_val = e1000_mng_enable_host_if_generic(hw);
151         if (ret_val != E1000_SUCCESS) {
152                 hw->mac.tx_pkt_filtering = FALSE;
153                 return hw->mac.tx_pkt_filtering;
154         }
155
156         /* Read in the header.  Length and offset are in dwords. */
157         len    = E1000_MNG_DHCP_COOKIE_LENGTH >> 2;
158         offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2;
159         for (i = 0; i < len; i++)
160                 *(buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF,
161                                                            offset + i);
162         hdr_csum = hdr->checksum;
163         hdr->checksum = 0;
164         csum = e1000_calculate_checksum((u8 *)hdr,
165                                         E1000_MNG_DHCP_COOKIE_LENGTH);
166         /* If either the checksums or signature don't match, then
167          * the cookie area isn't considered valid, in which case we
168          * take the safe route of assuming Tx filtering is enabled.
169          */
170         if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) {
171                 hw->mac.tx_pkt_filtering = TRUE;
172                 return hw->mac.tx_pkt_filtering;
173         }
174
175         /* Cookie area is valid, make the final check for filtering. */
176         if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING))
177                 hw->mac.tx_pkt_filtering = FALSE;
178
179         return hw->mac.tx_pkt_filtering;
180 }
181
182 /**
183  *  e1000_mng_write_cmd_header_generic - Writes manageability command header
184  *  @hw: pointer to the HW structure
185  *  @hdr: pointer to the host interface command header
186  *
187  *  Writes the command header after does the checksum calculation.
188  **/
189 s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw,
190                                       struct e1000_host_mng_command_header *hdr)
191 {
192         u16 i, length = sizeof(struct e1000_host_mng_command_header);
193
194         DEBUGFUNC("e1000_mng_write_cmd_header_generic");
195
196         /* Write the whole command header structure with new checksum. */
197
198         hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length);
199
200         length >>= 2;
201         /* Write the relevant command block into the ram area. */
202         for (i = 0; i < length; i++) {
203                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i,
204                                             *((u32 *) hdr + i));
205                 E1000_WRITE_FLUSH(hw);
206         }
207
208         return E1000_SUCCESS;
209 }
210
211 /**
212  *  e1000_mng_host_if_write_generic - Write to the manageability host interface
213  *  @hw: pointer to the HW structure
214  *  @buffer: pointer to the host interface buffer
215  *  @length: size of the buffer
216  *  @offset: location in the buffer to write to
217  *  @sum: sum of the data (not checksum)
218  *
219  *  This function writes the buffer content at the offset given on the host if.
220  *  It also does alignment considerations to do the writes in most efficient
221  *  way.  Also fills up the sum of the buffer in *buffer parameter.
222  **/
223 s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
224                                     u16 length, u16 offset, u8 *sum)
225 {
226         u8 *tmp;
227         u8 *bufptr = buffer;
228         u32 data = 0;
229         u16 remaining, i, j, prev_bytes;
230
231         DEBUGFUNC("e1000_mng_host_if_write_generic");
232
233         /* sum = only sum of the data and it is not checksum */
234
235         if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH)
236                 return -E1000_ERR_PARAM;
237
238         tmp = (u8 *)&data;
239         prev_bytes = offset & 0x3;
240         offset >>= 2;
241
242         if (prev_bytes) {
243                 data = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset);
244                 for (j = prev_bytes; j < sizeof(u32); j++) {
245                         *(tmp + j) = *bufptr++;
246                         *sum += *(tmp + j);
247                 }
248                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset, data);
249                 length -= j - prev_bytes;
250                 offset++;
251         }
252
253         remaining = length & 0x3;
254         length -= remaining;
255
256         /* Calculate length in DWORDs */
257         length >>= 2;
258
259         /* The device driver writes the relevant command block into the
260          * ram area.
261          */
262         for (i = 0; i < length; i++) {
263                 for (j = 0; j < sizeof(u32); j++) {
264                         *(tmp + j) = *bufptr++;
265                         *sum += *(tmp + j);
266                 }
267
268                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i,
269                                             data);
270         }
271         if (remaining) {
272                 for (j = 0; j < sizeof(u32); j++) {
273                         if (j < remaining)
274                                 *(tmp + j) = *bufptr++;
275                         else
276                                 *(tmp + j) = 0;
277
278                         *sum += *(tmp + j);
279                 }
280                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i,
281                                             data);
282         }
283
284         return E1000_SUCCESS;
285 }
286
287 /**
288  *  e1000_mng_write_dhcp_info_generic - Writes DHCP info to host interface
289  *  @hw: pointer to the HW structure
290  *  @buffer: pointer to the host interface
291  *  @length: size of the buffer
292  *
293  *  Writes the DHCP information to the host interface.
294  **/
295 s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, u8 *buffer,
296                                       u16 length)
297 {
298         struct e1000_host_mng_command_header hdr;
299         s32 ret_val;
300         u32 hicr;
301
302         DEBUGFUNC("e1000_mng_write_dhcp_info_generic");
303
304         hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
305         hdr.command_length = length;
306         hdr.reserved1 = 0;
307         hdr.reserved2 = 0;
308         hdr.checksum = 0;
309
310         /* Enable the host interface */
311         ret_val = e1000_mng_enable_host_if_generic(hw);
312         if (ret_val)
313                 return ret_val;
314
315         /* Populate the host interface with the contents of "buffer". */
316         ret_val = e1000_mng_host_if_write_generic(hw, buffer, length,
317                                                   sizeof(hdr), &(hdr.checksum));
318         if (ret_val)
319                 return ret_val;
320
321         /* Write the manageability command header */
322         ret_val = e1000_mng_write_cmd_header_generic(hw, &hdr);
323         if (ret_val)
324                 return ret_val;
325
326         /* Tell the ARC a new command is pending. */
327         hicr = E1000_READ_REG(hw, E1000_HICR);
328         E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
329
330         return E1000_SUCCESS;
331 }
332
333 /**
334  *  e1000_enable_mng_pass_thru - Check if management passthrough is needed
335  *  @hw: pointer to the HW structure
336  *
337  *  Verifies the hardware needs to leave interface enabled so that frames can
338  *  be directed to and from the management interface.
339  **/
340 bool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
341 {
342         u32 manc;
343         u32 fwsm, factps;
344
345         DEBUGFUNC("e1000_enable_mng_pass_thru");
346
347         if (!hw->mac.asf_firmware_present)
348                 return FALSE;
349
350         manc = E1000_READ_REG(hw, E1000_MANC);
351
352         if (!(manc & E1000_MANC_RCV_TCO_EN))
353                 return FALSE;
354
355         if (hw->mac.has_fwsm) {
356                 fwsm = E1000_READ_REG(hw, E1000_FWSM);
357                 factps = E1000_READ_REG(hw, E1000_FACTPS);
358
359                 if (!(factps & E1000_FACTPS_MNGCG) &&
360                     ((fwsm & E1000_FWSM_MODE_MASK) ==
361                      (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT)))
362                         return TRUE;
363         } else if ((hw->mac.type == e1000_82574) ||
364                    (hw->mac.type == e1000_82583)) {
365                 u16 data;
366                 s32 ret_val;
367
368                 factps = E1000_READ_REG(hw, E1000_FACTPS);
369                 ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data);
370                 if (ret_val)
371                         return FALSE;
372
373                 if (!(factps & E1000_FACTPS_MNGCG) &&
374                     ((data & E1000_NVM_INIT_CTRL2_MNGM) ==
375                      (e1000_mng_mode_pt << 13)))
376                         return TRUE;
377         } else if ((manc & E1000_MANC_SMBUS_EN) &&
378                    !(manc & E1000_MANC_ASF_EN)) {
379                 return TRUE;
380         }
381
382         return FALSE;
383 }
384
385 /**
386  *  e1000_host_interface_command - Writes buffer to host interface
387  *  @hw: pointer to the HW structure
388  *  @buffer: contains a command to write
389  *  @length: the byte length of the buffer, must be multiple of 4 bytes
390  *
391  *  Writes a buffer to the Host Interface.  Upon success, returns E1000_SUCCESS
392  *  else returns E1000_ERR_HOST_INTERFACE_COMMAND.
393  **/
394 s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length)
395 {
396         u32 hicr, i;
397
398         DEBUGFUNC("e1000_host_interface_command");
399
400         if (!(hw->mac.arc_subsystem_valid)) {
401                 DEBUGOUT("Hardware doesn't support host interface command.\n");
402                 return E1000_SUCCESS;
403         }
404
405         if (!hw->mac.asf_firmware_present) {
406                 DEBUGOUT("Firmware is not present.\n");
407                 return E1000_SUCCESS;
408         }
409
410         if (length == 0 || length & 0x3 ||
411             length > E1000_HI_MAX_BLOCK_BYTE_LENGTH) {
412                 DEBUGOUT("Buffer length failure.\n");
413                 return -E1000_ERR_HOST_INTERFACE_COMMAND;
414         }
415
416         /* Check that the host interface is enabled. */
417         hicr = E1000_READ_REG(hw, E1000_HICR);
418         if (!(hicr & E1000_HICR_EN)) {
419                 DEBUGOUT("E1000_HOST_EN bit disabled.\n");
420                 return -E1000_ERR_HOST_INTERFACE_COMMAND;
421         }
422
423         /* Calculate length in DWORDs */
424         length >>= 2;
425
426         /* The device driver writes the relevant command block
427          * into the ram area.
428          */
429         for (i = 0; i < length; i++)
430                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i,
431                                             *((u32 *)buffer + i));
432
433         /* Setting this bit tells the ARC that a new command is pending. */
434         E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
435
436         for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
437                 hicr = E1000_READ_REG(hw, E1000_HICR);
438                 if (!(hicr & E1000_HICR_C))
439                         break;
440                 msec_delay(1);
441         }
442
443         /* Check command successful completion. */
444         if (i == E1000_HI_COMMAND_TIMEOUT ||
445             (!(E1000_READ_REG(hw, E1000_HICR) & E1000_HICR_SV))) {
446                 DEBUGOUT("Command has failed with no status valid.\n");
447                 return -E1000_ERR_HOST_INTERFACE_COMMAND;
448         }
449
450         for (i = 0; i < length; i++)
451                 *((u32 *)buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw,
452                                                                   E1000_HOST_IF,
453                                                                   i);
454
455         return E1000_SUCCESS;
456 }
457 /**
458  *  e1000_load_firmware - Writes proxy FW code buffer to host interface
459  *                        and execute.
460  *  @hw: pointer to the HW structure
461  *  @buffer: contains a firmware to write
462  *  @length: the byte length of the buffer, must be multiple of 4 bytes
463  *
464  *  Upon success returns E1000_SUCCESS, returns E1000_ERR_CONFIG if not enabled
465  *  in HW else returns E1000_ERR_HOST_INTERFACE_COMMAND.
466  **/
467 s32 e1000_load_firmware(struct e1000_hw *hw, u8 *buffer, u32 length)
468 {
469         u32 hicr, hibba, fwsm, icr, i;
470
471         DEBUGFUNC("e1000_load_firmware");
472
473         if (hw->mac.type < e1000_i210) {
474                 DEBUGOUT("Hardware doesn't support loading FW by the driver\n");
475                 return -E1000_ERR_CONFIG;
476         }
477
478         /* Check that the host interface is enabled. */
479         hicr = E1000_READ_REG(hw, E1000_HICR);
480         if (!(hicr & E1000_HICR_EN)) {
481                 DEBUGOUT("E1000_HOST_EN bit disabled.\n");
482                 return -E1000_ERR_CONFIG;
483         }
484         if (!(hicr & E1000_HICR_MEMORY_BASE_EN)) {
485                 DEBUGOUT("E1000_HICR_MEMORY_BASE_EN bit disabled.\n");
486                 return -E1000_ERR_CONFIG;
487         }
488
489         if (length == 0 || length & 0x3 || length > E1000_HI_FW_MAX_LENGTH) {
490                 DEBUGOUT("Buffer length failure.\n");
491                 return -E1000_ERR_INVALID_ARGUMENT;
492         }
493
494         /* Clear notification from ROM-FW by reading ICR register */
495         icr = E1000_READ_REG(hw, E1000_ICR_V2);
496
497         /* Reset ROM-FW */
498         hicr = E1000_READ_REG(hw, E1000_HICR);
499         hicr |= E1000_HICR_FW_RESET_ENABLE;
500         E1000_WRITE_REG(hw, E1000_HICR, hicr);
501         hicr |= E1000_HICR_FW_RESET;
502         E1000_WRITE_REG(hw, E1000_HICR, hicr);
503         E1000_WRITE_FLUSH(hw);
504
505         /* Wait till MAC notifies about its readiness after ROM-FW reset */
506         for (i = 0; i < (E1000_HI_COMMAND_TIMEOUT * 2); i++) {
507                 icr = E1000_READ_REG(hw, E1000_ICR_V2);
508                 if (icr & E1000_ICR_MNG)
509                         break;
510                 msec_delay(1);
511         }
512
513         /* Check for timeout */
514         if (i == E1000_HI_COMMAND_TIMEOUT) {
515                 DEBUGOUT("FW reset failed.\n");
516                 return -E1000_ERR_HOST_INTERFACE_COMMAND;
517         }
518
519         /* Wait till MAC is ready to accept new FW code */
520         for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
521                 fwsm = E1000_READ_REG(hw, E1000_FWSM);
522                 if ((fwsm & E1000_FWSM_FW_VALID) &&
523                     ((fwsm & E1000_FWSM_MODE_MASK) >> E1000_FWSM_MODE_SHIFT ==
524                     E1000_FWSM_HI_EN_ONLY_MODE))
525                         break;
526                 msec_delay(1);
527         }
528
529         /* Check for timeout */
530         if (i == E1000_HI_COMMAND_TIMEOUT) {
531                 DEBUGOUT("FW reset failed.\n");
532                 return -E1000_ERR_HOST_INTERFACE_COMMAND;
533         }
534
535         /* Calculate length in DWORDs */
536         length >>= 2;
537
538         /* The device driver writes the relevant FW code block
539          * into the ram area in DWORDs via 1kB ram addressing window.
540          */
541         for (i = 0; i < length; i++) {
542                 if (!(i % E1000_HI_FW_BLOCK_DWORD_LENGTH)) {
543                         /* Point to correct 1kB ram window */
544                         hibba = E1000_HI_FW_BASE_ADDRESS +
545                                 ((E1000_HI_FW_BLOCK_DWORD_LENGTH << 2) *
546                                 (i / E1000_HI_FW_BLOCK_DWORD_LENGTH));
547
548                         E1000_WRITE_REG(hw, E1000_HIBBA, hibba);
549                 }
550
551                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF,
552                                             i % E1000_HI_FW_BLOCK_DWORD_LENGTH,
553                                             *((u32 *)buffer + i));
554         }
555
556         /* Setting this bit tells the ARC that a new FW is ready to execute. */
557         hicr = E1000_READ_REG(hw, E1000_HICR);
558         E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
559
560         for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
561                 hicr = E1000_READ_REG(hw, E1000_HICR);
562                 if (!(hicr & E1000_HICR_C))
563                         break;
564                 msec_delay(1);
565         }
566
567         /* Check for successful FW start. */
568         if (i == E1000_HI_COMMAND_TIMEOUT) {
569                 DEBUGOUT("New FW did not start within timeout period.\n");
570                 return -E1000_ERR_HOST_INTERFACE_COMMAND;
571         }
572
573         return E1000_SUCCESS;
574 }
575
576