e100_config.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_config.c                                         *
  35. *                                                                     *
  36. * Abstract:     Functions for configuring the network adapter.        *
  37. *                                                                     *
  38. * Environment:  This file is intended to be specific to the Linux     *
  39. *               operating system.                                     *
  40. *                                                                     *
  41. **********************************************************************/
  42. #include "e100_config.h"
  43. static void e100_config_long_rx(struct e100_private *bdp, unsigned char enable);
  44. static const u8 def_config[] = {
  45. CB_CFIG_BYTE_COUNT,
  46. 0x08, 0x00, 0x00, 0x00, 0x00, 0x32, 0x07, 0x01,
  47. 0x00, 0x2e, 0x00, 0x60, 0x00, 0xf2, 0xc8, 0x00,
  48. 0x40, 0xf2, 0x80, 0x3f, 0x05
  49. };
  50. /**
  51.  * e100_config_init_82557 - config the 82557 adapter
  52.  * @bdp: atapter's private data struct
  53.  *
  54.  * This routine will initialize the 82557 configure block.
  55.  * All other init functions will only set values that are
  56.  * different from the 82557 default.
  57.  */
  58. static void __devinit
  59. e100_config_init_82557(struct e100_private *bdp)
  60. {
  61. /* initialize config block */
  62. memcpy(bdp->config, def_config, sizeof (def_config));
  63. bdp->config[0] = CB_CFIG_BYTE_COUNT; /* just in case */
  64. e100_config_ifs(bdp);
  65. /*
  66.  * Enable extended statistical counters (82558 and up) and TCO counters
  67.  * (82559 and up) and set the statistical counters' mode in bdp 
  68.  *  
  69.  *  stat. mode      |    TCO stat. bit (2)  |  Extended stat. bit (5)
  70.  * ------------------------------------------------------------------
  71.  *  Basic (557)     |       0               |         1
  72.  * ------------------------------------------------------------------
  73.  *  Extended (558)  |       0               |         0
  74.  * ------------------------------------------------------------------
  75.  *  TCO (559)       |       1               |         1
  76.  * ------------------------------------------------------------------
  77.  *  Reserved        |       1               |         0
  78.  * ------------------------------------------------------------------
  79.  */
  80. bdp->config[6] &= ~CB_CFIG_TCO_STAT;
  81. bdp->config[6] |= CB_CFIG_EXT_STAT_DIS;
  82. bdp->stat_mode = E100_BASIC_STATS;
  83. /* Setup for MII or 503 operation.  The CRS+CDT bit should only be set */
  84. /* when operating in 503 mode. */
  85. if (bdp->phy_addr == 32) {
  86. bdp->config[8] &= ~CB_CFIG_503_MII;
  87. bdp->config[15] |= CB_CFIG_CRS_OR_CDT;
  88. } else {
  89. bdp->config[8] |= CB_CFIG_503_MII;
  90. bdp->config[15] &= ~CB_CFIG_CRS_OR_CDT;
  91. }
  92. e100_config_fc(bdp);
  93. e100_config_force_dplx(bdp);
  94. e100_config_promisc(bdp, false);
  95. e100_config_mulcast_enbl(bdp, false);
  96. }
  97. static void __devinit
  98. e100_config_init_82558(struct e100_private *bdp)
  99. {
  100. /* MWI enable. This should be turned on only if the adapter is a 82558/9
  101.  * and if the PCI command reg. has enabled the MWI bit. */
  102. bdp->config[3] |= CB_CFIG_MWI_EN;
  103. bdp->config[6] &= ~CB_CFIG_EXT_TCB_DIS;
  104. if (bdp->rev_id >= D101MA_REV_ID) {
  105. /* this is 82559 and up - enable TCO counters */
  106. bdp->config[6] |= CB_CFIG_TCO_STAT;
  107. bdp->config[6] |= CB_CFIG_EXT_STAT_DIS;
  108. bdp->stat_mode = E100_TCO_STATS;
  109. if ((bdp->rev_id < D102_REV_ID) &&
  110.     (bdp->params.b_params & PRM_XSUMRX) &&
  111.     (bdp->pdev->device != 0x1209)) {
  112. bdp->flags |= DF_CSUM_OFFLOAD;
  113. bdp->config[9] |= 1;
  114. }
  115. } else {
  116. /* this is 82558 */
  117. bdp->config[6] &= ~CB_CFIG_TCO_STAT;
  118. bdp->config[6] &= ~CB_CFIG_EXT_STAT_DIS;
  119. bdp->stat_mode = E100_EXTENDED_STATS;
  120. }
  121. e100_config_long_rx(bdp, true);
  122. }
  123. static void __devinit
  124. e100_config_init_82550(struct e100_private *bdp)
  125. {
  126. /* The D102 chip allows for 32 config bytes.  This value is
  127.  * supposed to be in Byte 0.  Just add the extra bytes to
  128.  * what was already setup in the block. */
  129. bdp->config[0] += CB_CFIG_D102_BYTE_COUNT;
  130. /* now we need to enable the extended RFD.  When this is
  131.  * enabled, the immediated receive data buffer starts at offset
  132.  * 32 from the RFD base address, instead of at offset 16. */
  133. bdp->config[7] |= CB_CFIG_EXTENDED_RFD;
  134. /* put the chip into D102 receive mode.  This is neccessary
  135.  * for any parsing and offloading features. */
  136. bdp->config[22] = CB_CFIG_RECEIVE_GAMLA_MODE;
  137. /* set the flag if checksum offloading was enabled */
  138. if (bdp->params.b_params & PRM_XSUMRX) {
  139. bdp->flags |= DF_CSUM_OFFLOAD;
  140. }
  141. }
  142. /* Initialize the adapter's configure block */
  143. void __devinit
  144. e100_config_init(struct e100_private *bdp)
  145. {
  146. e100_config_init_82557(bdp);
  147. if (bdp->flags & IS_BACHELOR)
  148. e100_config_init_82558(bdp);
  149. if (bdp->rev_id >= D102_REV_ID)
  150. e100_config_init_82550(bdp);
  151. }
  152. /**
  153.  * e100_force_config - force a configure command
  154.  * @bdp: atapter's private data struct
  155.  *
  156.  * This routine will force a configure command to the adapter.
  157.  * The command will be executed in polled mode as interrupts
  158.  * are _disabled_ at this time.
  159.  *
  160.  * Returns:
  161.  *      true: if the configure command was successfully issued and completed
  162.  *      false: otherwise
  163.  */
  164. unsigned char
  165. e100_force_config(struct e100_private *bdp)
  166. {
  167. spin_lock_bh(&(bdp->config_lock));
  168. bdp->config[0] = CB_CFIG_BYTE_COUNT;
  169. if (bdp->rev_id >= D102_REV_ID) {
  170. /* The D102 chip allows for 32 config bytes.  This value is
  171.    supposed to be in Byte 0.  Just add the extra bytes to
  172.    what was already setup in the block. */
  173. bdp->config[0] += CB_CFIG_D102_BYTE_COUNT;
  174. }
  175. spin_unlock_bh(&(bdp->config_lock));
  176. // although we call config outside the lock, there is no
  177. // race condition because config byte count has maximum value
  178. return e100_config(bdp);
  179. }
  180. /**
  181.  * e100_config - issue a configure command
  182.  * @bdp: atapter's private data struct
  183.  *
  184.  * This routine will issue a configure command to the 82557.
  185.  * This command will be executed in polled mode as interrupts
  186.  * are _disabled_ at this time.
  187.  *
  188.  * Returns:
  189.  *      true: if the configure command was successfully issued and completed
  190.  *      false: otherwise
  191.  */
  192. unsigned char
  193. e100_config(struct e100_private *bdp)
  194. {
  195. cb_header_t *pntcb_hdr;
  196. unsigned char res = true;
  197. nxmit_cb_entry_t *cmd;
  198. if (bdp->config[0] == 0) {
  199. goto exit;
  200. }
  201. if ((cmd = e100_alloc_non_tx_cmd(bdp)) == NULL) {
  202. res = false;
  203. goto exit;
  204. }
  205. pntcb_hdr = (cb_header_t *) cmd->non_tx_cmd;
  206. pntcb_hdr->cb_cmd = __constant_cpu_to_le16(CB_CONFIGURE);
  207. spin_lock_bh(&bdp->config_lock);
  208. if (bdp->config[0] < CB_CFIG_MIN_PARAMS) {
  209. bdp->config[0] = CB_CFIG_MIN_PARAMS;
  210. }
  211. /* Copy the device's config block to the device's memory */
  212. memcpy(cmd->non_tx_cmd->ntcb.config.cfg_byte, bdp->config,
  213.        bdp->config[0]);
  214. /* reset number of bytes to config next time */
  215. bdp->config[0] = 0;
  216. spin_unlock_bh(&bdp->config_lock);
  217. res = e100_exec_non_cu_cmd(bdp, cmd);
  218. exit:
  219. if (netif_running(bdp->device))
  220. netif_wake_queue(bdp->device);
  221. return res;
  222. }
  223. /**
  224.  * e100_config_fc - config flow-control state
  225.  * @bdp: adapter's private data struct
  226.  *
  227.  * This routine will enable or disable flow control support in the adapter's
  228.  * config block. Flow control will be enable only if requested using the command
  229.  * line option, and if the link is flow-contorl capable (both us and the link
  230.  * partner). But, if link partner is capable of autoneg, but not capable of
  231.  * flow control, received PAUSE frames are still honored.
  232.  */
  233. void
  234. e100_config_fc(struct e100_private *bdp)
  235. {
  236. unsigned char enable = false;
  237. /* 82557 doesn't support fc. Don't touch this option */
  238. if (!(bdp->flags & IS_BACHELOR))
  239. return;
  240. /* Enable fc if requested and if the link supports it */
  241. if ((bdp->params.b_params & PRM_FC) && (bdp->flags & 
  242. (DF_LINK_FC_CAP | DF_LINK_FC_TX_ONLY))) {
  243. enable = true;
  244. }
  245. spin_lock_bh(&(bdp->config_lock));
  246. if (enable) {
  247. if (bdp->flags & DF_LINK_FC_TX_ONLY) {
  248. /* If link partner is capable of autoneg, but  */
  249. /* not capable of flow control, Received PAUSE */
  250. /* frames are still honored, i.e.,             */
  251. /* transmitted frames would be paused by       */
  252. /* incoming PAUSE frames                       */
  253. bdp->config[16] = DFLT_NO_FC_DELAY_LSB;
  254. bdp->config[17] = DFLT_NO_FC_DELAY_MSB;
  255. bdp->config[19] &= ~(CB_CFIG_FC_RESTOP | CB_CFIG_FC_RESTART);
  256. bdp->config[19] |= CB_CFIG_FC_REJECT;
  257. bdp->config[19] &= ~CB_CFIG_TX_FC_DIS;
  258. } else {
  259. bdp->config[16] = DFLT_FC_DELAY_LSB;
  260. bdp->config[17] = DFLT_FC_DELAY_MSB;
  261. bdp->config[19] |= CB_CFIG_FC_OPTS;
  262. bdp->config[19] &= ~CB_CFIG_TX_FC_DIS;
  263. }
  264. } else {
  265. bdp->config[16] = DFLT_NO_FC_DELAY_LSB;
  266. bdp->config[17] = DFLT_NO_FC_DELAY_MSB;
  267. bdp->config[19] &= ~CB_CFIG_FC_OPTS;
  268. bdp->config[19] |= CB_CFIG_TX_FC_DIS;
  269. }
  270. E100_CONFIG(bdp, 19);
  271. spin_unlock_bh(&(bdp->config_lock));
  272. return;
  273. }
  274. /**
  275.  * e100_config_promisc - configure promiscuous mode
  276.  * @bdp: atapter's private data struct
  277.  * @enable: should we enable this option or not
  278.  *
  279.  * This routine will enable or disable promiscuous mode
  280.  * in the adapter's config block.
  281.  */
  282. void
  283. e100_config_promisc(struct e100_private *bdp, unsigned char enable)
  284. {
  285. spin_lock_bh(&(bdp->config_lock));
  286. /* if in promiscuous mode, save bad frames */
  287. if (enable) {
  288. if (!(bdp->config[6] & CB_CFIG_SAVE_BAD_FRAMES)) {
  289. bdp->config[6] |= CB_CFIG_SAVE_BAD_FRAMES;
  290. E100_CONFIG(bdp, 6);
  291. }
  292. if (bdp->config[7] & (u8) BIT_0) {
  293. bdp->config[7] &= (u8) (~BIT_0);
  294. E100_CONFIG(bdp, 7);
  295. }
  296. if (!(bdp->config[15] & CB_CFIG_PROMISCUOUS)) {
  297. bdp->config[15] |= CB_CFIG_PROMISCUOUS;
  298. E100_CONFIG(bdp, 15);
  299. }
  300. } else { /* not in promiscuous mode */
  301. if (bdp->config[6] & CB_CFIG_SAVE_BAD_FRAMES) {
  302. bdp->config[6] &= ~CB_CFIG_SAVE_BAD_FRAMES;
  303. E100_CONFIG(bdp, 6);
  304. }
  305. if (!(bdp->config[7] & (u8) BIT_0)) {
  306. bdp->config[7] |= (u8) (BIT_0);
  307. E100_CONFIG(bdp, 7);
  308. }
  309. if (bdp->config[15] & CB_CFIG_PROMISCUOUS) {
  310. bdp->config[15] &= ~CB_CFIG_PROMISCUOUS;
  311. E100_CONFIG(bdp, 15);
  312. }
  313. }
  314. spin_unlock_bh(&(bdp->config_lock));
  315. }
  316. /**
  317.  * e100_config_mulcast_enbl - configure allmulti mode
  318.  * @bdp: atapter's private data struct
  319.  * @enable: should we enable this option or not
  320.  *
  321.  * This routine will enable or disable reception of all multicast packets
  322.  * in the adapter's config block.
  323.  */
  324. void
  325. e100_config_mulcast_enbl(struct e100_private *bdp, unsigned char enable)
  326. {
  327. spin_lock_bh(&(bdp->config_lock));
  328. /* this flag is used to enable receiving all multicast packet */
  329. if (enable) {
  330. if (!(bdp->config[21] & CB_CFIG_MULTICAST_ALL)) {
  331. bdp->config[21] |= CB_CFIG_MULTICAST_ALL;
  332. E100_CONFIG(bdp, 21);
  333. }
  334. } else {
  335. if (bdp->config[21] & CB_CFIG_MULTICAST_ALL) {
  336. bdp->config[21] &= ~CB_CFIG_MULTICAST_ALL;
  337. E100_CONFIG(bdp, 21);
  338. }
  339. }
  340. spin_unlock_bh(&(bdp->config_lock));
  341. }
  342. /**
  343.  * e100_config_ifs - configure the IFS parameter
  344.  * @bdp: atapter's private data struct
  345.  *
  346.  * This routine will configure the adaptive IFS value
  347.  * in the adapter's config block. IFS values are only
  348.  * relevant in half duplex, so set to 0 in full duplex.
  349.  */
  350. void
  351. e100_config_ifs(struct e100_private *bdp)
  352. {
  353. u8 value = 0;
  354. spin_lock_bh(&(bdp->config_lock));
  355. /* IFS value is only needed to be specified at half-duplex mode */
  356. if (bdp->cur_dplx_mode == HALF_DUPLEX) {
  357. value = (u8) bdp->ifs_value;
  358. }
  359. if (bdp->config[2] != value) {
  360. bdp->config[2] = value;
  361. E100_CONFIG(bdp, 2);
  362. }
  363. spin_unlock_bh(&(bdp->config_lock));
  364. }
  365. /**
  366.  * e100_config_force_dplx - configure the forced full duplex mode
  367.  * @bdp: atapter's private data struct
  368.  *
  369.  * This routine will enable or disable force full duplex
  370.  * in the adapter's config block. If the PHY is 503, and
  371.  * the duplex is full, consider the adapter forced.
  372.  */
  373. void
  374. e100_config_force_dplx(struct e100_private *bdp)
  375. {
  376. spin_lock_bh(&(bdp->config_lock));
  377. /* We must force full duplex on if we are using PHY 0, and we are */
  378. /* supposed to run in FDX mode. We do this because the e100 has only */
  379. /* one FDX# input pin, and that pin will be connected to PHY 1. */
  380. /* Changed the 'if' condition below to fix performance problem * at 10
  381.  * full. The Phy was getting forced to full duplex while the MAC * was
  382.  * not, because the cur_dplx_mode was not being set to 2 by SetupPhy. *
  383.  * This is how the condition was, initially. * This has been changed so
  384.  * that the MAC gets forced to full duplex * simply if the user has
  385.  * forced full duplex. * * if (( bdp->phy_addr == 0 ) && (
  386.  * bdp->cur_dplx_mode == 2 )) */
  387. /* The rest of the fix is in the PhyDetect code. */
  388. if ((bdp->params.e100_speed_duplex == E100_SPEED_10_FULL) ||
  389.     (bdp->params.e100_speed_duplex == E100_SPEED_100_FULL) ||
  390.     ((bdp->phy_addr == 32) && (bdp->cur_dplx_mode == FULL_DUPLEX))) {
  391. if (!(bdp->config[19] & (u8) CB_CFIG_FORCE_FDX)) {
  392. bdp->config[19] |= (u8) CB_CFIG_FORCE_FDX;
  393. E100_CONFIG(bdp, 19);
  394. }
  395. } else {
  396. if (bdp->config[19] & (u8) CB_CFIG_FORCE_FDX) {
  397. bdp->config[19] &= (u8) (~CB_CFIG_FORCE_FDX);
  398. E100_CONFIG(bdp, 19);
  399. }
  400. }
  401. spin_unlock_bh(&(bdp->config_lock));
  402. }
  403. /**
  404.  * e100_config_long_rx
  405.  * @bdp: atapter's private data struct
  406.  * @enable: should we enable this option or not
  407.  *
  408.  * This routine will enable or disable reception of larger packets.
  409.  * This is needed by VLAN implementations.
  410.  */
  411. static void
  412. e100_config_long_rx(struct e100_private *bdp, unsigned char enable)
  413. {
  414. if (enable) {
  415. if (!(bdp->config[18] & CB_CFIG_LONG_RX_OK)) {
  416. bdp->config[18] |= CB_CFIG_LONG_RX_OK;
  417. E100_CONFIG(bdp, 18);
  418. }
  419. } else {
  420. if ((bdp->config[18] & CB_CFIG_LONG_RX_OK)) {
  421. bdp->config[18] &= ~CB_CFIG_LONG_RX_OK;
  422. E100_CONFIG(bdp, 18);
  423. }
  424. }
  425. }
  426. /**
  427.  * e100_config_wol
  428.  * @bdp: atapter's private data struct
  429.  *
  430.  * This sets configuration options for Wake On LAN functionality (WOL) in the
  431.  * config record. WOL options are retrieved from wolinfo_wolopts in @bdp
  432.  */
  433. void
  434. e100_config_wol(struct e100_private *bdp)
  435. {
  436. spin_lock_bh(&(bdp->config_lock));
  437. if (bdp->wolopts & WAKE_PHY) {
  438. bdp->config[9] |= CB_LINK_STATUS_WOL;
  439. E100_CONFIG(bdp, 9);
  440. }
  441. if (!(bdp->wolopts & WAKE_MAGIC)) {
  442. bdp->config[19] |= CB_DISABLE_MAGPAK_WAKE;
  443. E100_CONFIG(bdp, 19);
  444. }
  445. spin_unlock_bh(&(bdp->config_lock));
  446. }
  447. /**
  448.  * e100_config_loopback_mode
  449.  * @bdp: atapter's private data struct
  450.  * @mode: loopback mode(phy/mac/none)
  451.  *
  452.  */
  453. unsigned char
  454. e100_config_loopback_mode(struct e100_private *bdp, u8 mode)
  455. {
  456. unsigned char bc_changed = false;
  457. u8 config_byte;
  458. spin_lock_bh(&(bdp->config_lock));
  459. switch (mode) {
  460. case NO_LOOPBACK:
  461. config_byte = CB_CFIG_LOOPBACK_NORMAL;
  462. break;
  463. case MAC_LOOPBACK:
  464. config_byte = CB_CFIG_LOOPBACK_INTERNAL;
  465. break;
  466. case PHY_LOOPBACK:
  467. config_byte = CB_CFIG_LOOPBACK_EXTERNAL;
  468. break;
  469. default:
  470. printk(KERN_NOTICE "e100: e100_config_loopback_mode: "
  471.        "Invalid argument 'mode': %dn", mode);
  472. goto exit;
  473. }
  474. if ((bdp->config[10] & CB_CFIG_LOOPBACK_MODE) != config_byte) {
  475. bdp->config[10] &= (~CB_CFIG_LOOPBACK_MODE);
  476. bdp->config[10] |= config_byte;
  477. E100_CONFIG(bdp, 10);
  478. bc_changed = true;
  479. }
  480. exit:
  481. spin_unlock_bh(&(bdp->config_lock));
  482. return bc_changed;
  483. }
  484. unsigned char
  485. e100_config_tcb_ext_enable(struct e100_private *bdp, unsigned char enable)
  486. {
  487.         unsigned char bc_changed = false;
  488.  
  489.         spin_lock_bh(&(bdp->config_lock));
  490.  
  491.         if (enable) {
  492.                 if (bdp->config[6] & CB_CFIG_EXT_TCB_DIS) {
  493.  
  494.                         bdp->config[6] &= (~CB_CFIG_EXT_TCB_DIS);
  495.                         E100_CONFIG(bdp, 6);
  496.                         bc_changed = true;
  497.                 }
  498.  
  499.         } else {
  500.                 if (!(bdp->config[6] & CB_CFIG_EXT_TCB_DIS)) {
  501.  
  502.                         bdp->config[6] |= CB_CFIG_EXT_TCB_DIS;
  503.                         E100_CONFIG(bdp, 6);
  504.                         bc_changed = true;
  505.                 }
  506.         }
  507.         spin_unlock_bh(&(bdp->config_lock));
  508.  
  509.         return bc_changed;
  510. }
  511. unsigned char
  512. e100_config_dynamic_tbd(struct e100_private *bdp, unsigned char enable)
  513. {
  514.         unsigned char bc_changed = false;
  515.  
  516.         spin_lock_bh(&(bdp->config_lock));
  517.  
  518.         if (enable) {
  519.                 if (!(bdp->config[7] & CB_CFIG_DYNTBD_EN)) {
  520.  
  521.                         bdp->config[7] |= CB_CFIG_DYNTBD_EN;
  522.                         E100_CONFIG(bdp, 7);
  523.                         bc_changed = true;
  524.                 }
  525.  
  526.         } else {
  527.                 if (bdp->config[7] & CB_CFIG_DYNTBD_EN) {
  528.  
  529.                         bdp->config[7] &= (~CB_CFIG_DYNTBD_EN);
  530.                         E100_CONFIG(bdp, 7);
  531.                         bc_changed = true;
  532.                 }
  533.         }
  534.         spin_unlock_bh(&(bdp->config_lock));
  535.  
  536.         return bc_changed;
  537. }