e100_eeprom.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:18k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*******************************************************************************
  2.   
  3.   Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
  4.   
  5.   This program is free software; you can redistribute it and/or modify it 
  6.   under the terms of the GNU General Public License as published by the Free 
  7.   Software Foundation; either version 2 of the License, or (at your option) 
  8.   any later version.
  9.   
  10.   This program is distributed in the hope that 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., 59 
  17.   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.   
  19.   The full GNU General Public License is included in this distribution in the
  20.   file called LICENSE.
  21.   
  22.   Contact Information:
  23.   Linux NICS <linux.nics@intel.com>
  24.   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  25. *******************************************************************************/
  26. /**********************************************************************
  27. *                                                                     *
  28. * INTEL CORPORATION                                                   *
  29. *                                                                     *
  30. * This software is supplied under the terms of the license included   *
  31. * above.  All use of this driver must be in accordance with the terms *
  32. * of that license.                                                    *
  33. *                                                                     *
  34. * Module Name:  e100_eeprom.c                                         *
  35. *                                                                     *
  36. * Abstract:     This module contains routines to read and write to a  *
  37. *               serial EEPROM                                         *
  38. *                                                                     *
  39. * Environment:  This file is intended to be specific to the Linux     *
  40. *               operating system.                                     *
  41. *                                                                     *
  42. **********************************************************************/
  43. #include "e100.h"
  44. #define CSR_EEPROM_CONTROL_FIELD(bdp) ((bdp)->scb->scb_eprm_cntrl)
  45. #define CSR_GENERAL_CONTROL2_FIELD(bdp) 
  46.            ((bdp)->scb->scb_ext.d102_scb.scb_gen_ctrl2)
  47. #define EEPROM_STALL_TIME 4
  48. #define EEPROM_CHECKSUM ((u16) 0xBABA)
  49. #define EEPROM_MAX_WORD_SIZE 256
  50. void e100_eeprom_cleanup(struct e100_private *adapter);
  51. u16 e100_eeprom_calculate_chksum(struct e100_private *adapter);
  52. static void e100_eeprom_write_word(struct e100_private *adapter, u16 reg,
  53.    u16 data);
  54. void e100_eeprom_write_block(struct e100_private *adapter, u16 start, u16 *data,
  55.      u16 size);
  56. u16 e100_eeprom_size(struct e100_private *adapter);
  57. u16 e100_eeprom_read(struct e100_private *adapter, u16 reg);
  58. static void shift_out_bits(struct e100_private *adapter, u16 data, u16 count);
  59. static u16 shift_in_bits(struct e100_private *adapter);
  60. static void raise_clock(struct e100_private *adapter, u16 *x);
  61. static void lower_clock(struct e100_private *adapter, u16 *x);
  62. static u16 eeprom_wait_cmd_done(struct e100_private *adapter);
  63. static void eeprom_stand_by(struct e100_private *adapter);
  64. //----------------------------------------------------------------------------------------
  65. // Procedure:   eeprom_set_semaphore
  66. //
  67. // Description: This function set (write 1) Gamla EEPROM semaphore bit (bit 23 word 0x1C in the CSR).
  68. //
  69. // Arguments:
  70. //      Adapter                 - Adapter context
  71. //
  72. // Returns:  true if success
  73. //           else return false 
  74. //
  75. //----------------------------------------------------------------------------------------
  76. inline u8
  77. eeprom_set_semaphore(struct e100_private *adapter)
  78. {
  79. u16 data = 0;
  80. unsigned long expiration_time = jiffies + HZ / 100 + 1;
  81. do {
  82. // Get current value of General Control 2
  83. data = readb(&CSR_GENERAL_CONTROL2_FIELD(adapter));
  84. // Set bit 23 word 0x1C in the CSR.
  85. data |= SCB_GCR2_EEPROM_ACCESS_SEMAPHORE;
  86. writeb(data, &CSR_GENERAL_CONTROL2_FIELD(adapter));
  87. // Check to see if this bit set or not.
  88. data = readb(&CSR_GENERAL_CONTROL2_FIELD(adapter));
  89. if (data & SCB_GCR2_EEPROM_ACCESS_SEMAPHORE) {
  90. return true;
  91. }
  92. if (time_before(jiffies, expiration_time))
  93. yield();
  94. else
  95. return false;
  96. } while (true);
  97. }
  98. //----------------------------------------------------------------------------------------
  99. // Procedure:   eeprom_reset_semaphore
  100. //
  101. // Description: This function reset (write 0) Gamla EEPROM semaphore bit 
  102. //              (bit 23 word 0x1C in the CSR).
  103. //
  104. // Arguments:  struct e100_private * adapter - Adapter context
  105. //----------------------------------------------------------------------------------------
  106. inline void
  107. eeprom_reset_semaphore(struct e100_private *adapter)
  108. {
  109. u16 data = 0;
  110. data = readb(&CSR_GENERAL_CONTROL2_FIELD(adapter));
  111. data &= ~(SCB_GCR2_EEPROM_ACCESS_SEMAPHORE);
  112. writeb(data, &CSR_GENERAL_CONTROL2_FIELD(adapter));
  113. }
  114. //----------------------------------------------------------------------------------------
  115. // Procedure:   e100_eeprom_size
  116. //
  117. // Description: This routine determines the size of the EEPROM.  This value should be
  118. //              checked for validity - ie. is it too big or too small.  The size returned
  119. //              is then passed to the read/write functions.
  120. //
  121. // Returns:
  122. //      Size of the eeprom, or zero if an error occured
  123. //----------------------------------------------------------------------------------------
  124. u16
  125. e100_eeprom_size(struct e100_private *adapter)
  126. {
  127. u16 x, size = 1; // must be one to accumulate a product
  128. // if we've already stored this data, read from memory
  129. if (adapter->eeprom_size) {
  130. return adapter->eeprom_size;
  131. }
  132. // otherwise, read from the eeprom
  133. // Set EEPROM semaphore.
  134. if (adapter->rev_id >= D102_REV_ID) {
  135. if (!eeprom_set_semaphore(adapter))
  136. return 0;
  137. }
  138. // enable the eeprom by setting EECS.
  139. x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
  140. x &= ~(EEDI | EEDO | EESK);
  141. x |= EECS;
  142. writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
  143. // write the read opcode
  144. shift_out_bits(adapter, EEPROM_READ_OPCODE, 3);
  145. // experiment to discover the size of the eeprom.  request register zero
  146. // and wait for the eeprom to tell us it has accepted the entire address.
  147. x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
  148. do {
  149. size *= 2; // each bit of address doubles eeprom size
  150. x |= EEDO; // set bit to detect "dummy zero"
  151. x &= ~EEDI; // address consists of all zeros
  152. writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
  153. readw(&(adapter->scb->scb_status));
  154. udelay(EEPROM_STALL_TIME);
  155. raise_clock(adapter, &x);
  156. lower_clock(adapter, &x);
  157. // check for "dummy zero"
  158. x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
  159. if (size > EEPROM_MAX_WORD_SIZE) {
  160. size = 0;
  161. break;
  162. }
  163. } while (x & EEDO);
  164. // read in the value requested
  165. (void) shift_in_bits(adapter);
  166. e100_eeprom_cleanup(adapter);
  167. // Clear EEPROM Semaphore.
  168. if (adapter->rev_id >= D102_REV_ID) {
  169. eeprom_reset_semaphore(adapter);
  170. }
  171. return size;
  172. }
  173. //----------------------------------------------------------------------------------------
  174. // Procedure:   eeprom_address_size
  175. //
  176. // Description: determines the number of bits in an address for the eeprom acceptable
  177. //              values are 64, 128, and 256
  178. // Arguments: size of the eeprom
  179. // Returns: bits in an address for that size eeprom
  180. //----------------------------------------------------------------------------------------
  181. static inline int
  182. eeprom_address_size(u16 size)
  183. {
  184. int isize = size;
  185. return (ffs(isize) - 1);
  186. }
  187. //----------------------------------------------------------------------------------------
  188. // Procedure:   e100_eeprom_read
  189. //
  190. // Description: This routine serially reads one word out of the EEPROM.
  191. //
  192. // Arguments:
  193. //      adapter - our adapter context
  194. //      reg - EEPROM word to read.
  195. //
  196. // Returns:
  197. //      Contents of EEPROM word (reg).
  198. //----------------------------------------------------------------------------------------
  199. u16
  200. e100_eeprom_read(struct e100_private *adapter, u16 reg)
  201. {
  202. u16 x, data, bits;
  203. // Set EEPROM semaphore.
  204. if (adapter->rev_id >= D102_REV_ID) {
  205. if (!eeprom_set_semaphore(adapter))
  206. return 0;
  207. }
  208. // eeprom size is initialized to zero
  209. if (!adapter->eeprom_size)
  210. adapter->eeprom_size = e100_eeprom_size(adapter);
  211. bits = eeprom_address_size(adapter->eeprom_size);
  212. // select EEPROM, reset bits, set EECS
  213. x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
  214. x &= ~(EEDI | EEDO | EESK);
  215. x |= EECS;
  216. writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
  217. // write the read opcode and register number in that order
  218. // The opcode is 3bits in length, reg is 'bits' bits long
  219. shift_out_bits(adapter, EEPROM_READ_OPCODE, 3);
  220. shift_out_bits(adapter, reg, bits);
  221. // Now read the data (16 bits) in from the selected EEPROM word
  222. data = shift_in_bits(adapter);
  223. e100_eeprom_cleanup(adapter);
  224. // Clear EEPROM Semaphore.
  225. if (adapter->rev_id >= D102_REV_ID) {
  226. eeprom_reset_semaphore(adapter);
  227. }
  228. return data;
  229. }
  230. //----------------------------------------------------------------------------------------
  231. // Procedure:   shift_out_bits
  232. //
  233. // Description: This routine shifts data bits out to the EEPROM.
  234. //
  235. // Arguments:
  236. //      data - data to send to the EEPROM.
  237. //      count - number of data bits to shift out.
  238. //
  239. // Returns: (none)
  240. //----------------------------------------------------------------------------------------
  241. static void
  242. shift_out_bits(struct e100_private *adapter, u16 data, u16 count)
  243. {
  244. u16 x, mask;
  245. mask = 1 << (count - 1);
  246. x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
  247. x &= ~(EEDO | EEDI);
  248. do {
  249. x &= ~EEDI;
  250. if (data & mask)
  251. x |= EEDI;
  252. writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
  253. readw(&(adapter->scb->scb_status)); /* flush command to card */
  254. udelay(EEPROM_STALL_TIME);
  255. raise_clock(adapter, &x);
  256. lower_clock(adapter, &x);
  257. mask = mask >> 1;
  258. } while (mask);
  259. x &= ~EEDI;
  260. writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
  261. }
  262. //----------------------------------------------------------------------------------------
  263. // Procedure:   raise_clock
  264. //
  265. // Description: This routine raises the EEPROM's clock input (EESK)
  266. //
  267. // Arguments:
  268. //      x - Ptr to the EEPROM control register's current value
  269. //
  270. // Returns: (none)
  271. //----------------------------------------------------------------------------------------
  272. void
  273. raise_clock(struct e100_private *adapter, u16 *x)
  274. {
  275. *x = *x | EESK;
  276. writew(*x, &CSR_EEPROM_CONTROL_FIELD(adapter));
  277. readw(&(adapter->scb->scb_status)); /* flush command to card */
  278. udelay(EEPROM_STALL_TIME);
  279. }
  280. //----------------------------------------------------------------------------------------
  281. // Procedure:   lower_clock
  282. //
  283. // Description: This routine lower's the EEPROM's clock input (EESK)
  284. //
  285. // Arguments:
  286. //      x - Ptr to the EEPROM control register's current value
  287. //
  288. // Returns: (none)
  289. //----------------------------------------------------------------------------------------
  290. void
  291. lower_clock(struct e100_private *adapter, u16 *x)
  292. {
  293. *x = *x & ~EESK;
  294. writew(*x, &CSR_EEPROM_CONTROL_FIELD(adapter));
  295. readw(&(adapter->scb->scb_status)); /* flush command to card */
  296. udelay(EEPROM_STALL_TIME);
  297. }
  298. //----------------------------------------------------------------------------------------
  299. // Procedure:   shift_in_bits
  300. //
  301. // Description: This routine shifts data bits in from the EEPROM.
  302. //
  303. // Arguments:
  304. //
  305. // Returns:
  306. //      The contents of that particular EEPROM word
  307. //----------------------------------------------------------------------------------------
  308. static u16
  309. shift_in_bits(struct e100_private *adapter)
  310. {
  311. u16 x, d, i;
  312. x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
  313. x &= ~(EEDO | EEDI);
  314. d = 0;
  315. for (i = 0; i < 16; i++) {
  316. d <<= 1;
  317. raise_clock(adapter, &x);
  318. x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
  319. x &= ~EEDI;
  320. if (x & EEDO)
  321. d |= 1;
  322. lower_clock(adapter, &x);
  323. }
  324. return d;
  325. }
  326. //----------------------------------------------------------------------------------------
  327. // Procedure:   e100_eeprom_cleanup
  328. //
  329. // Description: This routine returns the EEPROM to an idle state
  330. //----------------------------------------------------------------------------------------
  331. void
  332. e100_eeprom_cleanup(struct e100_private *adapter)
  333. {
  334. u16 x;
  335. x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
  336. x &= ~(EECS | EEDI);
  337. writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
  338. raise_clock(adapter, &x);
  339. lower_clock(adapter, &x);
  340. }
  341. //**********************************************************************************
  342. // Procedure:   e100_eeprom_update_chksum
  343. //
  344. // Description: Calculates the checksum and writes it to the EEProm. 
  345. //              It calculates the checksum accroding to the formula: 
  346. //                              Checksum = 0xBABA - (sum of first 63 words).
  347. //
  348. //-----------------------------------------------------------------------------------
  349. u16
  350. e100_eeprom_calculate_chksum(struct e100_private *adapter)
  351. {
  352. u16 idx, xsum_index, checksum = 0;
  353. // eeprom size is initialized to zero
  354. if (!adapter->eeprom_size)
  355. adapter->eeprom_size = e100_eeprom_size(adapter);
  356. xsum_index = adapter->eeprom_size - 1;
  357. for (idx = 0; idx < xsum_index; idx++)
  358. checksum += e100_eeprom_read(adapter, idx);
  359. checksum = EEPROM_CHECKSUM - checksum;
  360. return checksum;
  361. }
  362. //----------------------------------------------------------------------------------------
  363. // Procedure:   e100_eeprom_write_word
  364. //
  365. // Description: This routine writes a word to a specific EEPROM location without.
  366. //              taking EEPROM semaphore and updating checksum. 
  367. //              Use e100_eeprom_write_block for the EEPROM update
  368. // Arguments: reg - The EEPROM word that we are going to write to.
  369. //            data - The data (word) that we are going to write to the EEPROM.
  370. //----------------------------------------------------------------------------------------
  371. static void
  372. e100_eeprom_write_word(struct e100_private *adapter, u16 reg, u16 data)
  373. {
  374. u16 x;
  375. u16 bits;
  376. bits = eeprom_address_size(adapter->eeprom_size);
  377. /* select EEPROM, mask off ASIC and reset bits, set EECS */
  378. x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
  379. x &= ~(EEDI | EEDO | EESK);
  380. writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
  381. readw(&(adapter->scb->scb_status)); /* flush command to card */
  382. udelay(EEPROM_STALL_TIME);
  383. x |= EECS;
  384. writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
  385. shift_out_bits(adapter, EEPROM_EWEN_OPCODE, 5);
  386. shift_out_bits(adapter, reg, (u16) (bits - 2));
  387. if (!eeprom_wait_cmd_done(adapter))
  388. return;
  389. /* write the new word to the EEPROM & send the write opcode the EEPORM */
  390. shift_out_bits(adapter, EEPROM_WRITE_OPCODE, 3);
  391. /* select which word in the EEPROM that we are writing to */
  392. shift_out_bits(adapter, reg, bits);
  393. /* write the data to the selected EEPROM word */
  394. shift_out_bits(adapter, data, 16);
  395. if (!eeprom_wait_cmd_done(adapter))
  396. return;
  397. shift_out_bits(adapter, EEPROM_EWDS_OPCODE, 5);
  398. shift_out_bits(adapter, reg, (u16) (bits - 2));
  399. if (!eeprom_wait_cmd_done(adapter))
  400. return;
  401. e100_eeprom_cleanup(adapter);
  402. }
  403. //----------------------------------------------------------------------------------------
  404. // Procedure:   e100_eeprom_write_block
  405. //
  406. // Description: This routine writes a block of words starting from specified EEPROM 
  407. //              location and updates checksum
  408. // Arguments: reg - The EEPROM word that we are going to write to.
  409. //            data - The data (word) that we are going to write to the EEPROM.
  410. //----------------------------------------------------------------------------------------
  411. void
  412. e100_eeprom_write_block(struct e100_private *adapter, u16 start, u16 *data,
  413. u16 size)
  414. {
  415. u16 checksum;
  416. u16 i;
  417. if (!adapter->eeprom_size)
  418. adapter->eeprom_size = e100_eeprom_size(adapter);
  419. // Set EEPROM semaphore.
  420. if (adapter->rev_id >= D102_REV_ID) {
  421. if (!eeprom_set_semaphore(adapter))
  422. return;
  423. }
  424. for (i = 0; i < size; i++) {
  425. e100_eeprom_write_word(adapter, start + i, data[i]);
  426. }
  427. //Update checksum
  428. checksum = e100_eeprom_calculate_chksum(adapter);
  429. e100_eeprom_write_word(adapter, (adapter->eeprom_size - 1), checksum);
  430. // Clear EEPROM Semaphore.
  431. if (adapter->rev_id >= D102_REV_ID) {
  432. eeprom_reset_semaphore(adapter);
  433. }
  434. }
  435. //----------------------------------------------------------------------------------------
  436. // Procedure:   eeprom_wait_cmd_done
  437. //
  438. // Description: This routine waits for the the EEPROM to finish its command.  
  439. //                              Specifically, it waits for EEDO (data out) to go high.
  440. // Returns:     true - If the command finished
  441. //              false - If the command never finished (EEDO stayed low)
  442. //----------------------------------------------------------------------------------------
  443. static u16
  444. eeprom_wait_cmd_done(struct e100_private *adapter)
  445. {
  446. u16 x;
  447. unsigned long expiration_time = jiffies + HZ / 100 + 1;
  448. eeprom_stand_by(adapter);
  449. do {
  450. rmb();
  451. x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
  452. if (x & EEDO)
  453. return true;
  454. if (time_before(jiffies, expiration_time))
  455. yield();
  456. else
  457. return false;
  458. } while (true);
  459. }
  460. //----------------------------------------------------------------------------------------
  461. // Procedure:   eeprom_stand_by
  462. //
  463. // Description: This routine lowers the EEPROM chip select (EECS) for a few microseconds.
  464. //----------------------------------------------------------------------------------------
  465. static void
  466. eeprom_stand_by(struct e100_private *adapter)
  467. {
  468. u16 x;
  469. x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
  470. x &= ~(EECS | EESK);
  471. writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
  472. readw(&(adapter->scb->scb_status)); /* flush command to card */
  473. udelay(EEPROM_STALL_TIME);
  474. x |= EECS;
  475. writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
  476. readw(&(adapter->scb->scb_status)); /* flush command to card */
  477. udelay(EEPROM_STALL_TIME);
  478. }