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));