1
//------------------------------------------------------------------------------
2
// Copyright (c) 2004-2010 Atheros Communications Inc.
3
// All rights reserved.
7
// Permission to use, copy, modify, and/or distribute this software for any
8
// purpose with or without fee is hereby granted, provided that the above
9
// copyright notice and this permission notice appear in all copies.
11
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21
// Author(s): ="Atheros"
22
//------------------------------------------------------------------------------
25
#include "ar6000_drv.h"
29
#include "AR6002/hw2.0/hw/gpio_reg.h"
30
#include "AR6002/hw2.0/hw/si_reg.h"
36
#define MAX_FILENAME 1023
37
#define EEPROM_WAIT_LIMIT 16
39
#define HOST_INTEREST_ITEM_ADDRESS(item) \
40
(AR6002_HOST_INTEREST_ITEM_ADDRESS(item))
46
#define ATH_SOFT_MAC_TMP_BUF_LEN 64
47
unsigned char mac_addr[ATH_MAC_LEN];
48
unsigned char soft_mac_tmp_buf[ATH_SOFT_MAC_TMP_BUF_LEN];
56
static A_UCHAR eeprom_data[EEPROM_SZ];
57
static A_UINT32 sys_sleep_reg;
58
static HIF_DEVICE *p_bmi_device;
66
wmic_ether_aton(const char *orig, A_UINT8 *eth)
72
for(bufp = orig; *bufp != '\0'; ++bufp) {
76
h = hex_to_bin(*bufp++);
79
printk("%s: MAC value is invalid\n", __FUNCTION__);
83
l = hex_to_bin(*bufp++);
85
printk("%s: MAC value is invalid\n", __FUNCTION__);
91
eth[i] = (unsigned char) (val & 0377);
92
if(++i == ATH_MAC_LEN) {
93
/* That's it. Any trailing junk? */
106
update_mac(unsigned char* eeprom, int size, unsigned char* macaddr)
109
A_UINT16* ptr = (A_UINT16*)(eeprom+4);
110
A_UINT16 checksum = 0;
112
memcpy(eeprom+10,macaddr,6);
115
ptr = (A_UINT16*)eeprom;
117
for (i=0; i<size; i+=2) {
120
checksum = ~checksum;
122
ptr = (A_UINT16*)(eeprom+4);
128
/* Read a Target register and return its value. */
130
BMI_read_reg(A_UINT32 address, A_UINT32 *pvalue)
132
BMIReadSOCRegister(p_bmi_device, address, pvalue);
135
/* Write a value to a Target register. */
137
BMI_write_reg(A_UINT32 address, A_UINT32 value)
139
BMIWriteSOCRegister(p_bmi_device, address, value);
142
/* Read Target memory word and return its value. */
144
BMI_read_mem(A_UINT32 address, A_UINT32 *pvalue)
146
BMIReadMemory(p_bmi_device, address, (A_UCHAR*)(pvalue), 4);
149
/* Write a word to a Target memory. */
151
BMI_write_mem(A_UINT32 address, A_UINT8 *p_data, A_UINT32 sz)
153
BMIWriteMemory(p_bmi_device, address, (A_UCHAR*)(p_data), sz);
157
* Enable and configure the Target's Serial Interface
158
* so we can access the EEPROM.
161
enable_SI(HIF_DEVICE *p_device)
165
printk("%s\n", __FUNCTION__);
167
p_bmi_device = p_device;
169
BMI_read_reg(RTC_BASE_ADDRESS+SYSTEM_SLEEP_OFFSET, &sys_sleep_reg);
170
BMI_write_reg(RTC_BASE_ADDRESS+SYSTEM_SLEEP_OFFSET, SYSTEM_SLEEP_DISABLE_SET(1)); //disable system sleep temporarily
172
BMI_read_reg(RTC_BASE_ADDRESS+CLOCK_CONTROL_OFFSET, ®val);
173
regval &= ~CLOCK_CONTROL_SI0_CLK_MASK;
174
BMI_write_reg(RTC_BASE_ADDRESS+CLOCK_CONTROL_OFFSET, regval);
176
BMI_read_reg(RTC_BASE_ADDRESS+RESET_CONTROL_OFFSET, ®val);
177
regval &= ~RESET_CONTROL_SI0_RST_MASK;
178
BMI_write_reg(RTC_BASE_ADDRESS+RESET_CONTROL_OFFSET, regval);
181
BMI_read_reg(GPIO_BASE_ADDRESS+GPIO_PIN0_OFFSET, ®val);
182
regval &= ~GPIO_PIN0_CONFIG_MASK;
183
BMI_write_reg(GPIO_BASE_ADDRESS+GPIO_PIN0_OFFSET, regval);
185
BMI_read_reg(GPIO_BASE_ADDRESS+GPIO_PIN1_OFFSET, ®val);
186
regval &= ~GPIO_PIN1_CONFIG_MASK;
187
BMI_write_reg(GPIO_BASE_ADDRESS+GPIO_PIN1_OFFSET, regval);
189
/* SI_CONFIG = 0x500a6; */
190
regval = SI_CONFIG_BIDIR_OD_DATA_SET(1) |
191
SI_CONFIG_I2C_SET(1) |
192
SI_CONFIG_POS_SAMPLE_SET(1) |
193
SI_CONFIG_INACTIVE_CLK_SET(1) |
194
SI_CONFIG_INACTIVE_DATA_SET(1) |
195
SI_CONFIG_DIVIDER_SET(6);
196
BMI_write_reg(SI_BASE_ADDRESS+SI_CONFIG_OFFSET, regval);
205
printk("%s\n", __FUNCTION__);
207
BMI_write_reg(RTC_BASE_ADDRESS+RESET_CONTROL_OFFSET, RESET_CONTROL_SI0_RST_MASK);
208
BMI_read_reg(RTC_BASE_ADDRESS+CLOCK_CONTROL_OFFSET, ®val);
209
regval |= CLOCK_CONTROL_SI0_CLK_MASK;
210
BMI_write_reg(RTC_BASE_ADDRESS+CLOCK_CONTROL_OFFSET, regval);//Gate SI0 clock
211
BMI_write_reg(RTC_BASE_ADDRESS+SYSTEM_SLEEP_OFFSET, sys_sleep_reg); //restore system sleep setting
215
* Tell the Target to start an 8-byte read from EEPROM,
216
* putting the results in Target RX_DATA registers.
219
request_8byte_read(int offset)
223
// printk("%s: request_8byte_read from offset 0x%x\n", __FUNCTION__, offset);
226
/* SI_TX_DATA0 = read from offset */
228
((offset & 0xff)<<8) |
229
(0xa0 | ((offset & 0xff00)>>7));
231
BMI_write_reg(SI_BASE_ADDRESS+SI_TX_DATA0_OFFSET, regval);
233
regval = SI_CS_START_SET(1) |
234
SI_CS_RX_CNT_SET(8) |
236
BMI_write_reg(SI_BASE_ADDRESS+SI_CS_OFFSET, regval);
240
* Tell the Target to start a 4-byte write to EEPROM,
241
* writing values from Target TX_DATA registers.
244
request_4byte_write(int offset, A_UINT32 data)
248
printk("%s: request_4byte_write (0x%x) to offset 0x%x\n", __FUNCTION__, data, offset);
250
/* SI_TX_DATA0 = write data to offset */
251
regval = ((data & 0xffff) <<16) |
252
((offset & 0xff)<<8) |
253
(0xa0 | ((offset & 0xff00)>>7));
254
BMI_write_reg(SI_BASE_ADDRESS+SI_TX_DATA0_OFFSET, regval);
257
BMI_write_reg(SI_BASE_ADDRESS+SI_TX_DATA1_OFFSET, regval);
259
regval = SI_CS_START_SET(1) |
260
SI_CS_RX_CNT_SET(0) |
262
BMI_write_reg(SI_BASE_ADDRESS+SI_CS_OFFSET, regval);
266
* Check whether or not an EEPROM request that was started
267
* earlier has completed yet.
270
request_in_progress(void)
274
/* Wait for DONE_INT in SI_CS */
275
BMI_read_reg(SI_BASE_ADDRESS+SI_CS_OFFSET, ®val);
277
// printk("%s: request in progress SI_CS=0x%x\n", __FUNCTION__, regval);
278
if (regval & SI_CS_DONE_ERR_MASK) {
279
printk("%s: EEPROM signaled ERROR (0x%x)\n", __FUNCTION__, regval);
282
return (!(regval & SI_CS_DONE_INT_MASK));
286
* try to detect the type of EEPROM,16bit address or 8bit address
289
static void eeprom_type_detect(void)
294
request_8byte_read(0x100);
295
/* Wait for DONE_INT in SI_CS */
297
BMI_read_reg(SI_BASE_ADDRESS+SI_CS_OFFSET, ®val);
298
if (regval & SI_CS_DONE_ERR_MASK) {
299
printk("%s: ERROR : address type was wrongly set\n", __FUNCTION__);
302
if (i++ == EEPROM_WAIT_LIMIT) {
303
printk("%s: EEPROM not responding\n", __FUNCTION__);
305
} while(!(regval & SI_CS_DONE_INT_MASK));
309
* Extract the results of a completed EEPROM Read request
310
* and return them to the caller.
313
read_8byte_results(A_UINT32 *data)
315
/* Read SI_RX_DATA0 and SI_RX_DATA1 */
316
BMI_read_reg(SI_BASE_ADDRESS+SI_RX_DATA0_OFFSET, &data[0]);
317
BMI_read_reg(SI_BASE_ADDRESS+SI_RX_DATA1_OFFSET, &data[1]);
322
* Wait for a previously started command to complete.
323
* Timeout if the command is takes "too long".
326
wait_for_eeprom_completion(void)
330
while (request_in_progress()) {
331
if (i++ == EEPROM_WAIT_LIMIT) {
332
printk("%s: EEPROM not responding\n", __FUNCTION__);
338
* High-level function which starts an 8-byte read,
339
* waits for it to complete, and returns the result.
342
fetch_8bytes(int offset, A_UINT32 *data)
344
request_8byte_read(offset);
345
wait_for_eeprom_completion();
346
read_8byte_results(data);
348
/* Clear any pending intr */
349
BMI_write_reg(SI_BASE_ADDRESS+SI_CS_OFFSET, SI_CS_DONE_INT_MASK);
353
* High-level function which starts a 4-byte write,
354
* and waits for it to complete.
357
commit_4bytes(int offset, A_UINT32 data)
359
request_4byte_write(offset, data);
360
wait_for_eeprom_completion();
364
void eeprom_ar6000_transfer(HIF_DEVICE *device, char *fake_file, char *p_mac)
367
A_UINT32 board_data_addr;
370
printk("%s: Enter\n", __FUNCTION__);
373
eeprom_type_detect();
377
* Transfer from file to Target RAM.
378
* Fetch source data from file.
382
struct inode *inode = NULL;
388
filp = filp_open(fake_file, O_RDONLY, S_IRUSR);
391
printk("%s: file %s filp_open error\n", __FUNCTION__, fake_file);
397
printk("%s: File Operation Method Error\n", __FUNCTION__);
398
filp_close(filp, NULL);
403
inode = GET_INODE_FROM_FILEP(filep);
405
printk("%s: Get inode from filp failed\n", __FUNCTION__);
406
filp_close(filp, NULL);
411
printk("%s file offset opsition: %xh\n", __FUNCTION__, (unsigned)filp->f_pos);
414
length = i_size_read(inode->i_mapping->host);
415
printk("%s: length=%d\n", __FUNCTION__, length);
416
if (length != EEPROM_SZ) {
417
printk("%s: The file's size is not as expected\n", __FUNCTION__);
418
filp_close(filp, NULL);
424
if (filp->f_op->read(filp, eeprom_data, length, &filp->f_pos) != length) {
425
printk("%s: file read error\n", __FUNCTION__);
426
filp_close(filp, NULL);
431
/* read data out successfully */
432
filp_close(filp, NULL);
436
* Read from EEPROM to file OR transfer from EEPROM to Target RAM.
437
* Fetch EEPROM_SZ Bytes of Board Data, 8 bytes at a time.
440
fetch_8bytes(0, (A_UINT32 *)(&eeprom_data[0]));
442
/* Check the first word of EEPROM for validity */
443
first_word = *((A_UINT32 *)eeprom_data);
445
if ((first_word == 0) || (first_word == 0xffffffff)) {
446
printk("Did not find EEPROM with valid Board Data.\n");
449
for (i=8; i<EEPROM_SZ; i+=8) {
450
fetch_8bytes(i, (A_UINT32 *)(&eeprom_data[i]));
459
struct inode *inode = NULL;
465
filp = filp_open(p_mac, O_RDONLY, S_IRUSR);
467
printk("%s try to open file %s\n", __FUNCTION__, p_mac);
470
printk("%s: file %s filp_open error\n", __FUNCTION__, p_mac);
476
printk("%s: File Operation Method Error\n", __FUNCTION__);
477
filp_close(filp, NULL);
482
inode = GET_INODE_FROM_FILEP(filep);
484
printk("%s: Get inode from filp failed\n", __FUNCTION__);
485
filp_close(filp, NULL);
490
printk("%s file offset opsition: %xh\n", __FUNCTION__, (unsigned)filp->f_pos);
493
length = i_size_read(inode->i_mapping->host);
494
printk("%s: length=%d\n", __FUNCTION__, length);
495
if (length > ATH_SOFT_MAC_TMP_BUF_LEN) {
496
printk("%s: MAC file's size is not as expected\n", __FUNCTION__);
497
filp_close(filp, NULL);
503
if (filp->f_op->read(filp, soft_mac_tmp_buf, length, &filp->f_pos) != length) {
504
printk("%s: file read error\n", __FUNCTION__);
505
filp_close(filp, NULL);
511
/* the data we just read */
512
printk("%s: mac address from the file:\n", __FUNCTION__);
513
for (i = 0; i < length; i++)
514
printk("[%c(0x%x)],", soft_mac_tmp_buf[i], soft_mac_tmp_buf[i]);
518
/* read data out successfully */
519
filp_close(filp, NULL);
522
/* convert mac address */
523
if (!wmic_ether_aton(soft_mac_tmp_buf, mac_addr)) {
524
printk("%s: convert mac value fail\n", __FUNCTION__);
529
/* the converted mac address */
530
printk("%s: the converted mac value\n", __FUNCTION__);
531
for (i = 0; i < ATH_MAC_LEN; i++)
532
printk("[0x%x],", mac_addr[i]);
538
/* Determine where in Target RAM to write Board Data */
539
BMI_read_mem( HOST_INTEREST_ITEM_ADDRESS(hi_board_data), &board_data_addr);
540
if (board_data_addr == 0) {
541
printk("hi_board_data is zero\n");
546
/* Update MAC address in RAM */
548
update_mac(eeprom_data, EEPROM_SZ, mac_addr);
552
/* mac address in eeprom array */
553
printk("%s: mac values in eeprom array\n", __FUNCTION__);
554
for (i = 10; i < 10 + 6; i++)
555
printk("[0x%x],", eeprom_data[i]);
560
/* Write EEPROM data to Target RAM */
561
BMI_write_mem(board_data_addr, ((A_UINT8 *)eeprom_data), EEPROM_SZ);
563
/* Record the fact that Board Data IS initialized */
566
BMI_write_mem(HOST_INTEREST_ITEM_ADDRESS(hi_board_data_initialized),
567
(A_UINT8 *)&one, sizeof(A_UINT32));