[e1000e] Add e1000e driver
[people/pcmattman/gpxe.git] / src / drivers / net / e1000e / e1000e_manage.c
1 /*******************************************************************************
2
3   Intel PRO/1000 Linux driver
4   Copyright(c) 1999 - 2009 Intel Corporation.
5
6   This program is free software; you can redistribute it and/or modify it
7   under the terms and conditions of the GNU General Public License,
8   version 2, as published by the Free Software Foundation.
9
10   This program is distributed in the hope it will be useful, but WITHOUT
11   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13   more details.
14
15   You should have received a copy of the GNU General Public License along with
16   this program; if not, write to the Free Software Foundation, Inc.,
17   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
19   The full GNU General Public License is included in this distribution in
20   the file called "COPYING".
21
22   Contact Information:
23   Linux NICS <linux.nics@intel.com>
24   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
25   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
26
27 *******************************************************************************/
28
29 FILE_LICENCE ( GPL2_OR_LATER );
30
31 #if 0
32
33 #include "e1000e.h"
34
35 static u8 e1000e_calculate_checksum(u8 *buffer, u32 length);
36
37 /**
38  *  e1000e_calculate_checksum - Calculate checksum for buffer
39  *  @buffer: pointer to EEPROM
40  *  @length: size of EEPROM to calculate a checksum for
41  *
42  *  Calculates the checksum for some buffer on a specified length.  The
43  *  checksum calculated is returned.
44  **/
45 static u8 e1000e_calculate_checksum(u8 *buffer, u32 length)
46 {
47         u32 i;
48         u8  sum = 0;
49
50         if (!buffer)
51                 return 0;
52         for (i = 0; i < length; i++)
53                 sum += buffer[i];
54
55         return (u8) (0 - sum);
56 }
57
58 /**
59  *  e1000e_mng_enable_host_if_generic - Checks host interface is enabled
60  *  @hw: pointer to the HW structure
61  *
62  *  Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
63  *
64  *  This function checks whether the HOST IF is enabled for command operation
65  *  and also checks whether the previous command is completed.  It busy waits
66  *  in case of previous command is not completed.
67  **/
68 s32 e1000e_mng_enable_host_if_generic(struct e1000_hw *hw)
69 {
70         u32 hicr;
71         s32 ret_val = E1000_SUCCESS;
72         u8  i;
73
74         /* Check that the host interface is enabled. */
75         hicr = er32(HICR);
76         if ((hicr & E1000_HICR_EN) == 0) {
77                 e_dbg("E1000_HOST_EN bit disabled.\n");
78                 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
79                 goto out;
80         }
81         /* check the previous command is completed */
82         for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
83                 hicr = er32(HICR);
84                 if (!(hicr & E1000_HICR_C))
85                         break;
86                 mdelay(1);
87         }
88
89         if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
90                 e_dbg("Previous command timeout failed .\n");
91                 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
92                 goto out;
93         }
94
95 out:
96         return ret_val;
97 }
98
99 /**
100  *  e1000e_check_mng_mode_generic - Generic check management mode
101  *  @hw: pointer to the HW structure
102  *
103  *  Reads the firmware semaphore register and returns true (>0) if
104  *  manageability is enabled, else false (0).
105  **/
106 bool e1000e_check_mng_mode_generic(struct e1000_hw *hw)
107 {
108         u32 fwsm;
109
110         fwsm = er32(FWSM);
111         return (fwsm & E1000_FWSM_MODE_MASK) ==
112                 (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT);
113 }
114
115 /**
116  *  e1000e_enable_tx_pkt_filtering - Enable packet filtering on TX
117  *  @hw: pointer to the HW structure
118  *
119  *  Enables packet filtering on transmit packets if manageability is enabled
120  *  and host interface is enabled.
121  **/
122 bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw)
123 {
124         struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie;
125         u32 *buffer = (u32 *)&hw->mng_cookie;
126         u32 offset;
127         s32 ret_val, hdr_csum, csum;
128         u8 i, len;
129         bool tx_filter = true;
130
131         /* No manageability, no filtering */
132         if (!hw->mac.ops.check_mng_mode(hw)) {
133                 tx_filter = false;
134                 goto out;
135         }
136
137         /*
138          * If we can't read from the host interface for whatever
139          * reason, disable filtering.
140          */
141         ret_val = hw->mac.ops.mng_enable_host_if(hw);
142         if (ret_val != E1000_SUCCESS) {
143                 tx_filter = false;
144                 goto out;
145         }
146
147         /* Read in the header.  Length and offset are in dwords. */
148         len    = E1000_MNG_DHCP_COOKIE_LENGTH >> 2;
149         offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2;
150         for (i = 0; i < len; i++) {
151                 *(buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw,
152                                                            E1000_HOST_IF,
153                                                            offset + i);
154         }
155         hdr_csum = hdr->checksum;
156         hdr->checksum = 0;
157         csum = e1000e_calculate_checksum((u8 *)hdr,
158                                         E1000_MNG_DHCP_COOKIE_LENGTH);
159         /*
160          * If either the checksums or signature don't match, then
161          * the cookie area isn't considered valid, in which case we
162          * take the safe route of assuming Tx filtering is enabled.
163          */
164         if (hdr_csum != csum)
165                 goto out;
166         if (hdr->signature != E1000_IAMT_SIGNATURE)
167                 goto out;
168
169         /* Cookie area is valid, make the final check for filtering. */
170         if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING))
171                 tx_filter = false;
172
173 out:
174         hw->mac.tx_pkt_filtering = tx_filter;
175         return tx_filter;
176 }
177
178 /**
179  *  e1000e_mng_write_dhcp_info - Writes DHCP info to host interface
180  *  @hw: pointer to the HW structure
181  *  @buffer: pointer to the host interface
182  *  @length: size of the buffer
183  *
184  *  Writes the DHCP information to the host interface.
185  **/
186 s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer,
187                                       u16 length)
188 {
189         struct e1000_host_mng_command_header hdr;
190         s32 ret_val;
191         u32 hicr;
192
193         hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
194         hdr.command_length = length;
195         hdr.reserved1 = 0;
196         hdr.reserved2 = 0;
197         hdr.checksum = 0;
198
199         /* Enable the host interface */
200         ret_val = hw->mac.ops.mng_enable_host_if(hw);
201         if (ret_val)
202                 goto out;
203
204         /* Populate the host interface with the contents of "buffer". */
205         ret_val = hw->mac.ops.mng_host_if_write(hw, buffer, length,
206                                           sizeof(hdr), &(hdr.checksum));
207         if (ret_val)
208                 goto out;
209
210         /* Write the manageability command header */
211         ret_val = hw->mac.ops.mng_write_cmd_header(hw, &hdr);
212         if (ret_val)
213                 goto out;
214
215         /* Tell the ARC a new command is pending. */
216         hicr = er32(HICR);
217         ew32(HICR, hicr | E1000_HICR_C);
218
219 out:
220         return ret_val;
221 }
222
223 /**
224  *  e1000e_mng_write_cmd_header_generic - Writes manageability command header
225  *  @hw: pointer to the HW structure
226  *  @hdr: pointer to the host interface command header
227  *
228  *  Writes the command header after does the checksum calculation.
229  **/
230 s32 e1000e_mng_write_cmd_header_generic(struct e1000_hw *hw,
231                                     struct e1000_host_mng_command_header *hdr)
232 {
233         u16 i, length = sizeof(struct e1000_host_mng_command_header);
234
235         /* Write the whole command header structure with new checksum. */
236
237         hdr->checksum = e1000e_calculate_checksum((u8 *)hdr, length);
238
239         length >>= 2;
240         /* Write the relevant command block into the ram area. */
241         for (i = 0; i < length; i++) {
242                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i,
243                                             *((u32 *) hdr + i));
244                 e1e_flush();
245         }
246
247         return E1000_SUCCESS;
248 }
249
250 /**
251  *  e1000e_mng_host_if_write_generic - Write to the manageability host interface
252  *  @hw: pointer to the HW structure
253  *  @buffer: pointer to the host interface buffer
254  *  @length: size of the buffer
255  *  @offset: location in the buffer to write to
256  *  @sum: sum of the data (not checksum)
257  *
258  *  This function writes the buffer content at the offset given on the host if.
259  *  It also does alignment considerations to do the writes in most efficient
260  *  way.  Also fills up the sum of the buffer in *buffer parameter.
261  **/
262 s32 e1000e_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
263                                     u16 length, u16 offset, u8 *sum)
264 {
265         u8 *tmp;
266         u8 *bufptr = buffer;
267         u32 data = 0;
268         s32 ret_val = E1000_SUCCESS;
269         u16 remaining, i, j, prev_bytes;
270
271         /* sum = only sum of the data and it is not checksum */
272
273         if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) {
274                 ret_val = -E1000_ERR_PARAM;
275                 goto out;
276         }
277
278         tmp = (u8 *)&data;
279         prev_bytes = offset & 0x3;
280         offset >>= 2;
281
282         if (prev_bytes) {
283                 data = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset);
284                 for (j = prev_bytes; j < sizeof(u32); j++) {
285                         *(tmp + j) = *bufptr++;
286                         *sum += *(tmp + j);
287                 }
288                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset, data);
289                 length -= j - prev_bytes;
290                 offset++;
291         }
292
293         remaining = length & 0x3;
294         length -= remaining;
295
296         /* Calculate length in DWORDs */
297         length >>= 2;
298
299         /*
300          * The device driver writes the relevant command block into the
301          * ram area.
302          */
303         for (i = 0; i < length; i++) {
304                 for (j = 0; j < sizeof(u32); j++) {
305                         *(tmp + j) = *bufptr++;
306                         *sum += *(tmp + j);
307                 }
308
309                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i,
310                                             data);
311         }
312         if (remaining) {
313                 for (j = 0; j < sizeof(u32); j++) {
314                         if (j < remaining)
315                                 *(tmp + j) = *bufptr++;
316                         else
317                                 *(tmp + j) = 0;
318
319                         *sum += *(tmp + j);
320                 }
321                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, data);
322         }
323
324 out:
325         return ret_val;
326 }
327
328 /**
329  *  e1000e_enable_mng_pass_thru - Enable processing of ARP's
330  *  @hw: pointer to the HW structure
331  *
332  *  Verifies the hardware needs to allow ARPs to be processed by the host.
333  **/
334 bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw)
335 {
336         u32 manc;
337         u32 fwsm, factps;
338         bool ret_val = false;
339
340         if (!hw->mac.asf_firmware_present)
341                 goto out;
342
343         manc = er32(MANC);
344
345         if (!(manc & E1000_MANC_RCV_TCO_EN) ||
346             !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
347                 goto out;
348
349         if (hw->mac.arc_subsystem_valid) {
350                 fwsm = er32(FWSM);
351                 factps = er32(FACTPS);
352
353                 if (!(factps & E1000_FACTPS_MNGCG) &&
354                     ((fwsm & E1000_FWSM_MODE_MASK) ==
355                      (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) {
356                         ret_val = true;
357                         goto out;
358                 }
359         } else {
360                 if ((manc & E1000_MANC_SMBUS_EN) &&
361                     !(manc & E1000_MANC_ASF_EN)) {
362                         ret_val = true;
363                         goto out;
364                 }
365         }
366
367 out:
368         return ret_val;
369 }
370
371 #endif
372