diff options
Diffstat (limited to 'drivers/staging/et131x')
-rw-r--r-- | drivers/staging/et131x/et1310_address_map.h | 343 | ||||
-rw-r--r-- | drivers/staging/et131x/et1310_eeprom.c | 436 | ||||
-rw-r--r-- | drivers/staging/et131x/et1310_eeprom.h | 42 | ||||
-rw-r--r-- | drivers/staging/et131x/et1310_mac.c | 102 | ||||
-rw-r--r-- | drivers/staging/et131x/et1310_phy.c | 1167 | ||||
-rw-r--r-- | drivers/staging/et131x/et1310_phy.h | 35 | ||||
-rw-r--r-- | drivers/staging/et131x/et1310_rx.c | 539 | ||||
-rw-r--r-- | drivers/staging/et131x/et1310_rx.h | 50 | ||||
-rw-r--r-- | drivers/staging/et131x/et1310_tx.c | 620 | ||||
-rw-r--r-- | drivers/staging/et131x/et1310_tx.h | 218 | ||||
-rw-r--r-- | drivers/staging/et131x/et131x_adapter.h | 13 | ||||
-rw-r--r-- | drivers/staging/et131x/et131x_defs.h | 1 | ||||
-rw-r--r-- | drivers/staging/et131x/et131x_initpci.c | 596 | ||||
-rw-r--r-- | drivers/staging/et131x/et131x_initpci.h | 2 | ||||
-rw-r--r-- | drivers/staging/et131x/et131x_isr.c | 16 | ||||
-rw-r--r-- | drivers/staging/et131x/et131x_netdev.c | 31 |
16 files changed, 1600 insertions, 2611 deletions
diff --git a/drivers/staging/et131x/et1310_address_map.h b/drivers/staging/et131x/et1310_address_map.h index 2c3d65a622a7..d4652e9e1225 100644 --- a/drivers/staging/et131x/et1310_address_map.h +++ b/drivers/staging/et131x/et1310_address_map.h @@ -1308,157 +1308,77 @@ typedef struct _RXMAC_t { /* Location: */ /* * structure for configuration #1 reg in mac address map. * located at address 0x5000 - */ -typedef union _MAC_CFG1_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 soft_reset:1; /* bit 31 */ - u32 sim_reset:1; /* bit 30 */ - u32 reserved3:10; /* bits 20-29 */ - u32 reset_rx_mc:1; /* bit 19 */ - u32 reset_tx_mc:1; /* bit 18 */ - u32 reset_rx_fun:1; /* bit 17 */ - u32 reset_tx_fun:1; /* bit 16 */ - u32 reserved2:7; /* bits 9-15 */ - u32 loop_back:1; /* bit 8 */ - u32 reserved1:2; /* bits 6-7 */ - u32 rx_flow:1; /* bit 5 */ - u32 tx_flow:1; /* bit 4 */ - u32 syncd_rx_en:1; /* bit 3 */ - u32 rx_enable:1; /* bit 2 */ - u32 syncd_tx_en:1; /* bit 1 */ - u32 tx_enable:1; /* bit 0 */ -#else - u32 tx_enable:1; /* bit 0 */ - u32 syncd_tx_en:1; /* bit 1 */ - u32 rx_enable:1; /* bit 2 */ - u32 syncd_rx_en:1; /* bit 3 */ - u32 tx_flow:1; /* bit 4 */ - u32 rx_flow:1; /* bit 5 */ - u32 reserved1:2; /* bits 6-7 */ - u32 loop_back:1; /* bit 8 */ - u32 reserved2:7; /* bits 9-15 */ - u32 reset_tx_fun:1; /* bit 16 */ - u32 reset_rx_fun:1; /* bit 17 */ - u32 reset_tx_mc:1; /* bit 18 */ - u32 reset_rx_mc:1; /* bit 19 */ - u32 reserved3:10; /* bits 20-29 */ - u32 sim_reset:1; /* bit 30 */ - u32 soft_reset:1; /* bit 31 */ -#endif - } bits; -} MAC_CFG1_t, *PMAC_CFG1_t; + * + * 31: soft reset + * 30: sim reset + * 29-20: reserved + * 19: reset rx mc + * 18: reset tx mc + * 17: reset rx func + * 16: reset tx fnc + * 15-9: reserved + * 8: loopback + * 7-6: reserved + * 5: rx flow + * 4: tx flow + * 3: syncd rx en + * 2: rx enable + * 1: syncd tx en + * 0: tx enable + */ + +#define CFG1_LOOPBACK 0x00000100 +#define CFG1_RX_FLOW 0x00000020 +#define CFG1_TX_FLOW 0x00000010 +#define CFG1_RX_ENABLE 0x00000004 +#define CFG1_TX_ENABLE 0x00000001 +#define CFG1_WAIT 0x0000000A /* RX & TX syncd */ /* * structure for configuration #2 reg in mac address map. * located at address 0x5004 + * 31-16: reserved + * 15-12: preamble + * 11-10: reserved + * 9-8: if mode + * 7-6: reserved + * 5: huge frame + * 4: length check + * 3: undefined + * 2: pad crc + * 1: crc enable + * 0: full duplex */ -typedef union _MAC_CFG2_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 reserved3:16; /* bits 16-31 */ - u32 preamble_len:4; /* bits 12-15 */ - u32 reserved2:2; /* bits 10-11 */ - u32 if_mode:2; /* bits 8-9 */ - u32 reserved1:2; /* bits 6-7 */ - u32 huge_frame:1; /* bit 5 */ - u32 len_check:1; /* bit 4 */ - u32 undefined:1; /* bit 3 */ - u32 pad_crc:1; /* bit 2 */ - u32 crc_enable:1; /* bit 1 */ - u32 full_duplex:1; /* bit 0 */ -#else - u32 full_duplex:1; /* bit 0 */ - u32 crc_enable:1; /* bit 1 */ - u32 pad_crc:1; /* bit 2 */ - u32 undefined:1; /* bit 3 */ - u32 len_check:1; /* bit 4 */ - u32 huge_frame:1; /* bit 5 */ - u32 reserved1:2; /* bits 6-7 */ - u32 if_mode:2; /* bits 8-9 */ - u32 reserved2:2; /* bits 10-11 */ - u32 preamble_len:4; /* bits 12-15 */ - u32 reserved3:16; /* bits 16-31 */ -#endif - } bits; -} MAC_CFG2_t, *PMAC_CFG2_t; + /* * structure for Interpacket gap reg in mac address map. * located at address 0x5008 - */ -typedef union _MAC_IPG_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 reserved:1; /* bit 31 */ - u32 non_B2B_ipg_1:7; /* bits 24-30 */ - u32 undefined2:1; /* bit 23 */ - u32 non_B2B_ipg_2:7; /* bits 16-22 */ - u32 min_ifg_enforce:8; /* bits 8-15 */ - u32 undefined1:1; /* bit 7 */ - u32 B2B_ipg:7; /* bits 0-6 */ -#else - u32 B2B_ipg:7; /* bits 0-6 */ - u32 undefined1:1; /* bit 7 */ - u32 min_ifg_enforce:8; /* bits 8-15 */ - u32 non_B2B_ipg_2:7; /* bits 16-22 */ - u32 undefined2:1; /* bit 23 */ - u32 non_B2B_ipg_1:7; /* bits 24-30 */ - u32 reserved:1; /* bit 31 */ -#endif - } bits; -} MAC_IPG_t, *PMAC_IPG_t; - -/* + * + * 31: reserved + * 30-24: non B2B ipg 1 + * 23: undefined + * 22-16: non B2B ipg 2 + * 15-8: Min ifg enforce + * 7-0: B2B ipg + * * structure for half duplex reg in mac address map. * located at address 0x500C + * 31-24: reserved + * 23-20: Alt BEB trunc + * 19: Alt BEB enable + * 18: BP no backoff + * 17: no backoff + * 16: excess defer + * 15-12: re-xmit max + * 11-10: reserved + * 9-0: collision window */ -typedef union _MAC_HFDP_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 reserved2:8; /* bits 24-31 */ - u32 alt_beb_trunc:4; /* bits 23-20 */ - u32 alt_beb_enable:1; /* bit 19 */ - u32 bp_no_backoff:1; /* bit 18 */ - u32 no_backoff:1; /* bit 17 */ - u32 excess_defer:1; /* bit 16 */ - u32 rexmit_max:4; /* bits 12-15 */ - u32 reserved1:2; /* bits 10-11 */ - u32 coll_window:10; /* bits 0-9 */ -#else - u32 coll_window:10; /* bits 0-9 */ - u32 reserved1:2; /* bits 10-11 */ - u32 rexmit_max:4; /* bits 12-15 */ - u32 excess_defer:1; /* bit 16 */ - u32 no_backoff:1; /* bit 17 */ - u32 bp_no_backoff:1; /* bit 18 */ - u32 alt_beb_enable:1; /* bit 19 */ - u32 alt_beb_trunc:4; /* bits 23-20 */ - u32 reserved2:8; /* bits 24-31 */ -#endif - } bits; -} MAC_HFDP_t, *PMAC_HFDP_t; /* * structure for Maximum Frame Length reg in mac address map. - * located at address 0x5010 + * located at address 0x5010: bits 0-15 hold the length. */ -typedef union _MAC_MAX_FM_LEN_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 reserved:16; /* bits 16-31 */ - u32 max_len:16; /* bits 0-15 */ -#else - u32 max_len:16; /* bits 0-15 */ - u32 reserved:16; /* bits 16-31 */ -#endif - } bits; -} MAC_MAX_FM_LEN_t, *PMAC_MAX_FM_LEN_t; /* * structure for Reserve 1 reg in mac address map. @@ -1469,139 +1389,64 @@ typedef union _MAC_MAX_FM_LEN_t { /* * structure for Test reg in mac address map. * located at address 0x501C + * test: bits 0-2, rest unused */ -typedef union _MAC_TEST_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 unused:29; /* bits 3-31 */ - u32 mac_test:3; /* bits 0-2 */ -#else - u32 mac_test:3; /* bits 0-2 */ - u32 unused:29; /* bits 3-31 */ -#endif - } bits; -} MAC_TEST_t, *PMAC_TEST_t; /* * structure for MII Management Configuration reg in mac address map. * located at address 0x5020 + * + * 31: reset MII mgmt + * 30-6: unused + * 5: scan auto increment + * 4: preamble supress + * 3: undefined + * 2-0: mgmt clock reset */ -typedef union _MII_MGMT_CFG_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 reset_mii_mgmt:1; /* bit 31 */ - u32 reserved:25; /* bits 6-30 */ - u32 scan_auto_incremt:1; /* bit 5 */ - u32 preamble_suppress:1; /* bit 4 */ - u32 undefined:1; /* bit 3 */ - u32 mgmt_clk_reset:3; /* bits 0-2 */ -#else - u32 mgmt_clk_reset:3; /* bits 0-2 */ - u32 undefined:1; /* bit 3 */ - u32 preamble_suppress:1; /* bit 4 */ - u32 scan_auto_incremt:1; /* bit 5 */ - u32 reserved:25; /* bits 6-30 */ - u32 reset_mii_mgmt:1; /* bit 31 */ -#endif - } bits; -} MII_MGMT_CFG_t, *PMII_MGMT_CFG_t; /* * structure for MII Management Command reg in mac address map. * located at address 0x5024 + * bit 1: scan cycle + * bit 0: read cycle */ -typedef union _MII_MGMT_CMD_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 reserved:30; /* bits 2-31 */ - u32 scan_cycle:1; /* bit 1 */ - u32 read_cycle:1; /* bit 0 */ -#else - u32 read_cycle:1; /* bit 0 */ - u32 scan_cycle:1; /* bit 1 */ - u32 reserved:30; /* bits 2-31 */ -#endif - } bits; -} MII_MGMT_CMD_t, *PMII_MGMT_CMD_t; /* * structure for MII Management Address reg in mac address map. * located at address 0x5028 + * 31-13: reserved + * 12-8: phy addr + * 7-5: reserved + * 4-0: register */ -typedef union _MII_MGMT_ADDR_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 reserved2:19; /* bit 13-31 */ - u32 phy_addr:5; /* bits 8-12 */ - u32 reserved1:3; /* bits 5-7 */ - u32 reg_addr:5; /* bits 0-4 */ -#else - u32 reg_addr:5; /* bits 0-4 */ - u32 reserved1:3; /* bits 5-7 */ - u32 phy_addr:5; /* bits 8-12 */ - u32 reserved2:19; /* bit 13-31 */ -#endif - } bits; -} MII_MGMT_ADDR_t, *PMII_MGMT_ADDR_t; + +#define MII_ADDR(phy,reg) ((phy) << 8 | (reg)) /* * structure for MII Management Control reg in mac address map. * located at address 0x502C + * 31-16: reserved + * 15-0: phy control */ -typedef union _MII_MGMT_CTRL_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 reserved:16; /* bits 16-31 */ - u32 phy_ctrl:16; /* bits 0-15 */ -#else - u32 phy_ctrl:16; /* bits 0-15 */ - u32 reserved:16; /* bits 16-31 */ -#endif - } bits; -} MII_MGMT_CTRL_t, *PMII_MGMT_CTRL_t; /* * structure for MII Management Status reg in mac address map. * located at address 0x5030 + * 31-16: reserved + * 15-0: phy control */ -typedef union _MII_MGMT_STAT_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 reserved:16; /* bits 16-31 */ - u32 phy_stat:16; /* bits 0-15 */ -#else - u32 phy_stat:16; /* bits 0-15 */ - u32 reserved:16; /* bits 16-31 */ -#endif - } bits; -} MII_MGMT_STAT_t, *PMII_MGMT_STAT_t; /* * structure for MII Management Indicators reg in mac address map. * located at address 0x5034 + * 31-3: reserved + * 2: not valid + * 1: scanning + * 0: busy */ -typedef union _MII_MGMT_INDICATOR_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 reserved:29; /* bits 3-31 */ - u32 not_valid:1; /* bit 2 */ - u32 scanning:1; /* bit 1 */ - u32 busy:1; /* bit 0 */ -#else - u32 busy:1; /* bit 0 */ - u32 scanning:1; /* bit 1 */ - u32 not_valid:1; /* bit 2 */ - u32 reserved:29; /* bits 3-31 */ -#endif - } bits; -} MII_MGMT_INDICATOR_t, *PMII_MGMT_INDICATOR_t; + +#define MGMT_BUSY 0x00000001 /* busy */ +#define MGMT_WAIT 0x00000005 /* busy | not valid */ /* * structure for Interface Control reg in mac address map. @@ -1729,20 +1574,20 @@ typedef union _MAC_STATION_ADDR2_t { * MAC Module of JAGCore Address Mapping */ typedef struct _MAC_t { /* Location: */ - MAC_CFG1_t cfg1; /* 0x5000 */ - MAC_CFG2_t cfg2; /* 0x5004 */ - MAC_IPG_t ipg; /* 0x5008 */ - MAC_HFDP_t hfdp; /* 0x500C */ - MAC_MAX_FM_LEN_t max_fm_len; /* 0x5010 */ + u32 cfg1; /* 0x5000 */ + u32 cfg2; /* 0x5004 */ + u32 ipg; /* 0x5008 */ + u32 hfdp; /* 0x500C */ + u32 max_fm_len; /* 0x5010 */ u32 rsv1; /* 0x5014 */ u32 rsv2; /* 0x5018 */ - MAC_TEST_t mac_test; /* 0x501C */ - MII_MGMT_CFG_t mii_mgmt_cfg; /* 0x5020 */ - MII_MGMT_CMD_t mii_mgmt_cmd; /* 0x5024 */ - MII_MGMT_ADDR_t mii_mgmt_addr; /* 0x5028 */ - MII_MGMT_CTRL_t mii_mgmt_ctrl; /* 0x502C */ - MII_MGMT_STAT_t mii_mgmt_stat; /* 0x5030 */ - MII_MGMT_INDICATOR_t mii_mgmt_indicator; /* 0x5034 */ + u32 mac_test; /* 0x501C */ + u32 mii_mgmt_cfg; /* 0x5020 */ + u32 mii_mgmt_cmd; /* 0x5024 */ + u32 mii_mgmt_addr; /* 0x5028 */ + u32 mii_mgmt_ctrl; /* 0x502C */ + u32 mii_mgmt_stat; /* 0x5030 */ + u32 mii_mgmt_indicator; /* 0x5034 */ MAC_IF_CTRL_t if_ctrl; /* 0x5038 */ MAC_IF_STAT_t if_stat; /* 0x503C */ MAC_STATION_ADDR1_t station_addr_1; /* 0x5040 */ diff --git a/drivers/staging/et131x/et1310_eeprom.c b/drivers/staging/et131x/et1310_eeprom.c index c853a2c243a8..bcca1f86f516 100644 --- a/drivers/staging/et131x/et1310_eeprom.c +++ b/drivers/staging/et131x/et1310_eeprom.c @@ -95,198 +95,120 @@ #include "et1310_tx.h" -/* - * EEPROM Defines - */ -/* LBCIF Register Groups (addressed via 32-bit offsets) */ -#define LBCIF_DWORD0_GROUP_OFFSET 0xAC -#define LBCIF_DWORD1_GROUP_OFFSET 0xB0 - -/* LBCIF Registers (addressed via 8-bit offsets) */ -#define LBCIF_ADDRESS_REGISTER_OFFSET 0xAC -#define LBCIF_DATA_REGISTER_OFFSET 0xB0 -#define LBCIF_CONTROL_REGISTER_OFFSET 0xB1 -#define LBCIF_STATUS_REGISTER_OFFSET 0xB2 - -/* LBCIF Control Register Bits */ -#define LBCIF_CONTROL_SEQUENTIAL_READ 0x01 -#define LBCIF_CONTROL_PAGE_WRITE 0x02 -#define LBCIF_CONTROL_UNUSED1 0x04 -#define LBCIF_CONTROL_EEPROM_RELOAD 0x08 -#define LBCIF_CONTROL_UNUSED2 0x10 -#define LBCIF_CONTROL_TWO_BYTE_ADDR 0x20 -#define LBCIF_CONTROL_I2C_WRITE 0x40 -#define LBCIF_CONTROL_LBCIF_ENABLE 0x80 - -/* LBCIF Status Register Bits */ -#define LBCIF_STATUS_PHY_QUEUE_AVAIL 0x01 -#define LBCIF_STATUS_I2C_IDLE 0x02 -#define LBCIF_STATUS_ACK_ERROR 0x04 -#define LBCIF_STATUS_GENERAL_ERROR 0x08 -#define LBCIF_STATUS_UNUSED 0x30 -#define LBCIF_STATUS_CHECKSUM_ERROR 0x40 -#define LBCIF_STATUS_EEPROM_PRESENT 0x80 - -/* Miscellaneous Constraints */ -#define MAX_NUM_REGISTER_POLLS 1000 -#define MAX_NUM_WRITE_RETRIES 2 +static int eeprom_wait_ready(struct pci_dev *pdev, u32 *status) +{ + u32 reg; + int i; + + /* + * 1. Check LBCIF Status Register for bits 6 & 3:2 all equal to 0 and + * bits 7,1:0 both equal to 1, at least once after reset. + * Subsequent operations need only to check that bits 1:0 are equal + * to 1 prior to starting a single byte read/write + */ + + for (i = 0; i < MAX_NUM_REGISTER_POLLS; i++) { + /* Read registers grouped in DWORD1 */ + if (pci_read_config_dword(pdev, LBCIF_DWORD1_GROUP, ®)) + return -EIO; + + /* I2C idle and Phy Queue Avail both true */ + if ((reg & 0x3000) == 0x3000) { + if (status) + *status = reg; + return reg & 0xFF; + } + } + return -ETIMEDOUT; +} -/* - * Define macros that allow individual register values to be extracted from a - * DWORD1 register grouping - */ -#define EXTRACT_DATA_REGISTER(x) (u8)(x & 0xFF) -#define EXTRACT_STATUS_REGISTER(x) (u8)((x >> 16) & 0xFF) -#define EXTRACT_CONTROL_REG(x) (u8)((x >> 8) & 0xFF) /** - * EepromWriteByte - Write a byte to the ET1310's EEPROM + * eeprom_write - Write a byte to the ET1310's EEPROM * @etdev: pointer to our private adapter structure * @addr: the address to write * @data: the value to write * - * Returns SUCCESS or FAILURE + * Returns 1 for a successful write. */ -int EepromWriteByte(struct et131x_adapter *etdev, u32 addr, u8 data) +static int eeprom_write(struct et131x_adapter *etdev, u32 addr, u8 data) { struct pci_dev *pdev = etdev->pdev; - int index; + int index = 0; int retries; int err = 0; int i2c_wack = 0; int writeok = 0; - u8 control; - u8 status = 0; - u32 dword1 = 0; + u32 status; u32 val = 0; /* - * The following excerpt is from "Serial EEPROM HW Design - * Specification" Version 0.92 (9/20/2004): - * - * Single Byte Writes - * * For an EEPROM, an I2C single byte write is defined as a START * condition followed by the device address, EEPROM address, one byte * of data and a STOP condition. The STOP condition will trigger the * EEPROM's internally timed write cycle to the nonvolatile memory. * All inputs are disabled during this write cycle and the EEPROM will * not respond to any access until the internal write is complete. - * The steps to execute a single byte write are as follows: - * - * 1. Check LBCIF Status Register for bits 6 & 3:2 all equal to 0 and - * bits 7,1:0 both equal to 1, at least once after reset. - * Subsequent operations need only to check that bits 1:0 are - * equal to 1 prior to starting a single byte write. - * + */ + + err = eeprom_wait_ready(pdev, NULL); + if (err) + return err; + + /* * 2. Write to the LBCIF Control Register: bit 7=1, bit 6=1, bit 3=0, * and bits 1:0 both =0. Bit 5 should be set according to the * type of EEPROM being accessed (1=two byte addressing, 0=one * byte addressing). - * - * 3. Write the address to the LBCIF Address Register. - * - * 4. Write the data to the LBCIF Data Register (the I2C write will - * begin). - * - * 5. Monitor bit 1:0 of the LBCIF Status Register. When bits 1:0 are - * both equal to 1, the I2C write has completed and the internal - * write cycle of the EEPROM is about to start. (bits 1:0 = 01 is - * a legal state while waiting from both equal to 1, but bits - * 1:0 = 10 is invalid and implies that something is broken). - * - * 6. Check bit 3 of the LBCIF Status Register. If equal to 1, an - * error has occurred. - * - * 7. Check bit 2 of the LBCIF Status Register. If equal to 1 an ACK - * error has occurred on the address phase of the write. This - * could be due to an actual hardware failure or the EEPROM may - * still be in its internal write cycle from a previous write. - * This write operation was ignored and must be repeated later. - * - * 8. Set bit 6 of the LBCIF Control Register = 0. If another write is - * required, go to step 1. */ - - /* Step 1: */ - for (index = 0; index < MAX_NUM_REGISTER_POLLS; index++) { - /* Read registers grouped in DWORD1 */ - if (pci_read_config_dword(pdev, LBCIF_DWORD1_GROUP_OFFSET, - &dword1)) { - err = 1; - break; - } - - status = EXTRACT_STATUS_REGISTER(dword1); - - if (status & LBCIF_STATUS_PHY_QUEUE_AVAIL && - status & LBCIF_STATUS_I2C_IDLE) - /* bits 1:0 are equal to 1 */ - break; - } - - if (err || (index >= MAX_NUM_REGISTER_POLLS)) - return FAILURE; - - /* Step 2: */ - control = 0; - control |= LBCIF_CONTROL_LBCIF_ENABLE | LBCIF_CONTROL_I2C_WRITE; - - if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER_OFFSET, - control)) { - return FAILURE; - } + if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER, + LBCIF_CONTROL_LBCIF_ENABLE | LBCIF_CONTROL_I2C_WRITE)) + return -EIO; i2c_wack = 1; /* Prepare EEPROM address for Step 3 */ for (retries = 0; retries < MAX_NUM_WRITE_RETRIES; retries++) { - /* Step 3:*/ - if (pci_write_config_dword(pdev, LBCIF_ADDRESS_REGISTER_OFFSET, - addr)) { - break; - } - - /* Step 4: */ - if (pci_write_config_byte(pdev, LBCIF_DATA_REGISTER_OFFSET, - data)) { + /* Write the address to the LBCIF Address Register */ + if (pci_write_config_dword(pdev, LBCIF_ADDRESS_REGISTER, addr)) break; - } - - /* Step 5: */ - for (index = 0; index < MAX_NUM_REGISTER_POLLS; index++) { - /* Read registers grouped in DWORD1 */ - if (pci_read_config_dword(pdev, - LBCIF_DWORD1_GROUP_OFFSET, - &dword1)) { - err = 1; - break; - } - - status = EXTRACT_STATUS_REGISTER(dword1); - - if (status & LBCIF_STATUS_PHY_QUEUE_AVAIL && - status & LBCIF_STATUS_I2C_IDLE) { - /* I2C write complete */ - break; - } - } - - if (err || (index >= MAX_NUM_REGISTER_POLLS)) + /* + * Write the data to the LBCIF Data Register (the I2C write + * will begin). + */ + if (pci_write_config_byte(pdev, LBCIF_DATA_REGISTER, data)) break; + /* + * Monitor bit 1:0 of the LBCIF Status Register. When bits + * 1:0 are both equal to 1, the I2C write has completed and the + * internal write cycle of the EEPROM is about to start. + * (bits 1:0 = 01 is a legal state while waiting from both + * equal to 1, but bits 1:0 = 10 is invalid and implies that + * something is broken). + */ + err = eeprom_wait_ready(pdev, &status); + if (err < 0) + return 0; /* - * Step 6: Don't break here if we are revision 1, this is - * so we do a blind write for load bug. + * Check bit 3 of the LBCIF Status Register. If equal to 1, + * an error has occurred.Don't break here if we are revision + * 1, this is so we do a blind write for load bug. */ - if (status & LBCIF_STATUS_GENERAL_ERROR - && etdev->pdev->revision == 0) { + if ((status & LBCIF_STATUS_GENERAL_ERROR) + && etdev->pdev->revision == 0) break; - } - /* Step 7 */ + /* + * Check bit 2 of the LBCIF Status Register. If equal to 1 an + * ACK error has occurred on the address phase of the write. + * This could be due to an actual hardware failure or the + * EEPROM may still be in its internal write cycle from a + * previous write. This write operation was ignored and must be + *repeated later. + */ if (status & LBCIF_STATUS_ACK_ERROR) { /* * This could be due to an actual hardware failure @@ -302,154 +224,160 @@ int EepromWriteByte(struct et131x_adapter *etdev, u32 addr, u8 data) break; } - /* Step 8: */ + /* + * Set bit 6 of the LBCIF Control Register = 0. + */ udelay(10); - index = 0; - while (i2c_wack) { - control &= ~LBCIF_CONTROL_I2C_WRITE; - if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER_OFFSET, - control)) { + while (i2c_wack) { + if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER, + LBCIF_CONTROL_LBCIF_ENABLE)) writeok = 0; - } /* Do read until internal ACK_ERROR goes away meaning write * completed */ do { pci_write_config_dword(pdev, - LBCIF_ADDRESS_REGISTER_OFFSET, + LBCIF_ADDRESS_REGISTER, addr); do { pci_read_config_dword(pdev, - LBCIF_DATA_REGISTER_OFFSET, &val); + LBCIF_DATA_REGISTER, &val); } while ((val & 0x00010000) == 0); } while (val & 0x00040000); - control = EXTRACT_CONTROL_REG(val); - - if (control != 0xC0 || index == 10000) + if ((val & 0xFF00) != 0xC000 || index == 10000) break; - index++; } - - return writeok ? SUCCESS : FAILURE; + return writeok ? 0 : -EIO; } /** - * EepromReadByte - Read a byte from the ET1310's EEPROM + * eeprom_read - Read a byte from the ET1310's EEPROM * @etdev: pointer to our private adapter structure * @addr: the address from which to read * @pdata: a pointer to a byte in which to store the value of the read * @eeprom_id: the ID of the EEPROM * @addrmode: how the EEPROM is to be accessed * - * Returns SUCCESS or FAILURE + * Returns 1 for a successful read */ -int EepromReadByte(struct et131x_adapter *etdev, u32 addr, u8 *pdata) +static int eeprom_read(struct et131x_adapter *etdev, u32 addr, u8 *pdata) { struct pci_dev *pdev = etdev->pdev; - int index; - int err = 0; - u8 control; - u8 status = 0; - u32 dword1 = 0; + int err; + u32 status; /* - * The following excerpt is from "Serial EEPROM HW Design - * Specification" Version 0.92 (9/20/2004): - * - * Single Byte Reads - * * A single byte read is similar to the single byte write, with the * exception of the data flow: - * - * 1. Check LBCIF Status Register for bits 6 & 3:2 all equal to 0 and - * bits 7,1:0 both equal to 1, at least once after reset. - * Subsequent operations need only to check that bits 1:0 are equal - * to 1 prior to starting a single byte read. - * - * 2. Write to the LBCIF Control Register: bit 7=1, bit 6=0, bit 3=0, - * and bits 1:0 both =0. Bit 5 should be set according to the type - * of EEPROM being accessed (1=two byte addressing, 0=one byte - * addressing). - * - * 3. Write the address to the LBCIF Address Register (I2C read will - * begin). - * - * 4. Monitor bit 0 of the LBCIF Status Register. When =1, I2C read - * is complete. (if bit 1 =1 and bit 0 stays =0, a hardware failure - * has occurred). - * - * 5. Check bit 2 of the LBCIF Status Register. If =1, then an error - * has occurred. The data that has been returned from the PHY may - * be invalid. - * - * 6. Regardless of error status, read data byte from LBCIF Data - * Register. If another byte is required, go to step 1. */ - /* Step 1: */ - for (index = 0; index < MAX_NUM_REGISTER_POLLS; index++) { - /* Read registers grouped in DWORD1 */ - if (pci_read_config_dword(pdev, LBCIF_DWORD1_GROUP_OFFSET, - &dword1)) { - err = 1; - break; - } - - status = EXTRACT_STATUS_REGISTER(dword1); - - if (status & LBCIF_STATUS_PHY_QUEUE_AVAIL && - status & LBCIF_STATUS_I2C_IDLE) { - /* bits 1:0 are equal to 1 */ - break; - } - } - - if (err || (index >= MAX_NUM_REGISTER_POLLS)) - return FAILURE; - - /* Step 2: */ - control = 0; - control |= LBCIF_CONTROL_LBCIF_ENABLE; - - if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER_OFFSET, - control)) { - return FAILURE; - } + err = eeprom_wait_ready(pdev, NULL); + if (err) + return err; + /* + * Write to the LBCIF Control Register: bit 7=1, bit 6=0, bit 3=0, + * and bits 1:0 both =0. Bit 5 should be set according to the type + * of EEPROM being accessed (1=two byte addressing, 0=one byte + * addressing). + */ + if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER, + LBCIF_CONTROL_LBCIF_ENABLE)) + return -EIO; + /* + * Write the address to the LBCIF Address Register (I2C read will + * begin). + */ + if (pci_write_config_dword(pdev, LBCIF_ADDRESS_REGISTER, addr)) + return -EIO; + /* + * Monitor bit 0 of the LBCIF Status Register. When = 1, I2C read + * is complete. (if bit 1 =1 and bit 0 stays = 0, a hardware failure + * has occurred). + */ + err = eeprom_wait_ready(pdev, &status); + if (err < 0) + return err; + /* + * Regardless of error status, read data byte from LBCIF Data + * Register. + */ + *pdata = err; + /* + * Check bit 2 of the LBCIF Status Register. If = 1, + * then an error has occurred. + */ + return (status & LBCIF_STATUS_ACK_ERROR) ? -EIO : 0; +} - /* Step 3: */ +int et131x_init_eeprom(struct et131x_adapter *etdev) +{ + struct pci_dev *pdev = etdev->pdev; + u8 eestatus; - if (pci_write_config_dword(pdev, LBCIF_ADDRESS_REGISTER_OFFSET, - addr)) { - return FAILURE; + /* We first need to check the EEPROM Status code located at offset + * 0xB2 of config space + */ + pci_read_config_byte(pdev, ET1310_PCI_EEPROM_STATUS, + &eestatus); + + /* THIS IS A WORKAROUND: + * I need to call this function twice to get my card in a + * LG M1 Express Dual running. I tried also a msleep before this + * function, because I thougth there could be some time condidions + * but it didn't work. Call the whole function twice also work. + */ + if (pci_read_config_byte(pdev, ET1310_PCI_EEPROM_STATUS, &eestatus)) { + dev_err(&pdev->dev, + "Could not read PCI config space for EEPROM Status\n"); + return -EIO; } - /* Step 4: */ - for (index = 0; index < MAX_NUM_REGISTER_POLLS; index++) { - /* Read registers grouped in DWORD1 */ - if (pci_read_config_dword(pdev, LBCIF_DWORD1_GROUP_OFFSET, - &dword1)) { - err = 1; - break; + /* Determine if the error(s) we care about are present. If they are + * present we need to fail. + */ + if (eestatus & 0x4C) { + int write_failed = 0; + if (pdev->revision == 0x01) { + int i; + static const u8 eedata[4] = { 0xFE, 0x13, 0x10, 0xFF }; + + /* Re-write the first 4 bytes if we have an eeprom + * present and the revision id is 1, this fixes the + * corruption seen with 1310 B Silicon + */ + for (i = 0; i < 3; i++) + if (eeprom_write(etdev, i, eedata[i]) < 0) + write_failed = 1; } - - status = EXTRACT_STATUS_REGISTER(dword1); - - if (status & LBCIF_STATUS_PHY_QUEUE_AVAIL - && status & LBCIF_STATUS_I2C_IDLE) { - /* I2C read complete */ - break; + if (pdev->revision != 0x01 || write_failed) { + dev_err(&pdev->dev, + "Fatal EEPROM Status Error - 0x%04x\n", eestatus); + + /* This error could mean that there was an error + * reading the eeprom or that the eeprom doesn't exist. + * We will treat each case the same and not try to gather + * additional information that normally would come from the + * eeprom, like MAC Address + */ + etdev->has_eeprom = 0; + return -EIO; } } + etdev->has_eeprom = 1; - if (err || (index >= MAX_NUM_REGISTER_POLLS)) - return FAILURE; + /* Read the EEPROM for information regarding LED behavior. Refer to + * ET1310_phy.c, et131x_xcvr_init(), for its use. + */ + eeprom_read(etdev, 0x70, &etdev->eepromData[0]); + eeprom_read(etdev, 0x71, &etdev->eepromData[1]); - /* Step 6: */ - *pdata = EXTRACT_DATA_REGISTER(dword1); + if (etdev->eepromData[0] != 0xcd) + /* Disable all optional features */ + etdev->eepromData[1] = 0x00; - return (status & LBCIF_STATUS_ACK_ERROR) ? FAILURE : SUCCESS; + return 0; } diff --git a/drivers/staging/et131x/et1310_eeprom.h b/drivers/staging/et131x/et1310_eeprom.h index d8ac9a0439e2..6a6c6a632a8f 100644 --- a/drivers/staging/et131x/et1310_eeprom.h +++ b/drivers/staging/et131x/et1310_eeprom.h @@ -61,17 +61,43 @@ #include "et1310_address_map.h" -#ifndef SUCCESS -#define SUCCESS 0 -#define FAILURE 1 -#endif +/* + * EEPROM Defines + */ + +/* LBCIF Register Groups (addressed via 32-bit offsets) */ +#define LBCIF_DWORD0_GROUP 0xAC +#define LBCIF_DWORD1_GROUP 0xB0 + +/* LBCIF Registers (addressed via 8-bit offsets) */ +#define LBCIF_ADDRESS_REGISTER 0xAC +#define LBCIF_DATA_REGISTER 0xB0 +#define LBCIF_CONTROL_REGISTER 0xB1 +#define LBCIF_STATUS_REGISTER 0xB2 + +/* LBCIF Control Register Bits */ +#define LBCIF_CONTROL_SEQUENTIAL_READ 0x01 +#define LBCIF_CONTROL_PAGE_WRITE 0x02 +#define LBCIF_CONTROL_EEPROM_RELOAD 0x08 +#define LBCIF_CONTROL_TWO_BYTE_ADDR 0x20 +#define LBCIF_CONTROL_I2C_WRITE 0x40 +#define LBCIF_CONTROL_LBCIF_ENABLE 0x80 + +/* LBCIF Status Register Bits */ +#define LBCIF_STATUS_PHY_QUEUE_AVAIL 0x01 +#define LBCIF_STATUS_I2C_IDLE 0x02 +#define LBCIF_STATUS_ACK_ERROR 0x04 +#define LBCIF_STATUS_GENERAL_ERROR 0x08 +#define LBCIF_STATUS_CHECKSUM_ERROR 0x40 +#define LBCIF_STATUS_EEPROM_PRESENT 0x80 + +/* Miscellaneous Constraints */ +#define MAX_NUM_REGISTER_POLLS 1000 +#define MAX_NUM_WRITE_RETRIES 2 /* Forward declaration of the private adapter structure */ struct et131x_adapter; -int32_t EepromWriteByte(struct et131x_adapter *adapter, u32 unAddress, - u8 bData); -int32_t EepromReadByte(struct et131x_adapter *adapter, u32 unAddress, - u8 *pbData); +int et131x_init_eeprom(struct et131x_adapter *etdev); #endif /* _ET1310_EEPROM_H_ */ diff --git a/drivers/staging/et131x/et1310_mac.c b/drivers/staging/et131x/et1310_mac.c index f81e1cba8547..ae7cee43a165 100644 --- a/drivers/staging/et131x/et1310_mac.c +++ b/drivers/staging/et131x/et1310_mac.c @@ -101,41 +101,27 @@ void ConfigMACRegs1(struct et131x_adapter *etdev) struct _MAC_t __iomem *pMac = &etdev->regs->mac; MAC_STATION_ADDR1_t station1; MAC_STATION_ADDR2_t station2; - MAC_IPG_t ipg; - MAC_HFDP_t hfdp; - MII_MGMT_CFG_t mii_mgmt_cfg; + u32 ipg; /* First we need to reset everything. Write to MAC configuration * register 1 to perform reset. */ - writel(0xC00F0000, &pMac->cfg1.value); + writel(0xC00F0000, &pMac->cfg1); /* Next lets configure the MAC Inter-packet gap register */ - ipg.bits.non_B2B_ipg_1 = 0x38; /* 58d */ - ipg.bits.non_B2B_ipg_2 = 0x58; /* 88d */ - ipg.bits.min_ifg_enforce = 0x50; /* 80d */ - ipg.bits.B2B_ipg = 0x60; /* 96d */ - writel(ipg.value, &pMac->ipg.value); + ipg = 0x38005860; /* IPG1 0x38 IPG2 0x58 B2B 0x60 */ + ipg |= 0x50 << 8; /* ifg enforce 0x50 */ + writel(ipg, &pMac->ipg); /* Next lets configure the MAC Half Duplex register */ - hfdp.bits.alt_beb_trunc = 0xA; - hfdp.bits.alt_beb_enable = 0x0; - hfdp.bits.bp_no_backoff = 0x0; - hfdp.bits.no_backoff = 0x0; - hfdp.bits.excess_defer = 0x1; - hfdp.bits.rexmit_max = 0xF; - hfdp.bits.coll_window = 0x37; /* 55d */ - writel(hfdp.value, &pMac->hfdp.value); + /* BEB trunc 0xA, Ex Defer, Rexmit 0xF Coll 0x37 */ + writel(0x00A1F037, &pMac->hfdp); /* Next lets configure the MAC Interface Control register */ writel(0, &pMac->if_ctrl.value); /* Let's move on to setting up the mii management configuration */ - mii_mgmt_cfg.bits.reset_mii_mgmt = 0; - mii_mgmt_cfg.bits.scan_auto_incremt = 0; - mii_mgmt_cfg.bits.preamble_suppress = 0; - mii_mgmt_cfg.bits.mgmt_clk_reset = 0x7; - writel(mii_mgmt_cfg.value, &pMac->mii_mgmt_cfg.value); + writel(0x07, &pMac->mii_mgmt_cfg); /* Clock reset 0x7 */ /* Next lets configure the MAC Station Address register. These * values are read from the EEPROM during initialization and stored @@ -160,10 +146,10 @@ void ConfigMACRegs1(struct et131x_adapter *etdev) * Packets larger than (RegistryJumboPacket) that do not contain a * VLAN ID will be dropped by the Rx function. */ - writel(etdev->RegistryJumboPacket + 4, &pMac->max_fm_len.value); + writel(etdev->RegistryJumboPacket + 4, &pMac->max_fm_len); /* clear out MAC config reset */ - writel(0, &pMac->cfg1.value); + writel(0, &pMac->cfg1); } /** @@ -174,79 +160,59 @@ void ConfigMACRegs2(struct et131x_adapter *etdev) { int32_t delay = 0; struct _MAC_t __iomem *pMac = &etdev->regs->mac; - MAC_CFG1_t cfg1; - MAC_CFG2_t cfg2; + u32 cfg1; + u32 cfg2; MAC_IF_CTRL_t ifctrl; TXMAC_CTL_t ctl; ctl.value = readl(&etdev->regs->txmac.ctl.value); - cfg1.value = readl(&pMac->cfg1.value); - cfg2.value = readl(&pMac->cfg2.value); + cfg1 = readl(&pMac->cfg1); + cfg2 = readl(&pMac->cfg2); ifctrl.value = readl(&pMac->if_ctrl.value); + /* Set up the if mode bits */ + cfg2 &= ~0x300; if (etdev->linkspeed == TRUEPHY_SPEED_1000MBPS) { - cfg2.bits.if_mode = 0x2; + cfg2 |= 0x200; ifctrl.bits.phy_mode = 0x0; } else { - cfg2.bits.if_mode = 0x1; + cfg2 |= 0x100; ifctrl.bits.phy_mode = 0x1; } /* We need to enable Rx/Tx */ - cfg1.bits.rx_enable = 0x1; - cfg1.bits.tx_enable = 0x1; - - /* Set up flow control */ - cfg1.bits.tx_flow = 0x1; - - if ((etdev->FlowControl == RxOnly) || - (etdev->FlowControl == Both)) { - cfg1.bits.rx_flow = 0x1; - } else { - cfg1.bits.rx_flow = 0x0; - } - + cfg1 |= CFG1_RX_ENABLE|CFG1_TX_ENABLE|CFG1_TX_FLOW; /* Initialize loop back to off */ - cfg1.bits.loop_back = 0; - - writel(cfg1.value, &pMac->cfg1.value); + cfg1 &= ~(CFG1_LOOPBACK|CFG1_RX_FLOW); + if (etdev->FlowControl == RxOnly || etdev->FlowControl == Both) + cfg1 |= CFG1_RX_FLOW; + writel(cfg1, &pMac->cfg1); /* Now we need to initialize the MAC Configuration 2 register */ - cfg2.bits.preamble_len = 0x7; - cfg2.bits.huge_frame = 0x0; - /* LENGTH FIELD CHECKING bit4: Set this bit to cause the MAC to check - * the frame's length field to ensure it matches the actual data - * field length. Clear this bit if no length field checking is - * desired. Its default is 0. - */ - cfg2.bits.len_check = 0x1; + /* preamble 7, check length, huge frame off, pad crc, crc enable + full duplex off */ + cfg2 |= 0x7016; + cfg2 &= ~0x0021; - if (etdev->RegistryPhyLoopbk == false) { - cfg2.bits.pad_crc = 0x1; - cfg2.bits.crc_enable = 0x1; - } else { - cfg2.bits.pad_crc = 0; - cfg2.bits.crc_enable = 0; - } + /* Turn on duplex if needed */ + if (etdev->duplex_mode) + cfg2 |= 0x01; - /* 1 - full duplex, 0 - half-duplex */ - cfg2.bits.full_duplex = etdev->duplex_mode; ifctrl.bits.ghd_mode = !etdev->duplex_mode; writel(ifctrl.value, &pMac->if_ctrl.value); - writel(cfg2.value, &pMac->cfg2.value); + writel(cfg2, &pMac->cfg2); do { udelay(10); delay++; - cfg1.value = readl(&pMac->cfg1.value); - } while ((!cfg1.bits.syncd_rx_en || !cfg1.bits.syncd_tx_en) && - delay < 100); + cfg1 = readl(&pMac->cfg1); + } while ((cfg1 & CFG1_WAIT) != CFG1_WAIT && delay < 100); if (delay == 100) { dev_warn(&etdev->pdev->dev, "Syncd bits did not respond correctly cfg1 word 0x%08x\n", - cfg1.value); + cfg1); } /* Enable TXMAC */ diff --git a/drivers/staging/et131x/et1310_phy.c b/drivers/staging/et131x/et1310_phy.c index dd199bdb9eff..6ecad619f779 100644 --- a/drivers/staging/et131x/et1310_phy.c +++ b/drivers/staging/et131x/et1310_phy.c @@ -98,238 +98,498 @@ #include "et1310_mac.h" /* Prototypes for functions with local scope */ -static int et131x_xcvr_init(struct et131x_adapter *adapter); +static void et131x_xcvr_init(struct et131x_adapter *etdev); /** * PhyMiRead - Read from the PHY through the MII Interface on the MAC - * @adapter: pointer to our private adapter structure + * @etdev: pointer to our private adapter structure * @xcvrAddr: the address of the transciever * @xcvrReg: the register to read * @value: pointer to a 16-bit value in which the value will be stored * * Returns 0 on success, errno on failure (as defined in errno.h) */ -int PhyMiRead(struct et131x_adapter *adapter, uint8_t xcvrAddr, - uint8_t xcvrReg, uint16_t *value) +int PhyMiRead(struct et131x_adapter *etdev, u8 xcvrAddr, + u8 xcvrReg, u16 *value) { - struct _MAC_t __iomem *mac = &adapter->regs->mac; + struct _MAC_t __iomem *mac = &etdev->regs->mac; int status = 0; - uint32_t delay; - MII_MGMT_ADDR_t miiAddr; - MII_MGMT_CMD_t miiCmd; - MII_MGMT_INDICATOR_t miiIndicator; + u32 delay; + u32 miiAddr; + u32 miiCmd; + u32 miiIndicator; /* Save a local copy of the registers we are dealing with so we can * set them back */ - miiAddr.value = readl(&mac->mii_mgmt_addr.value); - miiCmd.value = readl(&mac->mii_mgmt_cmd.value); + miiAddr = readl(&mac->mii_mgmt_addr); + miiCmd = readl(&mac->mii_mgmt_cmd); /* Stop the current operation */ - writel(0, &mac->mii_mgmt_cmd.value); + writel(0, &mac->mii_mgmt_cmd); /* Set up the register we need to read from on the correct PHY */ - { - MII_MGMT_ADDR_t mii_mgmt_addr = { 0 }; - - mii_mgmt_addr.bits.phy_addr = xcvrAddr; - mii_mgmt_addr.bits.reg_addr = xcvrReg; - writel(mii_mgmt_addr.value, &mac->mii_mgmt_addr.value); - } + writel(MII_ADDR(xcvrAddr, xcvrReg), &mac->mii_mgmt_addr); /* Kick the read cycle off */ delay = 0; - writel(0x1, &mac->mii_mgmt_cmd.value); + writel(0x1, &mac->mii_mgmt_cmd); do { udelay(50); delay++; - miiIndicator.value = readl(&mac->mii_mgmt_indicator.value); - } while ((miiIndicator.bits.not_valid || miiIndicator.bits.busy) && - delay < 50); + miiIndicator = readl(&mac->mii_mgmt_indicator); + } while ((miiIndicator & MGMT_WAIT) && delay < 50); /* If we hit the max delay, we could not read the register */ - if (delay >= 50) { - dev_warn(&adapter->pdev->dev, + if (delay == 50) { + dev_warn(&etdev->pdev->dev, "xcvrReg 0x%08x could not be read\n", xcvrReg); - dev_warn(&adapter->pdev->dev, "status is 0x%08x\n", - miiIndicator.value); + dev_warn(&etdev->pdev->dev, "status is 0x%08x\n", + miiIndicator); status = -EIO; } /* If we hit here we were able to read the register and we need to - * return the value to the caller - */ - /* TODO: make this stuff a simple readw()?! */ - { - MII_MGMT_STAT_t mii_mgmt_stat; - - mii_mgmt_stat.value = readl(&mac->mii_mgmt_stat.value); - *value = (uint16_t) mii_mgmt_stat.bits.phy_stat; - } + * return the value to the caller */ + *value = readl(&mac->mii_mgmt_stat) & 0xFFFF; /* Stop the read operation */ - writel(0, &mac->mii_mgmt_cmd.value); + writel(0, &mac->mii_mgmt_cmd); /* set the registers we touched back to the state at which we entered * this function */ - writel(miiAddr.value, &mac->mii_mgmt_addr.value); - writel(miiCmd.value, &mac->mii_mgmt_cmd.value); + writel(miiAddr, &mac->mii_mgmt_addr); + writel(miiCmd, &mac->mii_mgmt_cmd); return status; } /** * MiWrite - Write to a PHY register through the MII interface of the MAC - * @adapter: pointer to our private adapter structure + * @etdev: pointer to our private adapter structure * @xcvrReg: the register to read * @value: 16-bit value to write * + * FIXME: one caller in netdev still + * * Return 0 on success, errno on failure (as defined in errno.h) */ -int MiWrite(struct et131x_adapter *adapter, uint8_t xcvrReg, uint16_t value) +int MiWrite(struct et131x_adapter *etdev, u8 xcvrReg, u16 value) { - struct _MAC_t __iomem *mac = &adapter->regs->mac; + struct _MAC_t __iomem *mac = &etdev->regs->mac; int status = 0; - uint8_t xcvrAddr = adapter->Stats.xcvr_addr; - uint32_t delay; - MII_MGMT_ADDR_t miiAddr; - MII_MGMT_CMD_t miiCmd; - MII_MGMT_INDICATOR_t miiIndicator; + u8 xcvrAddr = etdev->Stats.xcvr_addr; + u32 delay; + u32 miiAddr; + u32 miiCmd; + u32 miiIndicator; /* Save a local copy of the registers we are dealing with so we can * set them back */ - miiAddr.value = readl(&mac->mii_mgmt_addr.value); - miiCmd.value = readl(&mac->mii_mgmt_cmd.value); + miiAddr = readl(&mac->mii_mgmt_addr); + miiCmd = readl(&mac->mii_mgmt_cmd); /* Stop the current operation */ - writel(0, &mac->mii_mgmt_cmd.value); + writel(0, &mac->mii_mgmt_cmd); /* Set up the register we need to write to on the correct PHY */ - { - MII_MGMT_ADDR_t mii_mgmt_addr; - - mii_mgmt_addr.bits.phy_addr = xcvrAddr; - mii_mgmt_addr.bits.reg_addr = xcvrReg; - writel(mii_mgmt_addr.value, &mac->mii_mgmt_addr.value); - } + writel(MII_ADDR(xcvrAddr, xcvrReg), &mac->mii_mgmt_addr); /* Add the value to write to the registers to the mac */ - writel(value, &mac->mii_mgmt_ctrl.value); + writel(value, &mac->mii_mgmt_ctrl); delay = 0; do { udelay(50); delay++; - miiIndicator.value = readl(&mac->mii_mgmt_indicator.value); - } while (miiIndicator.bits.busy && delay < 100); + miiIndicator = readl(&mac->mii_mgmt_indicator); + } while ((miiIndicator & MGMT_BUSY) && delay < 100); /* If we hit the max delay, we could not write the register */ if (delay == 100) { - uint16_t TempValue; + u16 TempValue; - dev_warn(&adapter->pdev->dev, + dev_warn(&etdev->pdev->dev, "xcvrReg 0x%08x could not be written", xcvrReg); - dev_warn(&adapter->pdev->dev, "status is 0x%08x\n", - miiIndicator.value); - dev_warn(&adapter->pdev->dev, "command is 0x%08x\n", - readl(&mac->mii_mgmt_cmd.value)); + dev_warn(&etdev->pdev->dev, "status is 0x%08x\n", + miiIndicator); + dev_warn(&etdev->pdev->dev, "command is 0x%08x\n", + readl(&mac->mii_mgmt_cmd)); - MiRead(adapter, xcvrReg, &TempValue); + MiRead(etdev, xcvrReg, &TempValue); status = -EIO; } - /* Stop the write operation */ - writel(0, &mac->mii_mgmt_cmd.value); + writel(0, &mac->mii_mgmt_cmd); /* set the registers we touched back to the state at which we entered * this function */ - writel(miiAddr.value, &mac->mii_mgmt_addr.value); - writel(miiCmd.value, &mac->mii_mgmt_cmd.value); + writel(miiAddr, &mac->mii_mgmt_addr); + writel(miiCmd, &mac->mii_mgmt_cmd); return status; } /** * et131x_xcvr_find - Find the PHY ID - * @adapter: pointer to our private adapter structure + * @etdev: pointer to our private adapter structure * * Returns 0 on success, errno on failure (as defined in errno.h) */ -int et131x_xcvr_find(struct et131x_adapter *adapter) +int et131x_xcvr_find(struct et131x_adapter *etdev) { - int status = -ENODEV; - uint8_t xcvr_addr; + u8 xcvr_addr; MI_IDR1_t idr1; MI_IDR2_t idr2; - uint32_t xcvr_id; + u32 xcvr_id; /* We need to get xcvr id and address we just get the first one */ for (xcvr_addr = 0; xcvr_addr < 32; xcvr_addr++) { /* Read the ID from the PHY */ - PhyMiRead(adapter, xcvr_addr, - (uint8_t) offsetof(MI_REGS_t, idr1), + PhyMiRead(etdev, xcvr_addr, + (u8) offsetof(MI_REGS_t, idr1), &idr1.value); - PhyMiRead(adapter, xcvr_addr, - (uint8_t) offsetof(MI_REGS_t, idr2), + PhyMiRead(etdev, xcvr_addr, + (u8) offsetof(MI_REGS_t, idr2), &idr2.value); - xcvr_id = (uint32_t) ((idr1.value << 16) | idr2.value); + xcvr_id = (u32) ((idr1.value << 16) | idr2.value); - if ((idr1.value != 0) && (idr1.value != 0xffff)) { - adapter->Stats.xcvr_id = xcvr_id; - adapter->Stats.xcvr_addr = xcvr_addr; - - status = 0; - break; + if (idr1.value != 0 && idr1.value != 0xffff) { + etdev->Stats.xcvr_id = xcvr_id; + etdev->Stats.xcvr_addr = xcvr_addr; + return 0; } } - return status; + return -ENODEV; +} + +void ET1310_PhyReset(struct et131x_adapter *etdev) +{ + MiWrite(etdev, PHY_CONTROL, 0x8000); +} + +/** + * ET1310_PhyPowerDown - PHY power control + * @etdev: device to control + * @down: true for off/false for back on + * + * one hundred, ten, one thousand megs + * How would you like to have your LAN accessed + * Can't you see that this code processed + * Phy power, phy power.. + */ + +void ET1310_PhyPowerDown(struct et131x_adapter *etdev, bool down) +{ + u16 data; + + MiRead(etdev, PHY_CONTROL, &data); + data &= ~0x0800; /* Power UP */ + if (down) /* Power DOWN */ + data |= 0x0800; + MiWrite(etdev, PHY_CONTROL, data); +} + +/** + * ET130_PhyAutoNEg - autonegotiate control + * @etdev: device to control + * @enabe: autoneg on/off + * + * Set up the autonegotiation state according to whether we will be + * negotiating the state or forcing a speed. + */ + +static void ET1310_PhyAutoNeg(struct et131x_adapter *etdev, bool enable) +{ + u16 data; + + MiRead(etdev, PHY_CONTROL, &data); + data &= ~0x1000; /* Autonegotiation OFF */ + if (enable) + data |= 0x1000; /* Autonegotiation ON */ + MiWrite(etdev, PHY_CONTROL, data); +} + +/** + * ET130_PhyDuplexMode - duplex control + * @etdev: device to control + * @duplex: duplex on/off + * + * Set up the duplex state on the PHY + */ + +static void ET1310_PhyDuplexMode(struct et131x_adapter *etdev, u16 duplex) +{ + u16 data; + + MiRead(etdev, PHY_CONTROL, &data); + data &= ~0x100; /* Set Half Duplex */ + if (duplex == TRUEPHY_DUPLEX_FULL) + data |= 0x100; /* Set Full Duplex */ + MiWrite(etdev, PHY_CONTROL, data); +} + +/** + * ET130_PhySpeedSelect - speed control + * @etdev: device to control + * @duplex: duplex on/off + * + * Set the speed of our PHY. + */ + +static void ET1310_PhySpeedSelect(struct et131x_adapter *etdev, u16 speed) +{ + u16 data; + static const u16 bits[3]={0x0000, 0x2000, 0x0040}; + + /* Read the PHY control register */ + MiRead(etdev, PHY_CONTROL, &data); + /* Clear all Speed settings (Bits 6, 13) */ + data &= ~0x2040; + /* Write back the new speed */ + MiWrite(etdev, PHY_CONTROL, data | bits[speed]); +} + +/** + * ET1310_PhyLinkStatus - read link state + * @etdev: device to read + * @link_status: reported link state + * @autoneg: reported autonegotiation state (complete/incomplete/disabled) + * @linkspeed: returnedlink speed in use + * @duplex_mode: reported half/full duplex state + * @mdi_mdix: not yet working + * @masterslave: report whether we are master or slave + * @polarity: link polarity + * + * I can read your lan like a magazine + * I see if your up + * I know your link speed + * I see all the setting that you'd rather keep + */ + +static void ET1310_PhyLinkStatus(struct et131x_adapter *etdev, + u8 *link_status, + u32 *autoneg, + u32 *linkspeed, + u32 *duplex_mode, + u32 *mdi_mdix, + u32 *masterslave, u32 *polarity) +{ + u16 mistatus = 0; + u16 is1000BaseT = 0; + u16 vmi_phystatus = 0; + u16 control = 0; + + MiRead(etdev, PHY_STATUS, &mistatus); + MiRead(etdev, PHY_1000_STATUS, &is1000BaseT); + MiRead(etdev, PHY_PHY_STATUS, &vmi_phystatus); + MiRead(etdev, PHY_CONTROL, &control); + + *link_status = (vmi_phystatus & 0x0040) ? 1 : 0; + *autoneg = (control & 0x1000) ? ((vmi_phystatus & 0x0020) ? + TRUEPHY_ANEG_COMPLETE : + TRUEPHY_ANEG_NOT_COMPLETE) : + TRUEPHY_ANEG_DISABLED; + *linkspeed = (vmi_phystatus & 0x0300) >> 8; + *duplex_mode = (vmi_phystatus & 0x0080) >> 7; + /* NOTE: Need to complete this */ + *mdi_mdix = 0; + + *masterslave = (is1000BaseT & 0x4000) ? + TRUEPHY_CFG_MASTER : TRUEPHY_CFG_SLAVE; + *polarity = (vmi_phystatus & 0x0400) ? + TRUEPHY_POLARITY_INVERTED : TRUEPHY_POLARITY_NORMAL; +} + +static void ET1310_PhyAndOrReg(struct et131x_adapter *etdev, + u16 regnum, u16 andMask, u16 orMask) +{ + u16 reg; + + MiRead(etdev, regnum, ®); + reg &= andMask; + reg |= orMask; + MiWrite(etdev, regnum, reg); +} + +/* Still used from _mac for BIT_READ */ +void ET1310_PhyAccessMiBit(struct et131x_adapter *etdev, u16 action, + u16 regnum, u16 bitnum, u8 *value) +{ + u16 reg; + u16 mask = 0x0001 << bitnum; + + /* Read the requested register */ + MiRead(etdev, regnum, ®); + + switch (action) { + case TRUEPHY_BIT_READ: + *value = (reg & mask) >> bitnum; + break; + + case TRUEPHY_BIT_SET: + MiWrite(etdev, regnum, reg | mask); + break; + + case TRUEPHY_BIT_CLEAR: + MiWrite(etdev, regnum, reg & ~mask); + break; + + default: + break; + } +} + +void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *etdev, + u16 duplex) +{ + u16 data; + + /* Read the PHY 1000 Base-T Control Register */ + MiRead(etdev, PHY_1000_CONTROL, &data); + + /* Clear Bits 8,9 */ + data &= ~0x0300; + + switch (duplex) { + case TRUEPHY_ADV_DUPLEX_NONE: + /* Duplex already cleared, do nothing */ + break; + + case TRUEPHY_ADV_DUPLEX_FULL: + /* Set Bit 9 */ + data |= 0x0200; + break; + + case TRUEPHY_ADV_DUPLEX_HALF: + /* Set Bit 8 */ + data |= 0x0100; + break; + + case TRUEPHY_ADV_DUPLEX_BOTH: + default: + data |= 0x0300; + break; + } + + /* Write back advertisement */ + MiWrite(etdev, PHY_1000_CONTROL, data); +} + +static void ET1310_PhyAdvertise100BaseT(struct et131x_adapter *etdev, + u16 duplex) +{ + u16 data; + + /* Read the Autonegotiation Register (10/100) */ + MiRead(etdev, PHY_AUTO_ADVERTISEMENT, &data); + + /* Clear bits 7,8 */ + data &= ~0x0180; + + switch (duplex) { + case TRUEPHY_ADV_DUPLEX_NONE: + /* Duplex already cleared, do nothing */ + break; + + case TRUEPHY_ADV_DUPLEX_FULL: + /* Set Bit 8 */ + data |= 0x0100; + break; + + case TRUEPHY_ADV_DUPLEX_HALF: + /* Set Bit 7 */ + data |= 0x0080; + break; + + case TRUEPHY_ADV_DUPLEX_BOTH: + default: + /* Set Bits 7,8 */ + data |= 0x0180; + break; + } + + /* Write back advertisement */ + MiWrite(etdev, PHY_AUTO_ADVERTISEMENT, data); +} + +static void ET1310_PhyAdvertise10BaseT(struct et131x_adapter *etdev, + u16 duplex) +{ + u16 data; + + /* Read the Autonegotiation Register (10/100) */ + MiRead(etdev, PHY_AUTO_ADVERTISEMENT, &data); + + /* Clear bits 5,6 */ + data &= ~0x0060; + + switch (duplex) { + case TRUEPHY_ADV_DUPLEX_NONE: + /* Duplex already cleared, do nothing */ + break; + + case TRUEPHY_ADV_DUPLEX_FULL: + /* Set Bit 6 */ + data |= 0x0040; + break; + + case TRUEPHY_ADV_DUPLEX_HALF: + /* Set Bit 5 */ + data |= 0x0020; + break; + + case TRUEPHY_ADV_DUPLEX_BOTH: + default: + /* Set Bits 5,6 */ + data |= 0x0060; + break; + } + + /* Write back advertisement */ + MiWrite(etdev, PHY_AUTO_ADVERTISEMENT, data); } /** * et131x_setphy_normal - Set PHY for normal operation. - * @adapter: pointer to our private adapter structure + * @etdev: pointer to our private adapter structure * * Used by Power Management to force the PHY into 10 Base T half-duplex mode, * when going to D3 in WOL mode. Also used during initialization to set the * PHY for normal operation. */ -int et131x_setphy_normal(struct et131x_adapter *adapter) +void et131x_setphy_normal(struct et131x_adapter *etdev) { - int status; - /* Make sure the PHY is powered up */ - ET1310_PhyPowerDown(adapter, 0); - status = et131x_xcvr_init(adapter); - return status; + ET1310_PhyPowerDown(etdev, 0); + et131x_xcvr_init(etdev); } + /** * et131x_xcvr_init - Init the phy if we are setting it into force mode - * @adapter: pointer to our private adapter structure + * @etdev: pointer to our private adapter structure * - * Returns 0 on success, errno on failure (as defined in errno.h) */ -static int et131x_xcvr_init(struct et131x_adapter *adapter) +static void et131x_xcvr_init(struct et131x_adapter *etdev) { - int status = 0; MI_IMR_t imr; MI_ISR_t isr; MI_LCR2_t lcr2; /* Zero out the adapter structure variable representing BMSR */ - adapter->Bmsr.value = 0; + etdev->Bmsr.value = 0; - MiRead(adapter, (uint8_t) offsetof(MI_REGS_t, isr), &isr.value); - - MiRead(adapter, (uint8_t) offsetof(MI_REGS_t, imr), &imr.value); + MiRead(etdev, (u8) offsetof(MI_REGS_t, isr), &isr.value); + MiRead(etdev, (u8) offsetof(MI_REGS_t, imr), &imr.value); /* Set the link status interrupt only. Bad behavior when link status * and auto neg are set, we run into a nested interrupt problem @@ -338,7 +598,7 @@ static int et131x_xcvr_init(struct et131x_adapter *adapter) imr.bits.link_status = 0x1; imr.bits.autoneg_status = 0x1; - MiWrite(adapter, (uint8_t) offsetof(MI_REGS_t, imr), imr.value); + MiWrite(etdev, (u8) offsetof(MI_REGS_t, imr), imr.value); /* Set the LED behavior such that LED 1 indicates speed (off = * 10Mbits, blink = 100Mbits, on = 1000Mbits) and LED 2 indicates @@ -348,111 +608,138 @@ static int et131x_xcvr_init(struct et131x_adapter *adapter) * vendors; The LED behavior is now determined by vendor data in the * EEPROM. However, the above description is the default. */ - if ((adapter->eepromData[1] & 0x4) == 0) { - MiRead(adapter, (uint8_t) offsetof(MI_REGS_t, lcr2), + if ((etdev->eepromData[1] & 0x4) == 0) { + MiRead(etdev, (u8) offsetof(MI_REGS_t, lcr2), &lcr2.value); - if ((adapter->eepromData[1] & 0x8) == 0) + if ((etdev->eepromData[1] & 0x8) == 0) lcr2.bits.led_tx_rx = 0x3; else lcr2.bits.led_tx_rx = 0x4; lcr2.bits.led_link = 0xa; - MiWrite(adapter, (uint8_t) offsetof(MI_REGS_t, lcr2), + MiWrite(etdev, (u8) offsetof(MI_REGS_t, lcr2), lcr2.value); } /* Determine if we need to go into a force mode and set it */ - if (adapter->AiForceSpeed == 0 && adapter->AiForceDpx == 0) { - if ((adapter->RegistryFlowControl == TxOnly) || - (adapter->RegistryFlowControl == Both)) { - ET1310_PhyAccessMiBit(adapter, + if (etdev->AiForceSpeed == 0 && etdev->AiForceDpx == 0) { + if (etdev->RegistryFlowControl == TxOnly || + etdev->RegistryFlowControl == Both) + ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_SET, 4, 11, NULL); - } else { - ET1310_PhyAccessMiBit(adapter, + else + ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_CLEAR, 4, 11, NULL); - } - if (adapter->RegistryFlowControl == Both) { - ET1310_PhyAccessMiBit(adapter, + if (etdev->RegistryFlowControl == Both) + ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_SET, 4, 10, NULL); - } else { - ET1310_PhyAccessMiBit(adapter, + else + ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_CLEAR, 4, 10, NULL); - } /* Set the phy to autonegotiation */ - ET1310_PhyAutoNeg(adapter, true); + ET1310_PhyAutoNeg(etdev, true); /* NOTE - Do we need this? */ - ET1310_PhyAccessMiBit(adapter, TRUEPHY_BIT_SET, 0, 9, NULL); - return status; - } else { - ET1310_PhyAutoNeg(adapter, false); - - /* Set to the correct force mode. */ - if (adapter->AiForceDpx != 1) { - if ((adapter->RegistryFlowControl == TxOnly) || - (adapter->RegistryFlowControl == Both)) { - ET1310_PhyAccessMiBit(adapter, - TRUEPHY_BIT_SET, 4, 11, - NULL); - } else { - ET1310_PhyAccessMiBit(adapter, - TRUEPHY_BIT_CLEAR, 4, 11, - NULL); - } + ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_SET, 0, 9, NULL); + return; + } - if (adapter->RegistryFlowControl == Both) { - ET1310_PhyAccessMiBit(adapter, - TRUEPHY_BIT_SET, 4, 10, - NULL); - } else { - ET1310_PhyAccessMiBit(adapter, - TRUEPHY_BIT_CLEAR, 4, 10, - NULL); - } - } else { - ET1310_PhyAccessMiBit(adapter, - TRUEPHY_BIT_CLEAR, 4, 10, NULL); - ET1310_PhyAccessMiBit(adapter, + ET1310_PhyAutoNeg(etdev, false); + + /* Set to the correct force mode. */ + if (etdev->AiForceDpx != 1) { + if (etdev->RegistryFlowControl == TxOnly || + etdev->RegistryFlowControl == Both) + ET1310_PhyAccessMiBit(etdev, + TRUEPHY_BIT_SET, 4, 11, NULL); + else + ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_CLEAR, 4, 11, NULL); - } - switch (adapter->AiForceSpeed) { - case 10: - if (adapter->AiForceDpx == 1) - TPAL_SetPhy10HalfDuplex(adapter); - else if (adapter->AiForceDpx == 2) - TPAL_SetPhy10FullDuplex(adapter); - else - TPAL_SetPhy10Force(adapter); - break; - case 100: - if (adapter->AiForceDpx == 1) - TPAL_SetPhy100HalfDuplex(adapter); - else if (adapter->AiForceDpx == 2) - TPAL_SetPhy100FullDuplex(adapter); - else - TPAL_SetPhy100Force(adapter); - break; - case 1000: - TPAL_SetPhy1000FullDuplex(adapter); - break; + if (etdev->RegistryFlowControl == Both) + ET1310_PhyAccessMiBit(etdev, + TRUEPHY_BIT_SET, 4, 10, NULL); + else + ET1310_PhyAccessMiBit(etdev, + TRUEPHY_BIT_CLEAR, 4, 10, NULL); + } else { + ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_CLEAR, 4, 10, NULL); + ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_CLEAR, 4, 11, NULL); + } + ET1310_PhyPowerDown(etdev, 1); + switch (etdev->AiForceSpeed) { + case 10: + /* First we need to turn off all other advertisement */ + ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); + ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); + if (etdev->AiForceDpx == 1) { + /* Set our advertise values accordingly */ + ET1310_PhyAdvertise10BaseT(etdev, + TRUEPHY_ADV_DUPLEX_HALF); + } else if (etdev->AiForceDpx == 2) { + /* Set our advertise values accordingly */ + ET1310_PhyAdvertise10BaseT(etdev, + TRUEPHY_ADV_DUPLEX_FULL); + } else { + /* Disable autoneg */ + ET1310_PhyAutoNeg(etdev, false); + /* Disable rest of the advertisements */ + ET1310_PhyAdvertise10BaseT(etdev, + TRUEPHY_ADV_DUPLEX_NONE); + /* Force 10 Mbps */ + ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_10MBPS); + /* Force Full duplex */ + ET1310_PhyDuplexMode(etdev, TRUEPHY_DUPLEX_FULL); } - - return status; + break; + case 100: + /* first we need to turn off all other advertisement */ + ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); + ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); + if (etdev->AiForceDpx == 1) { + /* Set our advertise values accordingly */ + ET1310_PhyAdvertise100BaseT(etdev, + TRUEPHY_ADV_DUPLEX_HALF); + /* Set speed */ + ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_100MBPS); + } else if (etdev->AiForceDpx == 2) { + /* Set our advertise values accordingly */ + ET1310_PhyAdvertise100BaseT(etdev, + TRUEPHY_ADV_DUPLEX_FULL); + } else { + /* Disable autoneg */ + ET1310_PhyAutoNeg(etdev, false); + /* Disable other advertisement */ + ET1310_PhyAdvertise100BaseT(etdev, + TRUEPHY_ADV_DUPLEX_NONE); + /* Force 100 Mbps */ + ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_100MBPS); + /* Force Full duplex */ + ET1310_PhyDuplexMode(etdev, TRUEPHY_DUPLEX_FULL); + } + break; + case 1000: + /* first we need to turn off all other advertisement */ + ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); + ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); + /* set our advertise values accordingly */ + ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL); + break; } + ET1310_PhyPowerDown(etdev, 0); } void et131x_Mii_check(struct et131x_adapter *etdev, MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints) { - uint8_t link_status; - uint32_t autoneg_status; - uint32_t speed; - uint32_t duplex; - uint32_t mdi_mdix; - uint32_t masterslave; - uint32_t polarity; + u8 link_status; + u32 autoneg_status; + u32 speed; + u32 duplex; + u32 mdi_mdix; + u32 masterslave; + u32 polarity; unsigned long flags; if (bmsr_ints.bits.link_status) { @@ -469,9 +756,7 @@ void et131x_Mii_check(struct et131x_adapter *etdev, spin_unlock_irqrestore(&etdev->Lock, flags); - /* Don't indicate state if we're in loopback mode */ - if (etdev->RegistryPhyLoopbk == false) - netif_carrier_on(etdev->netdev); + netif_carrier_on(etdev->netdev); } else { dev_warn(&etdev->pdev->dev, "Link down - cable problem ?\n"); @@ -481,7 +766,7 @@ void et131x_Mii_check(struct et131x_adapter *etdev, * TruePHY? * && TRU_QueryCoreType(etdev->hTruePhy, 0) == EMI_TRUEPHY_A13O) { */ - uint16_t Register18; + u16 Register18; MiRead(etdev, 0x12, &Register18); MiWrite(etdev, 0x12, Register18 | 0x4); @@ -504,11 +789,7 @@ void et131x_Mii_check(struct et131x_adapter *etdev, spin_unlock_irqrestore(&etdev->Lock, flags); - /* Only indicate state if we're in loopback - * mode - */ - if (etdev->RegistryPhyLoopbk == false) - netif_carrier_off(etdev->netdev); + netif_carrier_off(etdev->netdev); } etdev->linkspeed = 0; @@ -561,7 +842,7 @@ void et131x_Mii_check(struct et131x_adapter *etdev, * TruePHY? * && TRU_QueryCoreType(etdev->hTruePhy, 0)== EMI_TRUEPHY_A13O) { */ - uint16_t Register18; + u16 Register18; MiRead(etdev, 0x12, &Register18); MiWrite(etdev, 0x12, Register18 | 0x4); @@ -583,212 +864,13 @@ void et131x_Mii_check(struct et131x_adapter *etdev, } } -/** - * TPAL_SetPhy10HalfDuplex - Force the phy into 10 Base T Half Duplex mode. - * @etdev: pointer to the adapter structure - * - * Also sets the MAC so it is syncd up properly - */ -void TPAL_SetPhy10HalfDuplex(struct et131x_adapter *etdev) -{ - /* Power down PHY */ - ET1310_PhyPowerDown(etdev, 1); - - /* First we need to turn off all other advertisement */ - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - /* Set our advertise values accordingly */ - ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_HALF); - - /* Power up PHY */ - ET1310_PhyPowerDown(etdev, 0); -} - -/** - * TPAL_SetPhy10FullDuplex - Force the phy into 10 Base T Full Duplex mode. - * @etdev: pointer to the adapter structure - * - * Also sets the MAC so it is syncd up properly - */ -void TPAL_SetPhy10FullDuplex(struct et131x_adapter *etdev) -{ - /* Power down PHY */ - ET1310_PhyPowerDown(etdev, 1); - - /* First we need to turn off all other advertisement */ - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - /* Set our advertise values accordingly */ - ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL); - - /* Power up PHY */ - ET1310_PhyPowerDown(etdev, 0); -} - -/** - * TPAL_SetPhy10Force - Force Base-T FD mode WITHOUT using autonegotiation - * @etdev: pointer to the adapter structure - */ -void TPAL_SetPhy10Force(struct et131x_adapter *etdev) -{ - /* Power down PHY */ - ET1310_PhyPowerDown(etdev, 1); - - /* Disable autoneg */ - ET1310_PhyAutoNeg(etdev, false); - - /* Disable all advertisement */ - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - /* Force 10 Mbps */ - ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_10MBPS); - - /* Force Full duplex */ - ET1310_PhyDuplexMode(etdev, TRUEPHY_DUPLEX_FULL); - - /* Power up PHY */ - ET1310_PhyPowerDown(etdev, 0); -} - -/** - * TPAL_SetPhy100HalfDuplex - Force 100 Base T Half Duplex mode. - * @etdev: pointer to the adapter structure - * - * Also sets the MAC so it is syncd up properly. - */ -void TPAL_SetPhy100HalfDuplex(struct et131x_adapter *etdev) -{ - /* Power down PHY */ - ET1310_PhyPowerDown(etdev, 1); - - /* first we need to turn off all other advertisement */ - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - /* Set our advertise values accordingly */ - ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_HALF); - - /* Set speed */ - ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_100MBPS); - - /* Power up PHY */ - ET1310_PhyPowerDown(etdev, 0); -} - -/** - * TPAL_SetPhy100FullDuplex - Force 100 Base T Full Duplex mode. - * @etdev: pointer to the adapter structure - * - * Also sets the MAC so it is syncd up properly - */ -void TPAL_SetPhy100FullDuplex(struct et131x_adapter *etdev) -{ - /* Power down PHY */ - ET1310_PhyPowerDown(etdev, 1); - - /* First we need to turn off all other advertisement */ - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - /* Set our advertise values accordingly */ - ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL); - - /* Power up PHY */ - ET1310_PhyPowerDown(etdev, 0); -} - -/** - * TPAL_SetPhy100Force - Force 100 BaseT FD mode WITHOUT using autonegotiation - * @etdev: pointer to the adapter structure - */ -void TPAL_SetPhy100Force(struct et131x_adapter *etdev) -{ - /* Power down PHY */ - ET1310_PhyPowerDown(etdev, 1); - - /* Disable autoneg */ - ET1310_PhyAutoNeg(etdev, false); - - /* Disable all advertisement */ - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - /* Force 100 Mbps */ - ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_100MBPS); - - /* Force Full duplex */ - ET1310_PhyDuplexMode(etdev, TRUEPHY_DUPLEX_FULL); - - /* Power up PHY */ - ET1310_PhyPowerDown(etdev, 0); -} - -/** - * TPAL_SetPhy1000FullDuplex - Force 1000 Base T Full Duplex mode - * @etdev: pointer to the adapter structure - * - * Also sets the MAC so it is syncd up properly. - */ -void TPAL_SetPhy1000FullDuplex(struct et131x_adapter *etdev) -{ - /* Power down PHY */ - ET1310_PhyPowerDown(etdev, 1); - - /* first we need to turn off all other advertisement */ - ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - /* set our advertise values accordingly */ - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL); - - /* power up PHY */ - ET1310_PhyPowerDown(etdev, 0); -} - -/** - * TPAL_SetPhyAutoNeg - Set phy to autonegotiation mode. - * @etdev: pointer to the adapter structure - */ -void TPAL_SetPhyAutoNeg(struct et131x_adapter *etdev) -{ - /* Power down PHY */ - ET1310_PhyPowerDown(etdev, 1); - - /* Turn on advertisement of all capabilities */ - ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_BOTH); - - ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_BOTH); - - if (etdev->pdev->device != ET131X_PCI_DEVICE_ID_FAST) - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL); - else - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - - /* Make sure auto-neg is ON (it is disabled in FORCE modes) */ - ET1310_PhyAutoNeg(etdev, true); - - /* Power up PHY */ - ET1310_PhyPowerDown(etdev, 0); -} - - /* * The routines which follow provide low-level access to the PHY, and are used * primarily by the routines above (although there are a few places elsewhere * in the driver where this level of access is required). */ -static const uint16_t ConfigPhy[25][2] = { +static const u16 ConfigPhy[25][2] = { /* Reg Value Register */ /* Addr */ {0x880B, 0x0926}, /* AfeIfCreg4B1000Msbs */ @@ -831,7 +913,7 @@ static const uint16_t ConfigPhy[25][2] = { /* condensed version of the phy initialization routine */ void ET1310_PhyInit(struct et131x_adapter *etdev) { - uint16_t data, index; + u16 data, index; if (etdev == NULL) return; @@ -896,304 +978,3 @@ void ET1310_PhyInit(struct et131x_adapter *etdev) MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0002); } -void ET1310_PhyReset(struct et131x_adapter *etdev) -{ - MiWrite(etdev, PHY_CONTROL, 0x8000); -} - -void ET1310_PhyPowerDown(struct et131x_adapter *etdev, bool down) -{ - uint16_t data; - - MiRead(etdev, PHY_CONTROL, &data); - - if (down == false) { - /* Power UP */ - data &= ~0x0800; - MiWrite(etdev, PHY_CONTROL, data); - } else { - /* Power DOWN */ - data |= 0x0800; - MiWrite(etdev, PHY_CONTROL, data); - } -} - -void ET1310_PhyAutoNeg(struct et131x_adapter *etdev, bool enable) -{ - uint16_t data; - - MiRead(etdev, PHY_CONTROL, &data); - - if (enable == true) { - /* Autonegotiation ON */ - data |= 0x1000; - MiWrite(etdev, PHY_CONTROL, data); - } else { - /* Autonegotiation OFF */ - data &= ~0x1000; - MiWrite(etdev, PHY_CONTROL, data); - } -} - -void ET1310_PhyDuplexMode(struct et131x_adapter *etdev, uint16_t duplex) -{ - uint16_t data; - - MiRead(etdev, PHY_CONTROL, &data); - - if (duplex == TRUEPHY_DUPLEX_FULL) { - /* Set Full Duplex */ - data |= 0x100; - MiWrite(etdev, PHY_CONTROL, data); - } else { - /* Set Half Duplex */ - data &= ~0x100; - MiWrite(etdev, PHY_CONTROL, data); - } -} - -void ET1310_PhySpeedSelect(struct et131x_adapter *etdev, uint16_t speed) -{ - uint16_t data; - - /* Read the PHY control register */ - MiRead(etdev, PHY_CONTROL, &data); - - /* Clear all Speed settings (Bits 6, 13) */ - data &= ~0x2040; - - /* Reset the speed bits based on user selection */ - switch (speed) { - case TRUEPHY_SPEED_10MBPS: - /* Bits already cleared above, do nothing */ - break; - - case TRUEPHY_SPEED_100MBPS: - /* 100M == Set bit 13 */ - data |= 0x2000; - break; - - case TRUEPHY_SPEED_1000MBPS: - default: - data |= 0x0040; - break; - } - - /* Write back the new speed */ - MiWrite(etdev, PHY_CONTROL, data); -} - -void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *etdev, - uint16_t duplex) -{ - uint16_t data; - - /* Read the PHY 1000 Base-T Control Register */ - MiRead(etdev, PHY_1000_CONTROL, &data); - - /* Clear Bits 8,9 */ - data &= ~0x0300; - - switch (duplex) { - case TRUEPHY_ADV_DUPLEX_NONE: - /* Duplex already cleared, do nothing */ - break; - - case TRUEPHY_ADV_DUPLEX_FULL: - /* Set Bit 9 */ - data |= 0x0200; - break; - - case TRUEPHY_ADV_DUPLEX_HALF: - /* Set Bit 8 */ - data |= 0x0100; - break; - - case TRUEPHY_ADV_DUPLEX_BOTH: - default: - data |= 0x0300; - break; - } - - /* Write back advertisement */ - MiWrite(etdev, PHY_1000_CONTROL, data); -} - -void ET1310_PhyAdvertise100BaseT(struct et131x_adapter *etdev, - uint16_t duplex) -{ - uint16_t data; - - /* Read the Autonegotiation Register (10/100) */ - MiRead(etdev, PHY_AUTO_ADVERTISEMENT, &data); - - /* Clear bits 7,8 */ - data &= ~0x0180; - - switch (duplex) { - case TRUEPHY_ADV_DUPLEX_NONE: - /* Duplex already cleared, do nothing */ - break; - - case TRUEPHY_ADV_DUPLEX_FULL: - /* Set Bit 8 */ - data |= 0x0100; - break; - - case TRUEPHY_ADV_DUPLEX_HALF: - /* Set Bit 7 */ - data |= 0x0080; - break; - - case TRUEPHY_ADV_DUPLEX_BOTH: - default: - /* Set Bits 7,8 */ - data |= 0x0180; - break; - } - - /* Write back advertisement */ - MiWrite(etdev, PHY_AUTO_ADVERTISEMENT, data); -} - -void ET1310_PhyAdvertise10BaseT(struct et131x_adapter *etdev, - uint16_t duplex) -{ - uint16_t data; - - /* Read the Autonegotiation Register (10/100) */ - MiRead(etdev, PHY_AUTO_ADVERTISEMENT, &data); - - /* Clear bits 5,6 */ - data &= ~0x0060; - - switch (duplex) { - case TRUEPHY_ADV_DUPLEX_NONE: - /* Duplex already cleared, do nothing */ - break; - - case TRUEPHY_ADV_DUPLEX_FULL: - /* Set Bit 6 */ - data |= 0x0040; - break; - - case TRUEPHY_ADV_DUPLEX_HALF: - /* Set Bit 5 */ - data |= 0x0020; - break; - - case TRUEPHY_ADV_DUPLEX_BOTH: - default: - /* Set Bits 5,6 */ - data |= 0x0060; - break; - } - - /* Write back advertisement */ - MiWrite(etdev, PHY_AUTO_ADVERTISEMENT, data); -} - -void ET1310_PhyLinkStatus(struct et131x_adapter *etdev, - uint8_t *link_status, - uint32_t *autoneg, - uint32_t *linkspeed, - uint32_t *duplex_mode, - uint32_t *mdi_mdix, - uint32_t *masterslave, uint32_t *polarity) -{ - uint16_t mistatus = 0; - uint16_t is1000BaseT = 0; - uint16_t vmi_phystatus = 0; - uint16_t control = 0; - - MiRead(etdev, PHY_STATUS, &mistatus); - MiRead(etdev, PHY_1000_STATUS, &is1000BaseT); - MiRead(etdev, PHY_PHY_STATUS, &vmi_phystatus); - MiRead(etdev, PHY_CONTROL, &control); - - if (link_status) { - *link_status = - (unsigned char)((vmi_phystatus & 0x0040) ? 1 : 0); - } - - if (autoneg) { - *autoneg = - (control & 0x1000) ? ((vmi_phystatus & 0x0020) ? - TRUEPHY_ANEG_COMPLETE : - TRUEPHY_ANEG_NOT_COMPLETE) : - TRUEPHY_ANEG_DISABLED; - } - - if (linkspeed) - *linkspeed = (vmi_phystatus & 0x0300) >> 8; - - if (duplex_mode) - *duplex_mode = (vmi_phystatus & 0x0080) >> 7; - - if (mdi_mdix) - /* NOTE: Need to complete this */ - *mdi_mdix = 0; - - if (masterslave) { - *masterslave = - (is1000BaseT & 0x4000) ? TRUEPHY_CFG_MASTER : - TRUEPHY_CFG_SLAVE; - } - - if (polarity) { - *polarity = - (vmi_phystatus & 0x0400) ? TRUEPHY_POLARITY_INVERTED : - TRUEPHY_POLARITY_NORMAL; - } -} - -void ET1310_PhyAndOrReg(struct et131x_adapter *etdev, - uint16_t regnum, uint16_t andMask, uint16_t orMask) -{ - uint16_t reg; - - /* Read the requested register */ - MiRead(etdev, regnum, ®); - - /* Apply the AND mask */ - reg &= andMask; - - /* Apply the OR mask */ - reg |= orMask; - - /* Write the value back to the register */ - MiWrite(etdev, regnum, reg); -} - -void ET1310_PhyAccessMiBit(struct et131x_adapter *etdev, uint16_t action, - uint16_t regnum, uint16_t bitnum, uint8_t *value) -{ - uint16_t reg; - uint16_t mask = 0; - - /* Create a mask to isolate the requested bit */ - mask = 0x0001 << bitnum; - - /* Read the requested register */ - MiRead(etdev, regnum, ®); - - switch (action) { - case TRUEPHY_BIT_READ: - if (value != NULL) - *value = (reg & mask) >> bitnum; - break; - - case TRUEPHY_BIT_SET: - reg |= mask; - MiWrite(etdev, regnum, reg); - break; - - case TRUEPHY_BIT_CLEAR: - reg &= ~mask; - MiWrite(etdev, regnum, reg); - break; - - default: - break; - } -} diff --git a/drivers/staging/et131x/et1310_phy.h b/drivers/staging/et131x/et1310_phy.h index 080656c6142c..758b9b251715 100644 --- a/drivers/staging/et131x/et1310_phy.h +++ b/drivers/staging/et131x/et1310_phy.h @@ -61,9 +61,6 @@ #include "et1310_address_map.h" -#define TRUEPHY_SUCCESS 0 -#define TRUEPHY_FAILURE 1 - /* MI Register Addresses */ #define MI_CONTROL_REG 0 #define MI_STATUS_REG 1 @@ -742,25 +739,15 @@ typedef union _MI_LCR2_t { /* Forward declaration of the private adapter structure */ struct et131x_adapter; -/* OS Specific Functions*/ -void TPAL_SetPhy10HalfDuplex(struct et131x_adapter *adapter); -void TPAL_SetPhy10FullDuplex(struct et131x_adapter *adapter); -void TPAL_SetPhy10Force(struct et131x_adapter *pAdapter); -void TPAL_SetPhy100HalfDuplex(struct et131x_adapter *adapter); -void TPAL_SetPhy100FullDuplex(struct et131x_adapter *adapter); -void TPAL_SetPhy100Force(struct et131x_adapter *pAdapter); -void TPAL_SetPhy1000FullDuplex(struct et131x_adapter *adapter); -void TPAL_SetPhyAutoNeg(struct et131x_adapter *adapter); - /* Prototypes for ET1310_phy.c */ int et131x_xcvr_find(struct et131x_adapter *adapter); -int et131x_setphy_normal(struct et131x_adapter *adapter); -int32_t PhyMiRead(struct et131x_adapter *adapter, - u8 xcvrAddr, u8 xcvrReg, u16 *value); +void et131x_setphy_normal(struct et131x_adapter *adapter); /* static inline function does not work because et131x_adapter is not always * defined */ +int PhyMiRead(struct et131x_adapter *adapter, u8 xcvrAddr, + u8 xcvrReg, u16 *value); #define MiRead(adapter, xcvrReg, value) \ PhyMiRead((adapter), (adapter)->Stats.xcvr_addr, (xcvrReg), (value)) @@ -860,24 +847,8 @@ void SetPhy_10BaseTHalfDuplex(struct et131x_adapter *adapter); void ET1310_PhyInit(struct et131x_adapter *adapter); void ET1310_PhyReset(struct et131x_adapter *adapter); void ET1310_PhyPowerDown(struct et131x_adapter *adapter, bool down); -void ET1310_PhyAutoNeg(struct et131x_adapter *adapter, bool enable); -void ET1310_PhyDuplexMode(struct et131x_adapter *adapter, u16 duplex); -void ET1310_PhySpeedSelect(struct et131x_adapter *adapter, u16 speed); void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *adapter, u16 duplex); -void ET1310_PhyAdvertise100BaseT(struct et131x_adapter *adapter, - u16 duplex); -void ET1310_PhyAdvertise10BaseT(struct et131x_adapter *adapter, - u16 duplex); -void ET1310_PhyLinkStatus(struct et131x_adapter *adapter, - u8 *Link_status, - u32 *autoneg, - u32 *linkspeed, - u32 *duplex_mode, - u32 *mdi_mdix, - u32 *masterslave, u32 *polarity); -void ET1310_PhyAndOrReg(struct et131x_adapter *adapter, - u16 regnum, u16 andMask, u16 orMask); void ET1310_PhyAccessMiBit(struct et131x_adapter *adapter, u16 action, u16 regnum, u16 bitnum, u8 *value); diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c index 10e21db57ac3..4c4555dffd1f 100644 --- a/drivers/staging/et131x/et1310_rx.c +++ b/drivers/staging/et131x/et1310_rx.c @@ -106,9 +106,9 @@ void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD pMpRfd); */ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) { - uint32_t OuterLoop, InnerLoop; - uint32_t bufsize; - uint32_t pktStatRingSize, FBRChunkSize; + u32 i, j; + u32 bufsize; + u32 pktStatRingSize, FBRChunkSize; RX_RING_t *rx_ring; /* Setup some convenience pointers */ @@ -227,11 +227,11 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) rx_ring->Fbr0offset); #endif - for (OuterLoop = 0; OuterLoop < (rx_ring->Fbr1NumEntries / FBR_CHUNKS); - OuterLoop++) { - uint64_t Fbr1Offset; - uint64_t Fbr1TempPa; - uint32_t Fbr1Align; + for (i = 0; i < (rx_ring->Fbr1NumEntries / FBR_CHUNKS); + i++) { + u64 Fbr1Offset; + u64 Fbr1TempPa; + u32 Fbr1Align; /* This code allocates an area of memory big enough for N * free buffers + (buffer_size - 1) so that the buffers can @@ -247,39 +247,39 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) FBRChunkSize = (FBR_CHUNKS * rx_ring->Fbr1BufferSize) + Fbr1Align - 1; - rx_ring->Fbr1MemVa[OuterLoop] = + rx_ring->Fbr1MemVa[i] = pci_alloc_consistent(adapter->pdev, FBRChunkSize, - &rx_ring->Fbr1MemPa[OuterLoop]); + &rx_ring->Fbr1MemPa[i]); - if (!rx_ring->Fbr1MemVa[OuterLoop]) { + if (!rx_ring->Fbr1MemVa[i]) { dev_err(&adapter->pdev->dev, "Could not alloc memory\n"); return -ENOMEM; } /* See NOTE in "Save Physical Address" comment above */ - Fbr1TempPa = rx_ring->Fbr1MemPa[OuterLoop]; + Fbr1TempPa = rx_ring->Fbr1MemPa[i]; et131x_align_allocated_memory(adapter, &Fbr1TempPa, &Fbr1Offset, (Fbr1Align - 1)); - for (InnerLoop = 0; InnerLoop < FBR_CHUNKS; InnerLoop++) { - uint32_t index = (OuterLoop * FBR_CHUNKS) + InnerLoop; + for (j = 0; j < FBR_CHUNKS; j++) { + u32 index = (i * FBR_CHUNKS) + j; /* Save the Virtual address of this index for quick * access later */ rx_ring->Fbr[1]->Va[index] = - (uint8_t *) rx_ring->Fbr1MemVa[OuterLoop] + - (InnerLoop * rx_ring->Fbr1BufferSize) + Fbr1Offset; + (uint8_t *) rx_ring->Fbr1MemVa[i] + + (j * rx_ring->Fbr1BufferSize) + Fbr1Offset; /* now store the physical address in the descriptor * so the device can access it */ rx_ring->Fbr[1]->PAHigh[index] = - (uint32_t) (Fbr1TempPa >> 32); - rx_ring->Fbr[1]->PALow[index] = (uint32_t) Fbr1TempPa; + (u32) (Fbr1TempPa >> 32); + rx_ring->Fbr[1]->PALow[index] = (u32) Fbr1TempPa; Fbr1TempPa += rx_ring->Fbr1BufferSize; @@ -292,40 +292,40 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) #ifdef USE_FBR0 /* Same for FBR0 (if in use) */ - for (OuterLoop = 0; OuterLoop < (rx_ring->Fbr0NumEntries / FBR_CHUNKS); - OuterLoop++) { - uint64_t Fbr0Offset; - uint64_t Fbr0TempPa; + for (i = 0; i < (rx_ring->Fbr0NumEntries / FBR_CHUNKS); + i++) { + u64 Fbr0Offset; + u64 Fbr0TempPa; FBRChunkSize = ((FBR_CHUNKS + 1) * rx_ring->Fbr0BufferSize) - 1; - rx_ring->Fbr0MemVa[OuterLoop] = + rx_ring->Fbr0MemVa[i] = pci_alloc_consistent(adapter->pdev, FBRChunkSize, - &rx_ring->Fbr0MemPa[OuterLoop]); + &rx_ring->Fbr0MemPa[i]); - if (!rx_ring->Fbr0MemVa[OuterLoop]) { + if (!rx_ring->Fbr0MemVa[i]) { dev_err(&adapter->pdev->dev, "Could not alloc memory\n"); return -ENOMEM; } /* See NOTE in "Save Physical Address" comment above */ - Fbr0TempPa = rx_ring->Fbr0MemPa[OuterLoop]; + Fbr0TempPa = rx_ring->Fbr0MemPa[i]; et131x_align_allocated_memory(adapter, &Fbr0TempPa, &Fbr0Offset, rx_ring->Fbr0BufferSize - 1); - for (InnerLoop = 0; InnerLoop < FBR_CHUNKS; InnerLoop++) { - uint32_t index = (OuterLoop * FBR_CHUNKS) + InnerLoop; + for (j = 0; j < FBR_CHUNKS; j++) { + u32 index = (i * FBR_CHUNKS) + j; rx_ring->Fbr[0]->Va[index] = - (uint8_t *) rx_ring->Fbr0MemVa[OuterLoop] + - (InnerLoop * rx_ring->Fbr0BufferSize) + Fbr0Offset; + (uint8_t *) rx_ring->Fbr0MemVa[i] + + (j * rx_ring->Fbr0BufferSize) + Fbr0Offset; rx_ring->Fbr[0]->PAHigh[index] = - (uint32_t) (Fbr0TempPa >> 32); - rx_ring->Fbr[0]->PALow[index] = (uint32_t) Fbr0TempPa; + (u32) (Fbr0TempPa >> 32); + rx_ring->Fbr[0]->PALow[index] = (u32) Fbr0TempPa; Fbr0TempPa += rx_ring->Fbr0BufferSize; @@ -342,7 +342,7 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) sizeof(PKT_STAT_DESC_t) * adapter->RxRing.PsrNumEntries; rx_ring->pPSRingVa = pci_alloc_consistent(adapter->pdev, - pktStatRingSize + 0x0fff, + pktStatRingSize, &rx_ring->pPSRingPa); if (!rx_ring->pPSRingVa) { @@ -350,45 +350,26 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) "Cannot alloc memory for Packet Status Ring\n"); return -ENOMEM; } + printk("PSR %lx\n", (unsigned long) rx_ring->pPSRingPa); - /* Save physical address - * + /* * NOTE : pci_alloc_consistent(), used above to alloc DMA regions, * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses * are ever returned, make sure the high part is retrieved here before * storing the adjusted address. */ - rx_ring->pPSRingRealPa = rx_ring->pPSRingPa; - - /* Align Packet Status Ring on a 4K boundary */ - et131x_align_allocated_memory(adapter, - &rx_ring->pPSRingRealPa, - &rx_ring->pPSRingOffset, 0x0FFF); - - rx_ring->pPSRingVa = (void *)((uint8_t *) rx_ring->pPSRingVa + - rx_ring->pPSRingOffset); /* Allocate an area of memory for writeback of status information */ rx_ring->pRxStatusVa = pci_alloc_consistent(adapter->pdev, - sizeof(RX_STATUS_BLOCK_t) + - 0x7, &rx_ring->pRxStatusPa); + sizeof(RX_STATUS_BLOCK_t), + &rx_ring->pRxStatusPa); if (!rx_ring->pRxStatusVa) { dev_err(&adapter->pdev->dev, "Cannot alloc memory for Status Block\n"); return -ENOMEM; } - - /* Save physical address */ - rx_ring->RxStatusRealPA = rx_ring->pRxStatusPa; - - /* Align write back on an 8 byte boundary */ - et131x_align_allocated_memory(adapter, - &rx_ring->RxStatusRealPA, - &rx_ring->RxStatusOffset, 0x07); - - rx_ring->pRxStatusVa = (void *)((uint8_t *) rx_ring->pRxStatusVa + - rx_ring->RxStatusOffset); rx_ring->NumRfd = NIC_DEFAULT_NUM_RFD; + printk("PRS %lx\n", (unsigned long)rx_ring->pRxStatusPa); /* Recv * pci_pool_create initializes a lookaside list. After successful @@ -409,7 +390,6 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) * lists now. */ INIT_LIST_HEAD(&rx_ring->RecvList); - INIT_LIST_HEAD(&rx_ring->RecvPendingList); return 0; } @@ -419,10 +399,10 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) */ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) { - uint32_t index; - uint32_t bufsize; - uint32_t pktStatRingSize; - PMP_RFD pMpRfd; + u32 index; + u32 bufsize; + u32 pktStatRingSize; + PMP_RFD rfd; RX_RING_t *rx_ring; /* Setup some convenience pointers */ @@ -432,18 +412,12 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) WARN_ON(rx_ring->nReadyRecv != rx_ring->NumRfd); while (!list_empty(&rx_ring->RecvList)) { - pMpRfd = (MP_RFD *) list_entry(rx_ring->RecvList.next, + rfd = (MP_RFD *) list_entry(rx_ring->RecvList.next, MP_RFD, list_node); - list_del(&pMpRfd->list_node); - et131x_rfd_resources_free(adapter, pMpRfd); - } - - while (!list_empty(&rx_ring->RecvPendingList)) { - pMpRfd = (MP_RFD *) list_entry(rx_ring->RecvPendingList.next, - MP_RFD, list_node); - list_del(&pMpRfd->list_node); - et131x_rfd_resources_free(adapter, pMpRfd); + list_del(&rfd->list_node); + rfd->Packet = NULL; + kmem_cache_free(adapter->RxRing.RecvLookaside, rfd); } /* Free Free Buffer Ring 1 */ @@ -452,7 +426,7 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) for (index = 0; index < (rx_ring->Fbr1NumEntries / FBR_CHUNKS); index++) { if (rx_ring->Fbr1MemVa[index]) { - uint32_t Fbr1Align; + u32 Fbr1Align; if (rx_ring->Fbr1BufferSize > 4096) Fbr1Align = 4096; @@ -523,14 +497,10 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) /* Free Packet Status Ring */ if (rx_ring->pPSRingVa) { - rx_ring->pPSRingVa = (void *)((uint8_t *) rx_ring->pPSRingVa - - rx_ring->pPSRingOffset); - pktStatRingSize = sizeof(PKT_STAT_DESC_t) * adapter->RxRing.PsrNumEntries; - pci_free_consistent(adapter->pdev, - pktStatRingSize + 0x0fff, + pci_free_consistent(adapter->pdev, pktStatRingSize, rx_ring->pPSRingVa, rx_ring->pPSRingPa); rx_ring->pPSRingVa = NULL; @@ -538,11 +508,8 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) /* Free area of memory for the writeback of status information */ if (rx_ring->pRxStatusVa) { - rx_ring->pRxStatusVa = (void *)((uint8_t *) - rx_ring->pRxStatusVa - rx_ring->RxStatusOffset); - pci_free_consistent(adapter->pdev, - sizeof(RX_STATUS_BLOCK_t) + 0x7, + sizeof(RX_STATUS_BLOCK_t), rx_ring->pRxStatusVa, rx_ring->pRxStatusPa); rx_ring->pRxStatusVa = NULL; @@ -578,49 +545,43 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) int et131x_init_recv(struct et131x_adapter *adapter) { int status = -ENOMEM; - PMP_RFD pMpRfd = NULL; - uint32_t RfdCount; - uint32_t TotalNumRfd = 0; + PMP_RFD rfd = NULL; + u32 rfdct; + u32 numrfd = 0; RX_RING_t *rx_ring = NULL; /* Setup some convenience pointers */ rx_ring = (RX_RING_t *) &adapter->RxRing; /* Setup each RFD */ - for (RfdCount = 0; RfdCount < rx_ring->NumRfd; RfdCount++) { - pMpRfd = (MP_RFD *) kmem_cache_alloc(rx_ring->RecvLookaside, + for (rfdct = 0; rfdct < rx_ring->NumRfd; rfdct++) { + rfd = (MP_RFD *) kmem_cache_alloc(rx_ring->RecvLookaside, GFP_ATOMIC | GFP_DMA); - if (!pMpRfd) { + if (!rfd) { dev_err(&adapter->pdev->dev, "Couldn't alloc RFD out of kmem_cache\n"); status = -ENOMEM; continue; } - status = et131x_rfd_resources_alloc(adapter, pMpRfd); - if (status != 0) { - dev_err(&adapter->pdev->dev, - "Couldn't alloc packet for RFD\n"); - kmem_cache_free(rx_ring->RecvLookaside, pMpRfd); - continue; - } + rfd->Packet = NULL; /* Add this RFD to the RecvList */ - list_add_tail(&pMpRfd->list_node, &rx_ring->RecvList); + list_add_tail(&rfd->list_node, &rx_ring->RecvList); /* Increment both the available RFD's, and the total RFD's. */ rx_ring->nReadyRecv++; - TotalNumRfd++; + numrfd++; } - if (TotalNumRfd > NIC_MIN_NUM_RFD) + if (numrfd > NIC_MIN_NUM_RFD) status = 0; - rx_ring->NumRfd = TotalNumRfd; + rx_ring->NumRfd = numrfd; if (status != 0) { - kmem_cache_free(rx_ring->RecvLookaside, pMpRfd); + kmem_cache_free(rx_ring->RecvLookaside, rfd); dev_err(&adapter->pdev->dev, "Allocation problems in et131x_init_recv\n"); } @@ -628,40 +589,15 @@ int et131x_init_recv(struct et131x_adapter *adapter) } /** - * et131x_rfd_resources_alloc - * @adapter: pointer to our private adapter structure - * @pMpRfd: pointer to a RFD - * - * Returns 0 on success and errno on failure (as defined in errno.h) - */ -int et131x_rfd_resources_alloc(struct et131x_adapter *adapter, MP_RFD *pMpRfd) -{ - pMpRfd->Packet = NULL; - - return 0; -} - -/** - * et131x_rfd_resources_free - Free the packet allocated for the given RFD - * @adapter: pointer to our private adapter structure - * @pMpRfd: pointer to a RFD - */ -void et131x_rfd_resources_free(struct et131x_adapter *adapter, MP_RFD *pMpRfd) -{ - pMpRfd->Packet = NULL; - kmem_cache_free(adapter->RxRing.RecvLookaside, pMpRfd); -} - -/** * ConfigRxDmaRegs - Start of Rx_DMA init sequence * @etdev: pointer to our adapter structure */ void ConfigRxDmaRegs(struct et131x_adapter *etdev) { struct _RXDMA_t __iomem *rx_dma = &etdev->regs->rxdma; - struct _rx_ring_t *pRxLocal = &etdev->RxRing; + struct _rx_ring_t *rx_local = &etdev->RxRing; PFBR_DESC_t fbr_entry; - uint32_t entry; + u32 entry; RXDMA_PSR_NUM_DES_t psr_num_des; unsigned long flags; @@ -675,19 +611,19 @@ void ConfigRxDmaRegs(struct et131x_adapter *etdev) * are ever returned, make sure the high part is retrieved here * before storing the adjusted address. */ - writel((uint32_t) (pRxLocal->RxStatusRealPA >> 32), + writel((u32) ((u64)rx_local->pRxStatusPa >> 32), &rx_dma->dma_wb_base_hi); - writel((uint32_t) pRxLocal->RxStatusRealPA, &rx_dma->dma_wb_base_lo); + writel((u32) rx_local->pRxStatusPa, &rx_dma->dma_wb_base_lo); - memset(pRxLocal->pRxStatusVa, 0, sizeof(RX_STATUS_BLOCK_t)); + memset(rx_local->pRxStatusVa, 0, sizeof(RX_STATUS_BLOCK_t)); /* Set the address and parameters of the packet status ring into the * 1310's registers */ - writel((uint32_t) (pRxLocal->pPSRingRealPa >> 32), + writel((u32) ((u64)rx_local->pPSRingPa >> 32), &rx_dma->psr_base_hi); - writel((uint32_t) pRxLocal->pPSRingRealPa, &rx_dma->psr_base_lo); - writel(pRxLocal->PsrNumEntries - 1, &rx_dma->psr_num_des.value); + writel((u32) rx_local->pPSRingPa, &rx_dma->psr_base_lo); + writel(rx_local->PsrNumEntries - 1, &rx_dma->psr_num_des.value); writel(0, &rx_dma->psr_full_offset.value); psr_num_des.value = readl(&rx_dma->psr_num_des.value); @@ -697,14 +633,14 @@ void ConfigRxDmaRegs(struct et131x_adapter *etdev) spin_lock_irqsave(&etdev->RcvLock, flags); /* These local variables track the PSR in the adapter structure */ - pRxLocal->local_psr_full.bits.psr_full = 0; - pRxLocal->local_psr_full.bits.psr_full_wrap = 0; + rx_local->local_psr_full.bits.psr_full = 0; + rx_local->local_psr_full.bits.psr_full_wrap = 0; /* Now's the best time to initialize FBR1 contents */ - fbr_entry = (PFBR_DESC_t) pRxLocal->pFbr1RingVa; - for (entry = 0; entry < pRxLocal->Fbr1NumEntries; entry++) { - fbr_entry->addr_hi = pRxLocal->Fbr[1]->PAHigh[entry]; - fbr_entry->addr_lo = pRxLocal->Fbr[1]->PALow[entry]; + fbr_entry = (PFBR_DESC_t) rx_local->pFbr1RingVa; + for (entry = 0; entry < rx_local->Fbr1NumEntries; entry++) { + fbr_entry->addr_hi = rx_local->Fbr[1]->PAHigh[entry]; + fbr_entry->addr_lo = rx_local->Fbr[1]->PALow[entry]; fbr_entry->word2.bits.bi = entry; fbr_entry++; } @@ -712,38 +648,38 @@ void ConfigRxDmaRegs(struct et131x_adapter *etdev) /* Set the address and parameters of Free buffer ring 1 (and 0 if * required) into the 1310's registers */ - writel((uint32_t) (pRxLocal->Fbr1Realpa >> 32), &rx_dma->fbr1_base_hi); - writel((uint32_t) pRxLocal->Fbr1Realpa, &rx_dma->fbr1_base_lo); - writel(pRxLocal->Fbr1NumEntries - 1, &rx_dma->fbr1_num_des.value); + writel((u32) (rx_local->Fbr1Realpa >> 32), &rx_dma->fbr1_base_hi); + writel((u32) rx_local->Fbr1Realpa, &rx_dma->fbr1_base_lo); + writel(rx_local->Fbr1NumEntries - 1, &rx_dma->fbr1_num_des.value); writel(ET_DMA10_WRAP, &rx_dma->fbr1_full_offset); /* This variable tracks the free buffer ring 1 full position, so it * has to match the above. */ - pRxLocal->local_Fbr1_full = ET_DMA10_WRAP; - writel(((pRxLocal->Fbr1NumEntries * LO_MARK_PERCENT_FOR_RX) / 100) - 1, + rx_local->local_Fbr1_full = ET_DMA10_WRAP; + writel(((rx_local->Fbr1NumEntries * LO_MARK_PERCENT_FOR_RX) / 100) - 1, &rx_dma->fbr1_min_des.value); #ifdef USE_FBR0 /* Now's the best time to initialize FBR0 contents */ - fbr_entry = (PFBR_DESC_t) pRxLocal->pFbr0RingVa; - for (entry = 0; entry < pRxLocal->Fbr0NumEntries; entry++) { - fbr_entry->addr_hi = pRxLocal->Fbr[0]->PAHigh[entry]; - fbr_entry->addr_lo = pRxLocal->Fbr[0]->PALow[entry]; + fbr_entry = (PFBR_DESC_t) rx_local->pFbr0RingVa; + for (entry = 0; entry < rx_local->Fbr0NumEntries; entry++) { + fbr_entry->addr_hi = rx_local->Fbr[0]->PAHigh[entry]; + fbr_entry->addr_lo = rx_local->Fbr[0]->PALow[entry]; fbr_entry->word2.bits.bi = entry; fbr_entry++; } - writel((uint32_t) (pRxLocal->Fbr0Realpa >> 32), &rx_dma->fbr0_base_hi); - writel((uint32_t) pRxLocal->Fbr0Realpa, &rx_dma->fbr0_base_lo); - writel(pRxLocal->Fbr0NumEntries - 1, &rx_dma->fbr0_num_des.value); + writel((u32) (rx_local->Fbr0Realpa >> 32), &rx_dma->fbr0_base_hi); + writel((u32) rx_local->Fbr0Realpa, &rx_dma->fbr0_base_lo); + writel(rx_local->Fbr0NumEntries - 1, &rx_dma->fbr0_num_des.value); writel(ET_DMA10_WRAP, &rx_dma->fbr0_full_offset); /* This variable tracks the free buffer ring 0 full position, so it * has to match the above. */ - pRxLocal->local_Fbr0_full = ET_DMA10_WRAP; - writel(((pRxLocal->Fbr0NumEntries * LO_MARK_PERCENT_FOR_RX) / 100) - 1, + rx_local->local_Fbr0_full = ET_DMA10_WRAP; + writel(((rx_local->Fbr0NumEntries * LO_MARK_PERCENT_FOR_RX) / 100) - 1, &rx_dma->fbr0_min_des.value); #endif @@ -807,40 +743,35 @@ void et131x_rx_dma_disable(struct et131x_adapter *etdev) */ void et131x_rx_dma_enable(struct et131x_adapter *etdev) { - if (etdev->RegistryPhyLoopbk) - /* RxDMA is disabled for loopback operation. */ - writel(0x1, &etdev->regs->rxdma.csr.value); - else { /* Setup the receive dma configuration register for normal operation */ - RXDMA_CSR_t csr = { 0 }; - - csr.bits.fbr1_enable = 1; - if (etdev->RxRing.Fbr1BufferSize == 4096) - csr.bits.fbr1_size = 1; - else if (etdev->RxRing.Fbr1BufferSize == 8192) - csr.bits.fbr1_size = 2; - else if (etdev->RxRing.Fbr1BufferSize == 16384) - csr.bits.fbr1_size = 3; + RXDMA_CSR_t csr = { 0 }; + + csr.bits.fbr1_enable = 1; + if (etdev->RxRing.Fbr1BufferSize == 4096) + csr.bits.fbr1_size = 1; + else if (etdev->RxRing.Fbr1BufferSize == 8192) + csr.bits.fbr1_size = 2; + else if (etdev->RxRing.Fbr1BufferSize == 16384) + csr.bits.fbr1_size = 3; #ifdef USE_FBR0 - csr.bits.fbr0_enable = 1; - if (etdev->RxRing.Fbr0BufferSize == 256) - csr.bits.fbr0_size = 1; - else if (etdev->RxRing.Fbr0BufferSize == 512) - csr.bits.fbr0_size = 2; - else if (etdev->RxRing.Fbr0BufferSize == 1024) - csr.bits.fbr0_size = 3; + csr.bits.fbr0_enable = 1; + if (etdev->RxRing.Fbr0BufferSize == 256) + csr.bits.fbr0_size = 1; + else if (etdev->RxRing.Fbr0BufferSize == 512) + csr.bits.fbr0_size = 2; + else if (etdev->RxRing.Fbr0BufferSize == 1024) + csr.bits.fbr0_size = 3; #endif - writel(csr.value, &etdev->regs->rxdma.csr.value); + writel(csr.value, &etdev->regs->rxdma.csr.value); + csr.value = readl(&etdev->regs->rxdma.csr.value); + if (csr.bits.halt_status != 0) { + udelay(5); csr.value = readl(&etdev->regs->rxdma.csr.value); if (csr.bits.halt_status != 0) { - udelay(5); - csr.value = readl(&etdev->regs->rxdma.csr.value); - if (csr.bits.halt_status != 0) { - dev_err(&etdev->pdev->dev, - "RX Dma failed to exit halt state. CSR 0x%08x\n", - csr.value); - } + dev_err(&etdev->pdev->dev, + "RX Dma failed to exit halt state. CSR 0x%08x\n", + csr.value); } } } @@ -849,7 +780,7 @@ void et131x_rx_dma_enable(struct et131x_adapter *etdev) * nic_rx_pkts - Checks the hardware for available packets * @etdev: pointer to our adapter * - * Returns pMpRfd, a pointer to our MPRFD. + * Returns rfd, a pointer to our MPRFD. * * Checks the hardware for available packets, using completion ring * If packets are available, it gets an RFD from the RecvList, attaches @@ -858,119 +789,119 @@ void et131x_rx_dma_enable(struct et131x_adapter *etdev) */ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) { - struct _rx_ring_t *pRxLocal = &etdev->RxRing; - PRX_STATUS_BLOCK_t pRxStatusBlock; - PPKT_STAT_DESC_t pPSREntry; - PMP_RFD pMpRfd; - uint32_t nIndex; - uint8_t *pBufVa; + struct _rx_ring_t *rx_local = &etdev->RxRing; + PRX_STATUS_BLOCK_t status; + PPKT_STAT_DESC_t psr; + PMP_RFD rfd; + u32 i; + uint8_t *buf; unsigned long flags; struct list_head *element; - uint8_t ringIndex; - uint16_t bufferIndex; - uint32_t localLen; + uint8_t rindex; + uint16_t bindex; + u32 len; PKT_STAT_DESC_WORD0_t Word0; /* RX Status block is written by the DMA engine prior to every * interrupt. It contains the next to be used entry in the Packet * Status Ring, and also the two Free Buffer rings. */ - pRxStatusBlock = (PRX_STATUS_BLOCK_t) pRxLocal->pRxStatusVa; + status = (PRX_STATUS_BLOCK_t) rx_local->pRxStatusVa; - if (pRxStatusBlock->Word1.bits.PSRoffset == - pRxLocal->local_psr_full.bits.psr_full && - pRxStatusBlock->Word1.bits.PSRwrap == - pRxLocal->local_psr_full.bits.psr_full_wrap) { + if (status->Word1.bits.PSRoffset == + rx_local->local_psr_full.bits.psr_full && + status->Word1.bits.PSRwrap == + rx_local->local_psr_full.bits.psr_full_wrap) { /* Looks like this ring is not updated yet */ return NULL; } /* The packet status ring indicates that data is available. */ - pPSREntry = (PPKT_STAT_DESC_t) (pRxLocal->pPSRingVa) + - pRxLocal->local_psr_full.bits.psr_full; + psr = (PPKT_STAT_DESC_t) (rx_local->pPSRingVa) + + rx_local->local_psr_full.bits.psr_full; /* Grab any information that is required once the PSR is * advanced, since we can no longer rely on the memory being * accurate */ - localLen = pPSREntry->word1.bits.length; - ringIndex = (uint8_t) pPSREntry->word1.bits.ri; - bufferIndex = (uint16_t) pPSREntry->word1.bits.bi; - Word0 = pPSREntry->word0; + len = psr->word1.bits.length; + rindex = (uint8_t) psr->word1.bits.ri; + bindex = (uint16_t) psr->word1.bits.bi; + Word0 = psr->word0; /* Indicate that we have used this PSR entry. */ - if (++pRxLocal->local_psr_full.bits.psr_full > - pRxLocal->PsrNumEntries - 1) { - pRxLocal->local_psr_full.bits.psr_full = 0; - pRxLocal->local_psr_full.bits.psr_full_wrap ^= 1; + if (++rx_local->local_psr_full.bits.psr_full > + rx_local->PsrNumEntries - 1) { + rx_local->local_psr_full.bits.psr_full = 0; + rx_local->local_psr_full.bits.psr_full_wrap ^= 1; } - writel(pRxLocal->local_psr_full.value, + writel(rx_local->local_psr_full.value, &etdev->regs->rxdma.psr_full_offset.value); #ifndef USE_FBR0 - if (ringIndex != 1) { + if (rindex != 1) { return NULL; } #endif #ifdef USE_FBR0 - if (ringIndex > 1 || - (ringIndex == 0 && - bufferIndex > pRxLocal->Fbr0NumEntries - 1) || - (ringIndex == 1 && - bufferIndex > pRxLocal->Fbr1NumEntries - 1)) + if (rindex > 1 || + (rindex == 0 && + bindex > rx_local->Fbr0NumEntries - 1) || + (rindex == 1 && + bindex > rx_local->Fbr1NumEntries - 1)) #else - if (ringIndex != 1 || - bufferIndex > pRxLocal->Fbr1NumEntries - 1) + if (rindex != 1 || + bindex > rx_local->Fbr1NumEntries - 1) #endif { /* Illegal buffer or ring index cannot be used by S/W*/ dev_err(&etdev->pdev->dev, "NICRxPkts PSR Entry %d indicates " "length of %d and/or bad bi(%d)\n", - pRxLocal->local_psr_full.bits.psr_full, - localLen, bufferIndex); + rx_local->local_psr_full.bits.psr_full, + len, bindex); return NULL; } /* Get and fill the RFD. */ spin_lock_irqsave(&etdev->RcvLock, flags); - pMpRfd = NULL; - element = pRxLocal->RecvList.next; - pMpRfd = (PMP_RFD) list_entry(element, MP_RFD, list_node); + rfd = NULL; + element = rx_local->RecvList.next; + rfd = (PMP_RFD) list_entry(element, MP_RFD, list_node); - if (pMpRfd == NULL) { + if (rfd == NULL) { spin_unlock_irqrestore(&etdev->RcvLock, flags); return NULL; } - list_del(&pMpRfd->list_node); - pRxLocal->nReadyRecv--; + list_del(&rfd->list_node); + rx_local->nReadyRecv--; spin_unlock_irqrestore(&etdev->RcvLock, flags); - pMpRfd->bufferindex = bufferIndex; - pMpRfd->ringindex = ringIndex; + rfd->bufferindex = bindex; + rfd->ringindex = rindex; /* In V1 silicon, there is a bug which screws up filtering of * runt packets. Therefore runt packet filtering is disabled * in the MAC and the packets are dropped here. They are * also counted here. */ - if (localLen < (NIC_MIN_PACKET_SIZE + 4)) { + if (len < (NIC_MIN_PACKET_SIZE + 4)) { etdev->Stats.other_errors++; - localLen = 0; + len = 0; } - if (localLen) { + if (len) { if (etdev->ReplicaPhyLoopbk == 1) { - pBufVa = pRxLocal->Fbr[ringIndex]->Va[bufferIndex]; + buf = rx_local->Fbr[rindex]->Va[bindex]; - if (memcmp(&pBufVa[6], &etdev->CurrentAddress[0], + if (memcmp(&buf[6], &etdev->CurrentAddress[0], ETH_ALEN) == 0) { - if (memcmp(&pBufVa[42], "Replica packet", + if (memcmp(&buf[42], "Replica packet", ETH_HLEN)) { etdev->ReplicaPhyLoopbkPF = 1; } @@ -990,28 +921,28 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) if ((etdev->PacketFilter & ET131X_PACKET_TYPE_MULTICAST) && !(etdev->PacketFilter & ET131X_PACKET_TYPE_PROMISCUOUS) && !(etdev->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST)) { - pBufVa = pRxLocal->Fbr[ringIndex]-> - Va[bufferIndex]; + buf = rx_local->Fbr[rindex]-> + Va[bindex]; /* Loop through our list to see if the * destination address of this packet * matches one in our list. */ - for (nIndex = 0; - nIndex < etdev->MCAddressCount; - nIndex++) { - if (pBufVa[0] == - etdev->MCList[nIndex][0] - && pBufVa[1] == - etdev->MCList[nIndex][1] - && pBufVa[2] == - etdev->MCList[nIndex][2] - && pBufVa[3] == - etdev->MCList[nIndex][3] - && pBufVa[4] == - etdev->MCList[nIndex][4] - && pBufVa[5] == - etdev->MCList[nIndex][5]) { + for (i = 0; + i < etdev->MCAddressCount; + i++) { + if (buf[0] == + etdev->MCList[i][0] + && buf[1] == + etdev->MCList[i][1] + && buf[2] == + etdev->MCList[i][2] + && buf[3] == + etdev->MCList[i][3] + && buf[4] == + etdev->MCList[i][4] + && buf[5] == + etdev->MCList[i][5]) { break; } } @@ -1024,11 +955,11 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) * so we free our RFD when we return * from this function. */ - if (nIndex == etdev->MCAddressCount) - localLen = 0; + if (i == etdev->MCAddressCount) + len = 0; } - if (localLen > 0) + if (len > 0) etdev->Stats.multircv++; } else if (Word0.value & ALCATEL_BROADCAST_PKT) etdev->Stats.brdcstrcv++; @@ -1041,24 +972,24 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) etdev->Stats.unircv++; } - if (localLen > 0) { + if (len > 0) { struct sk_buff *skb = NULL; - /* pMpRfd->PacketSize = localLen - 4; */ - pMpRfd->PacketSize = localLen; + /* rfd->PacketSize = len - 4; */ + rfd->PacketSize = len; - skb = dev_alloc_skb(pMpRfd->PacketSize + 2); + skb = dev_alloc_skb(rfd->PacketSize + 2); if (!skb) { dev_err(&etdev->pdev->dev, "Couldn't alloc an SKB for Rx\n"); return NULL; } - etdev->net_stats.rx_bytes += pMpRfd->PacketSize; + etdev->net_stats.rx_bytes += rfd->PacketSize; - memcpy(skb_put(skb, pMpRfd->PacketSize), - pRxLocal->Fbr[ringIndex]->Va[bufferIndex], - pMpRfd->PacketSize); + memcpy(skb_put(skb, rfd->PacketSize), + rx_local->Fbr[rindex]->Va[bindex], + rfd->PacketSize); skb->dev = etdev->netdev; skb->protocol = eth_type_trans(skb, etdev->netdev); @@ -1066,11 +997,11 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) netif_rx(skb); } else { - pMpRfd->PacketSize = 0; + rfd->PacketSize = 0; } - nic_return_rfd(etdev, pMpRfd); - return pMpRfd; + nic_return_rfd(etdev, rfd); + return rfd; } /** @@ -1081,21 +1012,8 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) */ void et131x_reset_recv(struct et131x_adapter *etdev) { - PMP_RFD pMpRfd; - struct list_head *element; - WARN_ON(list_empty(&etdev->RxRing.RecvList)); - /* Take all the RFD's from the pending list, and stick them on the - * RecvList. - */ - while (!list_empty(&etdev->RxRing.RecvPendingList)) { - element = etdev->RxRing.RecvPendingList.next; - - pMpRfd = (PMP_RFD) list_entry(element, MP_RFD, list_node); - - list_move_tail(&pMpRfd->list_node, &etdev->RxRing.RecvList); - } } /** @@ -1106,27 +1024,21 @@ void et131x_reset_recv(struct et131x_adapter *etdev) */ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev) { - PMP_RFD pMpRfd = NULL; - struct sk_buff *PacketArray[NUM_PACKETS_HANDLED]; - PMP_RFD RFDFreeArray[NUM_PACKETS_HANDLED]; - uint32_t PacketArrayCount = 0; - uint32_t PacketsToHandle; - uint32_t PacketFreeCount = 0; - bool TempUnfinishedRec = false; - - PacketsToHandle = NUM_PACKETS_HANDLED; + PMP_RFD rfd = NULL; + u32 count = 0; + bool done = true; /* Process up to available RFD's */ - while (PacketArrayCount < PacketsToHandle) { + while (count < NUM_PACKETS_HANDLED) { if (list_empty(&etdev->RxRing.RecvList)) { WARN_ON(etdev->RxRing.nReadyRecv != 0); - TempUnfinishedRec = true; + done = false; break; } - pMpRfd = nic_rx_pkts(etdev); + rfd = nic_rx_pkts(etdev); - if (pMpRfd == NULL) + if (rfd == NULL) break; /* Do not receive any packets until a filter has been set. @@ -1136,7 +1048,7 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev) */ if (!etdev->PacketFilter || !(etdev->Flags & fMP_ADAPTER_LINK_DETECTION) || - pMpRfd->PacketSize == 0) { + rfd->PacketSize == 0) { continue; } @@ -1144,35 +1056,20 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev) etdev->Stats.ipackets++; /* Set the status on the packet, either resources or success */ - if (etdev->RxRing.nReadyRecv >= RFD_LOW_WATER_MARK) { - /* Put this RFD on the pending list - * - * NOTE: nic_rx_pkts() above is already returning the - * RFD to the RecvList, so don't additionally do that - * here. - * Besides, we don't really need (at this point) the - * pending list anyway. - */ - } else { - RFDFreeArray[PacketFreeCount] = pMpRfd; - PacketFreeCount++; - + if (etdev->RxRing.nReadyRecv < RFD_LOW_WATER_MARK) { dev_warn(&etdev->pdev->dev, "RFD's are running out\n"); } - - PacketArray[PacketArrayCount] = pMpRfd->Packet; - PacketArrayCount++; + count++; } - if ((PacketArrayCount == NUM_PACKETS_HANDLED) || TempUnfinishedRec) { + if (count == NUM_PACKETS_HANDLED || !done) { etdev->RxRing.UnfinishedReceives = true; writel(PARM_TX_TIME_INT_DEF * NANO_IN_A_MICRO, &etdev->regs->global.watchdog_timer); - } else { + } else /* Watchdog timer will disable itself if appropriate. */ etdev->RxRing.UnfinishedReceives = false; - } } static inline u32 bump_fbr(u32 *fbr, u32 limit) @@ -1196,14 +1093,14 @@ static inline u32 bump_fbr(u32 *fbr, u32 limit) /** * NICReturnRFD - Recycle a RFD and put it back onto the receive list * @etdev: pointer to our adapter - * @pMpRfd: pointer to the RFD + * @rfd: pointer to the RFD */ -void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD pMpRfd) +void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD rfd) { struct _rx_ring_t *rx_local = &etdev->RxRing; struct _RXDMA_t __iomem *rx_dma = &etdev->regs->rxdma; - uint16_t bi = pMpRfd->bufferindex; - uint8_t ri = pMpRfd->ringindex; + uint16_t bi = rfd->bufferindex; + uint8_t ri = rfd->ringindex; unsigned long flags; /* We don't use any of the OOB data besides status. Otherwise, we @@ -1217,7 +1114,7 @@ void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD pMpRfd) spin_lock_irqsave(&etdev->FbrLock, flags); if (ri == 1) { - PFBR_DESC_t pNextDesc = + PFBR_DESC_t next = (PFBR_DESC_t) (rx_local->pFbr1RingVa) + INDEX10(rx_local->local_Fbr1_full); @@ -1225,9 +1122,9 @@ void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD pMpRfd) * the PA / Buffer Index for the returned buffer into * the oldest (next to be freed)FBR entry */ - pNextDesc->addr_hi = rx_local->Fbr[1]->PAHigh[bi]; - pNextDesc->addr_lo = rx_local->Fbr[1]->PALow[bi]; - pNextDesc->word2.value = bi; + next->addr_hi = rx_local->Fbr[1]->PAHigh[bi]; + next->addr_lo = rx_local->Fbr[1]->PALow[bi]; + next->word2.value = bi; writel(bump_fbr(&rx_local->local_Fbr1_full, rx_local->Fbr1NumEntries - 1), @@ -1235,7 +1132,7 @@ void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD pMpRfd) } #ifdef USE_FBR0 else { - PFBR_DESC_t pNextDesc = + PFBR_DESC_t next = (PFBR_DESC_t) rx_local->pFbr0RingVa + INDEX10(rx_local->local_Fbr0_full); @@ -1243,9 +1140,9 @@ void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD pMpRfd) * the PA / Buffer Index for the returned buffer into * the oldest (next to be freed) FBR entry */ - pNextDesc->addr_hi = rx_local->Fbr[0]->PAHigh[bi]; - pNextDesc->addr_lo = rx_local->Fbr[0]->PALow[bi]; - pNextDesc->word2.value = bi; + next->addr_hi = rx_local->Fbr[0]->PAHigh[bi]; + next->addr_lo = rx_local->Fbr[0]->PALow[bi]; + next->word2.value = bi; writel(bump_fbr(&rx_local->local_Fbr0_full, rx_local->Fbr0NumEntries - 1), @@ -1262,7 +1159,7 @@ void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD pMpRfd) * our list */ spin_lock_irqsave(&etdev->RcvLock, flags); - list_add_tail(&pMpRfd->list_node, &rx_local->RecvList); + list_add_tail(&rfd->list_node, &rx_local->RecvList); rx_local->nReadyRecv++; spin_unlock_irqrestore(&etdev->RcvLock, flags); diff --git a/drivers/staging/et131x/et1310_rx.h b/drivers/staging/et131x/et1310_rx.h index 72a522985270..a11bd8b0872e 100644 --- a/drivers/staging/et131x/et1310_rx.h +++ b/drivers/staging/et131x/et1310_rx.h @@ -209,36 +209,26 @@ typedef struct _PKT_STAT_DESC_t { /* Typedefs for the RX DMA status word */ /* - * RXSTAT_WORD0_t structure holds part of the status bits of the Rx DMA engine + * rx status word 0 holds part of the status bits of the Rx DMA engine * that get copied out to memory by the ET-1310. Word 0 is a 32 bit word - * whichcontains Free Buffer ring 0 and 1 available offset. + * which contains the Free Buffer ring 0 and 1 available offset. + * + * bit 0-9 FBR1 offset + * bit 10 Wrap flag for FBR1 + * bit 16-25 FBR0 offset + * bit 26 Wrap flag for FBR0 */ -typedef union _rxstat_word0_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 FBR1unused:5; /* bits 27-31 */ - u32 FBR1wrap:1; /* bit 26 */ - u32 FBR1offset:10; /* bits 16-25 */ - u32 FBR0unused:5; /* bits 11-15 */ - u32 FBR0wrap:1; /* bit 10 */ - u32 FBR0offset:10; /* bits 0-9 */ -#else - u32 FBR0offset:10; /* bits 0-9 */ - u32 FBR0wrap:1; /* bit 10 */ - u32 FBR0unused:5; /* bits 11-15 */ - u32 FBR1offset:10; /* bits 16-25 */ - u32 FBR1wrap:1; /* bit 26 */ - u32 FBR1unused:5; /* bits 27-31 */ -#endif - } bits; -} RXSTAT_WORD0_t, *PRXSTAT_WORD0_t; /* * RXSTAT_WORD1_t structure holds part of the status bits of the Rx DMA engine * that get copied out to memory by the ET-1310. Word 3 is a 32 bit word * which contains the Packet Status Ring available offset. */ + +#define RXSTAT1_OFFSET 16 +#define RXSTAT1_MASK 0xFFF +#define RXSTAT1_WRAP 0x10000000 + typedef union _rxstat_word1_t { u32 value; struct { @@ -261,7 +251,7 @@ typedef union _rxstat_word1_t { * it sits in free memory, and is pointed to by 0x101c / 0x1020 */ typedef struct _rx_status_block_t { - RXSTAT_WORD0_t Word0; + u32 Word0; RXSTAT_WORD1_t Word1; } RX_STATUS_BLOCK_t, *PRX_STATUS_BLOCK_t; @@ -282,15 +272,6 @@ typedef enum { } eRX_INTERRUPT_STATE_t, *PeRX_INTERRUPT_STATE_t; /* - * Structure to hold the skb's in a list - */ -typedef struct rx_skb_list_elem { - struct list_head skb_list_elem; - dma_addr_t dma_addr; - struct sk_buff *skb; -} RX_SKB_LIST_ELEM, *PRX_SKB_LIST_ELEM; - -/* * RX_RING_t is sructure representing the adaptor's local reference(s) to the * rings */ @@ -319,21 +300,16 @@ typedef struct _rx_ring_t { void *pPSRingVa; dma_addr_t pPSRingPa; - uint64_t pPSRingRealPa; - uint64_t pPSRingOffset; RXDMA_PSR_FULL_OFFSET_t local_psr_full; u32 PsrNumEntries; void *pRxStatusVa; dma_addr_t pRxStatusPa; - uint64_t RxStatusRealPA; - uint64_t RxStatusOffset; struct list_head RecvBufferPool; /* RECV */ struct list_head RecvList; - struct list_head RecvPendingList; u32 nReadyRecv; u32 NumRfd; diff --git a/drivers/staging/et131x/et1310_tx.c b/drivers/staging/et131x/et1310_tx.c index 94f7752e2ccc..d0c71db6c57c 100644 --- a/drivers/staging/et131x/et1310_tx.c +++ b/drivers/staging/et131x/et1310_tx.c @@ -94,13 +94,11 @@ #include "et1310_tx.h" -static void et131x_update_tcb_list(struct et131x_adapter *etdev); -static void et131x_check_send_wait_list(struct et131x_adapter *etdev); static inline void et131x_free_send_packet(struct et131x_adapter *etdev, - PMP_TCB pMpTcb); + struct tcb *tcb); static int et131x_send_packet(struct sk_buff *skb, struct et131x_adapter *etdev); -static int nic_send_packet(struct et131x_adapter *etdev, PMP_TCB pMpTcb); +static int nic_send_packet(struct et131x_adapter *etdev, struct tcb *tcb); /** * et131x_tx_dma_memory_alloc @@ -117,12 +115,12 @@ static int nic_send_packet(struct et131x_adapter *etdev, PMP_TCB pMpTcb); int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter) { int desc_size = 0; - TX_RING_t *tx_ring = &adapter->TxRing; + struct tx_ring *tx_ring = &adapter->tx_ring; /* Allocate memory for the TCB's (Transmit Control Block) */ - adapter->TxRing.MpTcbMem = (MP_TCB *)kcalloc(NUM_TCB, sizeof(MP_TCB), - GFP_ATOMIC | GFP_DMA); - if (!adapter->TxRing.MpTcbMem) { + adapter->tx_ring.tcb_ring = (struct tcb *) + kcalloc(NUM_TCB, sizeof(struct tcb), GFP_ATOMIC | GFP_DMA); + if (!adapter->tx_ring.tcb_ring) { dev_err(&adapter->pdev->dev, "Cannot alloc memory for TCBs\n"); return -ENOMEM; } @@ -130,12 +128,13 @@ int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter) /* Allocate enough memory for the Tx descriptor ring, and allocate * some extra so that the ring can be aligned on a 4k boundary. */ - desc_size = (sizeof(TX_DESC_ENTRY_t) * NUM_DESC_PER_RING_TX) + 4096 - 1; - tx_ring->pTxDescRingVa = - (PTX_DESC_ENTRY_t) pci_alloc_consistent(adapter->pdev, desc_size, - &tx_ring->pTxDescRingPa); - if (!adapter->TxRing.pTxDescRingVa) { - dev_err(&adapter->pdev->dev, "Cannot alloc memory for Tx Ring\n"); + desc_size = (sizeof(struct tx_desc) * NUM_DESC_PER_RING_TX) + 4096 - 1; + tx_ring->tx_desc_ring = + (struct tx_desc *) pci_alloc_consistent(adapter->pdev, desc_size, + &tx_ring->tx_desc_ring_pa); + if (!adapter->tx_ring.tx_desc_ring) { + dev_err(&adapter->pdev->dev, + "Cannot alloc memory for Tx Ring\n"); return -ENOMEM; } @@ -146,35 +145,15 @@ int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter) * are ever returned, make sure the high part is retrieved here before * storing the adjusted address. */ - tx_ring->pTxDescRingAdjustedPa = tx_ring->pTxDescRingPa; - - /* Align Tx Descriptor Ring on a 4k (0x1000) byte boundary */ - et131x_align_allocated_memory(adapter, - &tx_ring->pTxDescRingAdjustedPa, - &tx_ring->TxDescOffset, 0x0FFF); - - tx_ring->pTxDescRingVa += tx_ring->TxDescOffset; - /* Allocate memory for the Tx status block */ - tx_ring->pTxStatusVa = pci_alloc_consistent(adapter->pdev, - sizeof(TX_STATUS_BLOCK_t), - &tx_ring->pTxStatusPa); - if (!adapter->TxRing.pTxStatusPa) { + tx_ring->tx_status = pci_alloc_consistent(adapter->pdev, + sizeof(u32), + &tx_ring->tx_status_pa); + if (!adapter->tx_ring.tx_status_pa) { dev_err(&adapter->pdev->dev, "Cannot alloc memory for Tx status block\n"); return -ENOMEM; } - - /* Allocate memory for a dummy buffer */ - tx_ring->pTxDummyBlkVa = pci_alloc_consistent(adapter->pdev, - NIC_MIN_PACKET_SIZE, - &tx_ring->pTxDummyBlkPa); - if (!adapter->TxRing.pTxDummyBlkPa) { - dev_err(&adapter->pdev->dev, - "Cannot alloc memory for Tx dummy buffer\n"); - return -ENOMEM; - } - return 0; } @@ -188,76 +167,59 @@ void et131x_tx_dma_memory_free(struct et131x_adapter *adapter) { int desc_size = 0; - if (adapter->TxRing.pTxDescRingVa) { + if (adapter->tx_ring.tx_desc_ring) { /* Free memory relating to Tx rings here */ - adapter->TxRing.pTxDescRingVa -= adapter->TxRing.TxDescOffset; - - desc_size = - (sizeof(TX_DESC_ENTRY_t) * NUM_DESC_PER_RING_TX) + 4096 - 1; - + desc_size = (sizeof(struct tx_desc) * NUM_DESC_PER_RING_TX) + + 4096 - 1; pci_free_consistent(adapter->pdev, desc_size, - adapter->TxRing.pTxDescRingVa, - adapter->TxRing.pTxDescRingPa); - - adapter->TxRing.pTxDescRingVa = NULL; + adapter->tx_ring.tx_desc_ring, + adapter->tx_ring.tx_desc_ring_pa); + adapter->tx_ring.tx_desc_ring = NULL; } /* Free memory for the Tx status block */ - if (adapter->TxRing.pTxStatusVa) { - pci_free_consistent(adapter->pdev, - sizeof(TX_STATUS_BLOCK_t), - adapter->TxRing.pTxStatusVa, - adapter->TxRing.pTxStatusPa); - - adapter->TxRing.pTxStatusVa = NULL; - } - - /* Free memory for the dummy buffer */ - if (adapter->TxRing.pTxDummyBlkVa) { + if (adapter->tx_ring.tx_status) { pci_free_consistent(adapter->pdev, - NIC_MIN_PACKET_SIZE, - adapter->TxRing.pTxDummyBlkVa, - adapter->TxRing.pTxDummyBlkPa); + sizeof(u32), + adapter->tx_ring.tx_status, + adapter->tx_ring.tx_status_pa); - adapter->TxRing.pTxDummyBlkVa = NULL; + adapter->tx_ring.tx_status = NULL; } - - /* Free the memory for MP_TCB structures */ - kfree(adapter->TxRing.MpTcbMem); + /* Free the memory for the tcb structures */ + kfree(adapter->tx_ring.tcb_ring); } /** * ConfigTxDmaRegs - Set up the tx dma section of the JAGCore. * @etdev: pointer to our private adapter structure + * + * Configure the transmit engine with the ring buffers we have created + * and prepare it for use. */ void ConfigTxDmaRegs(struct et131x_adapter *etdev) { struct _TXDMA_t __iomem *txdma = &etdev->regs->txdma; /* Load the hardware with the start of the transmit descriptor ring. */ - writel((uint32_t) (etdev->TxRing.pTxDescRingAdjustedPa >> 32), + writel((u32) ((u64)etdev->tx_ring.tx_desc_ring_pa >> 32), &txdma->pr_base_hi); - writel((uint32_t) etdev->TxRing.pTxDescRingAdjustedPa, + writel((u32) etdev->tx_ring.tx_desc_ring_pa, &txdma->pr_base_lo); /* Initialise the transmit DMA engine */ writel(NUM_DESC_PER_RING_TX - 1, &txdma->pr_num_des.value); - /* Load the completion writeback physical address - * - * NOTE: pci_alloc_consistent(), used above to alloc DMA regions, - * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses - * are ever returned, make sure the high part is retrieved here before - * storing the adjusted address. - */ - writel(0, &txdma->dma_wb_base_hi); - writel(etdev->TxRing.pTxStatusPa, &txdma->dma_wb_base_lo); + /* Load the completion writeback physical address */ + writel((u32)((u64)etdev->tx_ring.tx_status_pa >> 32), + &txdma->dma_wb_base_hi); + writel((u32)etdev->tx_ring.tx_status_pa, &txdma->dma_wb_base_lo); - memset(etdev->TxRing.pTxStatusVa, 0, sizeof(TX_STATUS_BLOCK_t)); + *etdev->tx_ring.tx_status = 0; writel(0, &txdma->service_request); - etdev->TxRing.txDmaReadyToSend = 0; + etdev->tx_ring.send_idx = 0; } /** @@ -279,16 +241,11 @@ void et131x_tx_dma_disable(struct et131x_adapter *etdev) */ void et131x_tx_dma_enable(struct et131x_adapter *etdev) { - u32 csr = ET_TXDMA_SNGL_EPKT; - if (etdev->RegistryPhyLoopbk) - /* TxDMA is disabled for loopback operation. */ - csr |= ET_TXDMA_CSR_HALT; - else - /* Setup the transmit dma configuration register for normal - * operation - */ - csr |= PARM_DMA_CACHE_DEF << ET_TXDMA_CACHE_SHIFT; - writel(csr, &etdev->regs->txdma.csr); + /* Setup the transmit dma configuration register for normal + * operation + */ + writel(ET_TXDMA_SNGL_EPKT|(PARM_DMA_CACHE_DEF << ET_TXDMA_CACHE_SHIFT), + &etdev->regs->txdma.csr); } /** @@ -297,39 +254,32 @@ void et131x_tx_dma_enable(struct et131x_adapter *etdev) */ void et131x_init_send(struct et131x_adapter *adapter) { - PMP_TCB pMpTcb; - uint32_t TcbCount; - TX_RING_t *tx_ring; + struct tcb *tcb; + u32 ct; + struct tx_ring *tx_ring; /* Setup some convenience pointers */ - tx_ring = &adapter->TxRing; - pMpTcb = adapter->TxRing.MpTcbMem; + tx_ring = &adapter->tx_ring; + tcb = adapter->tx_ring.tcb_ring; - tx_ring->TCBReadyQueueHead = pMpTcb; + tx_ring->tcb_qhead = tcb; - /* Go through and set up each TCB */ - for (TcbCount = 0; TcbCount < NUM_TCB; TcbCount++) { - memset(pMpTcb, 0, sizeof(MP_TCB)); + memset(tcb, 0, sizeof(struct tcb) * NUM_TCB); + /* Go through and set up each TCB */ + for (ct = 0; ct++ < NUM_TCB; tcb++) /* Set the link pointer in HW TCB to the next TCB in the - * chain. If this is the last TCB in the chain, also set the - * tail pointer. + * chain */ - if (TcbCount < NUM_TCB - 1) { - pMpTcb->Next = pMpTcb + 1; - } else { - tx_ring->TCBReadyQueueTail = pMpTcb; - pMpTcb->Next = (PMP_TCB) NULL; - } - - pMpTcb++; - } + tcb->next = tcb + 1; + /* Set the tail pointer */ + tcb--; + tx_ring->tcb_qtail = tcb; + tcb->next = NULL; /* Curr send queue should now be empty */ - tx_ring->CurrSendHead = (PMP_TCB) NULL; - tx_ring->CurrSendTail = (PMP_TCB) NULL; - - INIT_LIST_HEAD(&adapter->TxRing.SendWaitQueue); + tx_ring->send_head = NULL; + tx_ring->send_tail = NULL; } /** @@ -352,9 +302,8 @@ int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev) * to Tx, so the PacketCount and it's array used makes no sense here */ - /* Queue is not empty or TCB is not available */ - if (!list_empty(&etdev->TxRing.SendWaitQueue) || - MP_TCB_RESOURCES_NOT_AVAILABLE(etdev)) { + /* TCB is not available */ + if (etdev->tx_ring.used >= NUM_TCB) { /* NOTE: If there's an error on send, no need to queue the * packet under Linux; if we just send an error up to the * netif layer, it will resend the skb to us. @@ -364,27 +313,15 @@ int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev) /* We need to see if the link is up; if it's not, make the * netif layer think we're good and drop the packet */ - /* - * if( MP_SHOULD_FAIL_SEND( etdev ) || - * etdev->DriverNoPhyAccess ) - */ - if (MP_SHOULD_FAIL_SEND(etdev) || etdev->DriverNoPhyAccess - || !netif_carrier_ok(netdev)) { + if ((etdev->Flags & fMP_ADAPTER_FAIL_SEND_MASK) || + !netif_carrier_ok(netdev)) { dev_kfree_skb_any(skb); skb = NULL; etdev->net_stats.tx_dropped++; } else { status = et131x_send_packet(skb, etdev); - - if (status == -ENOMEM) { - - /* NOTE: If there's an error on send, no need - * to queue the packet under Linux; if we just - * send an error up to the netif layer, it - * will resend the skb to us. - */ - } else if (status != 0) { + if (status != 0 && status != -ENOMEM) { /* On any other error, make netif think we're * OK and drop the packet */ @@ -409,87 +346,83 @@ int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev) static int et131x_send_packet(struct sk_buff *skb, struct et131x_adapter *etdev) { - int status = 0; - PMP_TCB pMpTcb = NULL; - uint16_t *shbufva; + int status; + struct tcb *tcb = NULL; + u16 *shbufva; unsigned long flags; /* All packets must have at least a MAC address and a protocol type */ - if (skb->len < ETH_HLEN) { + if (skb->len < ETH_HLEN) return -EIO; - } /* Get a TCB for this packet */ spin_lock_irqsave(&etdev->TCBReadyQLock, flags); - pMpTcb = etdev->TxRing.TCBReadyQueueHead; + tcb = etdev->tx_ring.tcb_qhead; - if (pMpTcb == NULL) { + if (tcb == NULL) { spin_unlock_irqrestore(&etdev->TCBReadyQLock, flags); return -ENOMEM; } - etdev->TxRing.TCBReadyQueueHead = pMpTcb->Next; + etdev->tx_ring.tcb_qhead = tcb->next; - if (etdev->TxRing.TCBReadyQueueHead == NULL) - etdev->TxRing.TCBReadyQueueTail = NULL; + if (etdev->tx_ring.tcb_qhead == NULL) + etdev->tx_ring.tcb_qtail = NULL; spin_unlock_irqrestore(&etdev->TCBReadyQLock, flags); - pMpTcb->PacketLength = skb->len; - pMpTcb->Packet = skb; + tcb->skb = skb; - if ((skb->data != NULL) && ((skb->len - skb->data_len) >= 6)) { - shbufva = (uint16_t *) skb->data; + if (skb->data != NULL && skb->len - skb->data_len >= 6) { + shbufva = (u16 *) skb->data; if ((shbufva[0] == 0xffff) && (shbufva[1] == 0xffff) && (shbufva[2] == 0xffff)) { - pMpTcb->Flags |= fMP_DEST_BROAD; + tcb->flags |= fMP_DEST_BROAD; } else if ((shbufva[0] & 0x3) == 0x0001) { - pMpTcb->Flags |= fMP_DEST_MULTI; + tcb->flags |= fMP_DEST_MULTI; } } - pMpTcb->Next = NULL; + tcb->next = NULL; /* Call the NIC specific send handler. */ - if (status == 0) - status = nic_send_packet(etdev, pMpTcb); + status = nic_send_packet(etdev, tcb); if (status != 0) { spin_lock_irqsave(&etdev->TCBReadyQLock, flags); - if (etdev->TxRing.TCBReadyQueueTail) { - etdev->TxRing.TCBReadyQueueTail->Next = pMpTcb; - } else { + if (etdev->tx_ring.tcb_qtail) + etdev->tx_ring.tcb_qtail->next = tcb; + else /* Apparently ready Q is empty. */ - etdev->TxRing.TCBReadyQueueHead = pMpTcb; - } + etdev->tx_ring.tcb_qhead = tcb; - etdev->TxRing.TCBReadyQueueTail = pMpTcb; + etdev->tx_ring.tcb_qtail = tcb; spin_unlock_irqrestore(&etdev->TCBReadyQLock, flags); return status; } - WARN_ON(etdev->TxRing.nBusySend > NUM_TCB); + WARN_ON(etdev->tx_ring.used > NUM_TCB); return 0; } /** * nic_send_packet - NIC specific send handler for version B silicon. * @etdev: pointer to our adapter - * @pMpTcb: pointer to MP_TCB + * @tcb: pointer to struct tcb * * Returns 0 or errno. */ -static int nic_send_packet(struct et131x_adapter *etdev, PMP_TCB pMpTcb) +static int nic_send_packet(struct et131x_adapter *etdev, struct tcb *tcb) { - uint32_t loopIndex; - TX_DESC_ENTRY_t CurDesc[24]; - uint32_t FragmentNumber = 0; - uint32_t thiscopy, remainder; - struct sk_buff *pPacket = pMpTcb->Packet; - uint32_t FragListCount = skb_shinfo(pPacket)->nr_frags + 1; - struct skb_frag_struct *pFragList = &skb_shinfo(pPacket)->frags[0]; + u32 i; + struct tx_desc desc[24]; /* 24 x 16 byte */ + u32 frag = 0; + u32 thiscopy, remainder; + struct sk_buff *skb = tcb->skb; + u32 nr_frags = skb_shinfo(skb)->nr_frags + 1; + struct skb_frag_struct *frags = &skb_shinfo(skb)->frags[0]; unsigned long flags; /* Part of the optimizations of this send routine restrict us to @@ -500,17 +433,16 @@ static int nic_send_packet(struct et131x_adapter *etdev, PMP_TCB pMpTcb) * number of fragments. If needed, we can call this function, * although it is less efficient. */ - if (FragListCount > 23) { + if (nr_frags > 23) return -EIO; - } - memset(CurDesc, 0, sizeof(TX_DESC_ENTRY_t) * (FragListCount + 1)); + memset(desc, 0, sizeof(struct tx_desc) * (nr_frags + 1)); - for (loopIndex = 0; loopIndex < FragListCount; loopIndex++) { + for (i = 0; i < nr_frags; i++) { /* If there is something in this element, lets get a * descriptor from the ring and get the necessary data */ - if (loopIndex == 0) { + if (i == 0) { /* If the fragments are smaller than a standard MTU, * then map them to a single descriptor in the Tx * Desc ring. However, if they're larger, as is @@ -520,166 +452,164 @@ static int nic_send_packet(struct et131x_adapter *etdev, PMP_TCB pMpTcb) * This will work until we determine why the hardware * doesn't seem to like large fragments. */ - if ((pPacket->len - pPacket->data_len) <= 1514) { - CurDesc[FragmentNumber].DataBufferPtrHigh = 0; - CurDesc[FragmentNumber].word2.bits. - length_in_bytes = - pPacket->len - pPacket->data_len; + if ((skb->len - skb->data_len) <= 1514) { + desc[frag].addr_hi = 0; + /* Low 16bits are length, high is vlan and + unused currently so zero */ + desc[frag].len_vlan = + skb->len - skb->data_len; /* NOTE: Here, the dma_addr_t returned from * pci_map_single() is implicitly cast as a - * uint32_t. Although dma_addr_t can be + * u32. Although dma_addr_t can be * 64-bit, the address returned by * pci_map_single() is always 32-bit * addressable (as defined by the pci/dma * subsystem) */ - CurDesc[FragmentNumber++].DataBufferPtrLow = + desc[frag++].addr_lo = pci_map_single(etdev->pdev, - pPacket->data, - pPacket->len - - pPacket->data_len, + skb->data, + skb->len - + skb->data_len, PCI_DMA_TODEVICE); } else { - CurDesc[FragmentNumber].DataBufferPtrHigh = 0; - CurDesc[FragmentNumber].word2.bits. - length_in_bytes = - ((pPacket->len - pPacket->data_len) / 2); + desc[frag].addr_hi = 0; + desc[frag].len_vlan = + (skb->len - skb->data_len) / 2; /* NOTE: Here, the dma_addr_t returned from * pci_map_single() is implicitly cast as a - * uint32_t. Although dma_addr_t can be + * u32. Although dma_addr_t can be * 64-bit, the address returned by * pci_map_single() is always 32-bit * addressable (as defined by the pci/dma * subsystem) */ - CurDesc[FragmentNumber++].DataBufferPtrLow = + desc[frag++].addr_lo = pci_map_single(etdev->pdev, - pPacket->data, - ((pPacket->len - - pPacket->data_len) / 2), + skb->data, + ((skb->len - + skb->data_len) / 2), PCI_DMA_TODEVICE); - CurDesc[FragmentNumber].DataBufferPtrHigh = 0; + desc[frag].addr_hi = 0; - CurDesc[FragmentNumber].word2.bits. - length_in_bytes = - ((pPacket->len - pPacket->data_len) / 2); + desc[frag].len_vlan = + (skb->len - skb->data_len) / 2; /* NOTE: Here, the dma_addr_t returned from * pci_map_single() is implicitly cast as a - * uint32_t. Although dma_addr_t can be + * u32. Although dma_addr_t can be * 64-bit, the address returned by * pci_map_single() is always 32-bit * addressable (as defined by the pci/dma * subsystem) */ - CurDesc[FragmentNumber++].DataBufferPtrLow = + desc[frag++].addr_lo = pci_map_single(etdev->pdev, - pPacket->data + - ((pPacket->len - - pPacket->data_len) / 2), - ((pPacket->len - - pPacket->data_len) / 2), + skb->data + + ((skb->len - + skb->data_len) / 2), + ((skb->len - + skb->data_len) / 2), PCI_DMA_TODEVICE); } } else { - CurDesc[FragmentNumber].DataBufferPtrHigh = 0; - CurDesc[FragmentNumber].word2.bits.length_in_bytes = - pFragList[loopIndex - 1].size; + desc[frag].addr_hi = 0; + desc[frag].len_vlan = + frags[i - 1].size; /* NOTE: Here, the dma_addr_t returned from - * pci_map_page() is implicitly cast as a uint32_t. + * pci_map_page() is implicitly cast as a u32. * Although dma_addr_t can be 64-bit, the address * returned by pci_map_page() is always 32-bit * addressable (as defined by the pci/dma subsystem) */ - CurDesc[FragmentNumber++].DataBufferPtrLow = + desc[frag++].addr_lo = pci_map_page(etdev->pdev, - pFragList[loopIndex - 1].page, - pFragList[loopIndex - 1].page_offset, - pFragList[loopIndex - 1].size, + frags[i - 1].page, + frags[i - 1].page_offset, + frags[i - 1].size, PCI_DMA_TODEVICE); } } - if (FragmentNumber == 0) + if (frag == 0) return -EIO; if (etdev->linkspeed == TRUEPHY_SPEED_1000MBPS) { - if (++etdev->TxRing.TxPacketsSinceLastinterrupt == - PARM_TX_NUM_BUFS_DEF) { - CurDesc[FragmentNumber - 1].word3.value = 0x5; - etdev->TxRing.TxPacketsSinceLastinterrupt = 0; - } else { - CurDesc[FragmentNumber - 1].word3.value = 0x1; + if (++etdev->tx_ring.since_irq == PARM_TX_NUM_BUFS_DEF) { + /* Last element & Interrupt flag */ + desc[frag - 1].flags = 0x5; + etdev->tx_ring.since_irq = 0; + } else { /* Last element */ + desc[frag - 1].flags = 0x1; } - } else { - CurDesc[FragmentNumber - 1].word3.value = 0x5; - } + } else + desc[frag - 1].flags = 0x5; - CurDesc[0].word3.bits.f = 1; + desc[0].flags |= 2; /* First element flag */ - pMpTcb->WrIndexStart = etdev->TxRing.txDmaReadyToSend; - pMpTcb->PacketStaleCount = 0; + tcb->index_start = etdev->tx_ring.send_idx; + tcb->stale = 0; spin_lock_irqsave(&etdev->SendHWLock, flags); thiscopy = NUM_DESC_PER_RING_TX - - INDEX10(etdev->TxRing.txDmaReadyToSend); + INDEX10(etdev->tx_ring.send_idx); - if (thiscopy >= FragmentNumber) { + if (thiscopy >= frag) { remainder = 0; - thiscopy = FragmentNumber; + thiscopy = frag; } else { - remainder = FragmentNumber - thiscopy; + remainder = frag - thiscopy; } - memcpy(etdev->TxRing.pTxDescRingVa + - INDEX10(etdev->TxRing.txDmaReadyToSend), CurDesc, - sizeof(TX_DESC_ENTRY_t) * thiscopy); + memcpy(etdev->tx_ring.tx_desc_ring + + INDEX10(etdev->tx_ring.send_idx), desc, + sizeof(struct tx_desc) * thiscopy); - add_10bit(&etdev->TxRing.txDmaReadyToSend, thiscopy); + add_10bit(&etdev->tx_ring.send_idx, thiscopy); - if (INDEX10(etdev->TxRing.txDmaReadyToSend)== 0 || - INDEX10(etdev->TxRing.txDmaReadyToSend) == NUM_DESC_PER_RING_TX) { - etdev->TxRing.txDmaReadyToSend &= ~ET_DMA10_MASK; - etdev->TxRing.txDmaReadyToSend ^= ET_DMA10_WRAP; + if (INDEX10(etdev->tx_ring.send_idx) == 0 || + INDEX10(etdev->tx_ring.send_idx) == NUM_DESC_PER_RING_TX) { + etdev->tx_ring.send_idx &= ~ET_DMA10_MASK; + etdev->tx_ring.send_idx ^= ET_DMA10_WRAP; } if (remainder) { - memcpy(etdev->TxRing.pTxDescRingVa, - CurDesc + thiscopy, - sizeof(TX_DESC_ENTRY_t) * remainder); + memcpy(etdev->tx_ring.tx_desc_ring, + desc + thiscopy, + sizeof(struct tx_desc) * remainder); - add_10bit(&etdev->TxRing.txDmaReadyToSend, remainder); + add_10bit(&etdev->tx_ring.send_idx, remainder); } - if (INDEX10(etdev->TxRing.txDmaReadyToSend) == 0) { - if (etdev->TxRing.txDmaReadyToSend) - pMpTcb->WrIndex = NUM_DESC_PER_RING_TX - 1; + if (INDEX10(etdev->tx_ring.send_idx) == 0) { + if (etdev->tx_ring.send_idx) + tcb->index = NUM_DESC_PER_RING_TX - 1; else - pMpTcb->WrIndex= ET_DMA10_WRAP | (NUM_DESC_PER_RING_TX - 1); + tcb->index = ET_DMA10_WRAP|(NUM_DESC_PER_RING_TX - 1); } else - pMpTcb->WrIndex = etdev->TxRing.txDmaReadyToSend - 1; + tcb->index = etdev->tx_ring.send_idx - 1; spin_lock(&etdev->TCBSendQLock); - if (etdev->TxRing.CurrSendTail) - etdev->TxRing.CurrSendTail->Next = pMpTcb; + if (etdev->tx_ring.send_tail) + etdev->tx_ring.send_tail->next = tcb; else - etdev->TxRing.CurrSendHead = pMpTcb; + etdev->tx_ring.send_head = tcb; - etdev->TxRing.CurrSendTail = pMpTcb; + etdev->tx_ring.send_tail = tcb; - WARN_ON(pMpTcb->Next != NULL); + WARN_ON(tcb->next != NULL); - etdev->TxRing.nBusySend++; + etdev->tx_ring.used++; spin_unlock(&etdev->TCBSendQLock); /* Write the new write pointer back to the device. */ - writel(etdev->TxRing.txDmaReadyToSend, + writel(etdev->tx_ring.send_idx, &etdev->regs->txdma.service_request); /* For Gig only, we use Tx Interrupt coalescing. Enable the software @@ -696,72 +626,71 @@ static int nic_send_packet(struct et131x_adapter *etdev, PMP_TCB pMpTcb) /** - * et131x_free_send_packet - Recycle a MP_TCB, complete the packet if necessary + * et131x_free_send_packet - Recycle a struct tcb * @etdev: pointer to our adapter - * @pMpTcb: pointer to MP_TCB + * @tcb: pointer to struct tcb * + * Complete the packet if necessary * Assumption - Send spinlock has been acquired */ inline void et131x_free_send_packet(struct et131x_adapter *etdev, - PMP_TCB pMpTcb) + struct tcb *tcb) { unsigned long flags; - TX_DESC_ENTRY_t *desc = NULL; + struct tx_desc *desc = NULL; struct net_device_stats *stats = &etdev->net_stats; - if (pMpTcb->Flags & fMP_DEST_BROAD) + if (tcb->flags & fMP_DEST_BROAD) atomic_inc(&etdev->Stats.brdcstxmt); - else if (pMpTcb->Flags & fMP_DEST_MULTI) + else if (tcb->flags & fMP_DEST_MULTI) atomic_inc(&etdev->Stats.multixmt); else atomic_inc(&etdev->Stats.unixmt); - if (pMpTcb->Packet) { - stats->tx_bytes += pMpTcb->Packet->len; + if (tcb->skb) { + stats->tx_bytes += tcb->skb->len; /* Iterate through the TX descriptors on the ring * corresponding to this packet and umap the fragments * they point to */ do { - desc = - (TX_DESC_ENTRY_t *) (etdev->TxRing.pTxDescRingVa + - INDEX10(pMpTcb->WrIndexStart)); + desc = (struct tx_desc *)(etdev->tx_ring.tx_desc_ring + + INDEX10(tcb->index_start)); pci_unmap_single(etdev->pdev, - desc->DataBufferPtrLow, - desc->word2.value, PCI_DMA_TODEVICE); - - add_10bit(&pMpTcb->WrIndexStart, 1); - if (INDEX10(pMpTcb->WrIndexStart) >= - NUM_DESC_PER_RING_TX) { - pMpTcb->WrIndexStart &= ~ET_DMA10_MASK; - pMpTcb->WrIndexStart ^= ET_DMA10_WRAP; + desc->addr_lo, + desc->len_vlan, PCI_DMA_TODEVICE); + + add_10bit(&tcb->index_start, 1); + if (INDEX10(tcb->index_start) >= + NUM_DESC_PER_RING_TX) { + tcb->index_start &= ~ET_DMA10_MASK; + tcb->index_start ^= ET_DMA10_WRAP; } - } while (desc != (etdev->TxRing.pTxDescRingVa + - INDEX10(pMpTcb->WrIndex))); + } while (desc != (etdev->tx_ring.tx_desc_ring + + INDEX10(tcb->index))); - dev_kfree_skb_any(pMpTcb->Packet); + dev_kfree_skb_any(tcb->skb); } - memset(pMpTcb, 0, sizeof(MP_TCB)); + memset(tcb, 0, sizeof(struct tcb)); /* Add the TCB to the Ready Q */ spin_lock_irqsave(&etdev->TCBReadyQLock, flags); etdev->Stats.opackets++; - if (etdev->TxRing.TCBReadyQueueTail) { - etdev->TxRing.TCBReadyQueueTail->Next = pMpTcb; - } else { + if (etdev->tx_ring.tcb_qtail) + etdev->tx_ring.tcb_qtail->next = tcb; + else /* Apparently ready Q is empty. */ - etdev->TxRing.TCBReadyQueueHead = pMpTcb; - } + etdev->tx_ring.tcb_qhead = tcb; - etdev->TxRing.TCBReadyQueueTail = pMpTcb; + etdev->tx_ring.tcb_qtail = tcb; spin_unlock_irqrestore(&etdev->TCBReadyQLock, flags); - WARN_ON(etdev->TxRing.nBusySend < 0); + WARN_ON(etdev->tx_ring.used < 0); } /** @@ -772,52 +701,40 @@ inline void et131x_free_send_packet(struct et131x_adapter *etdev, */ void et131x_free_busy_send_packets(struct et131x_adapter *etdev) { - PMP_TCB pMpTcb; - struct list_head *entry; + struct tcb *tcb; unsigned long flags; - uint32_t FreeCounter = 0; - - while (!list_empty(&etdev->TxRing.SendWaitQueue)) { - spin_lock_irqsave(&etdev->SendWaitLock, flags); - - etdev->TxRing.nWaitSend--; - spin_unlock_irqrestore(&etdev->SendWaitLock, flags); - - entry = etdev->TxRing.SendWaitQueue.next; - } - - etdev->TxRing.nWaitSend = 0; + u32 freed = 0; /* Any packets being sent? Check the first TCB on the send list */ spin_lock_irqsave(&etdev->TCBSendQLock, flags); - pMpTcb = etdev->TxRing.CurrSendHead; + tcb = etdev->tx_ring.send_head; - while ((pMpTcb != NULL) && (FreeCounter < NUM_TCB)) { - PMP_TCB pNext = pMpTcb->Next; + while (tcb != NULL && freed < NUM_TCB) { + struct tcb *next = tcb->next; - etdev->TxRing.CurrSendHead = pNext; + etdev->tx_ring.send_head = next; - if (pNext == NULL) - etdev->TxRing.CurrSendTail = NULL; + if (next == NULL) + etdev->tx_ring.send_tail = NULL; - etdev->TxRing.nBusySend--; + etdev->tx_ring.used--; spin_unlock_irqrestore(&etdev->TCBSendQLock, flags); - FreeCounter++; - et131x_free_send_packet(etdev, pMpTcb); + freed++; + et131x_free_send_packet(etdev, tcb); spin_lock_irqsave(&etdev->TCBSendQLock, flags); - pMpTcb = etdev->TxRing.CurrSendHead; + tcb = etdev->tx_ring.send_head; } - WARN_ON(FreeCounter == NUM_TCB); + WARN_ON(freed == NUM_TCB); spin_unlock_irqrestore(&etdev->TCBSendQLock, flags); - etdev->TxRing.nBusySend = 0; + etdev->tx_ring.used = 0; } /** @@ -831,99 +748,56 @@ void et131x_free_busy_send_packets(struct et131x_adapter *etdev) */ void et131x_handle_send_interrupt(struct et131x_adapter *etdev) { - /* Mark as completed any packets which have been sent by the device. */ - et131x_update_tcb_list(etdev); - - /* If we queued any transmits because we didn't have any TCBs earlier, - * dequeue and send those packets now, as long as we have free TCBs. - */ - et131x_check_send_wait_list(etdev); -} - -/** - * et131x_update_tcb_list - Helper routine for Send Interrupt handler - * @etdev: pointer to our adapter - * - * Re-claims the send resources and completes sends. Can also be called as - * part of the NIC send routine when the "ServiceComplete" indication has - * wrapped. - */ -static void et131x_update_tcb_list(struct et131x_adapter *etdev) -{ unsigned long flags; - u32 ServiceComplete; - PMP_TCB pMpTcb; + u32 serviced; + struct tcb *tcb; u32 index; - ServiceComplete = readl(&etdev->regs->txdma.NewServiceComplete); - index = INDEX10(ServiceComplete); + serviced = readl(&etdev->regs->txdma.NewServiceComplete); + index = INDEX10(serviced); /* Has the ring wrapped? Process any descriptors that do not have * the same "wrap" indicator as the current completion indicator */ spin_lock_irqsave(&etdev->TCBSendQLock, flags); - pMpTcb = etdev->TxRing.CurrSendHead; + tcb = etdev->tx_ring.send_head; - while (pMpTcb && - ((ServiceComplete ^ pMpTcb->WrIndex) & ET_DMA10_WRAP) && - index < INDEX10(pMpTcb->WrIndex)) { - etdev->TxRing.nBusySend--; - etdev->TxRing.CurrSendHead = pMpTcb->Next; - if (pMpTcb->Next == NULL) - etdev->TxRing.CurrSendTail = NULL; + while (tcb && + ((serviced ^ tcb->index) & ET_DMA10_WRAP) && + index < INDEX10(tcb->index)) { + etdev->tx_ring.used--; + etdev->tx_ring.send_head = tcb->next; + if (tcb->next == NULL) + etdev->tx_ring.send_tail = NULL; spin_unlock_irqrestore(&etdev->TCBSendQLock, flags); - et131x_free_send_packet(etdev, pMpTcb); + et131x_free_send_packet(etdev, tcb); spin_lock_irqsave(&etdev->TCBSendQLock, flags); /* Goto the next packet */ - pMpTcb = etdev->TxRing.CurrSendHead; + tcb = etdev->tx_ring.send_head; } - while (pMpTcb && - !((ServiceComplete ^ pMpTcb->WrIndex) & ET_DMA10_WRAP) - && index > (pMpTcb->WrIndex & ET_DMA10_MASK)) { - etdev->TxRing.nBusySend--; - etdev->TxRing.CurrSendHead = pMpTcb->Next; - if (pMpTcb->Next == NULL) - etdev->TxRing.CurrSendTail = NULL; + while (tcb && + !((serviced ^ tcb->index) & ET_DMA10_WRAP) + && index > (tcb->index & ET_DMA10_MASK)) { + etdev->tx_ring.used--; + etdev->tx_ring.send_head = tcb->next; + if (tcb->next == NULL) + etdev->tx_ring.send_tail = NULL; spin_unlock_irqrestore(&etdev->TCBSendQLock, flags); - et131x_free_send_packet(etdev, pMpTcb); + et131x_free_send_packet(etdev, tcb); spin_lock_irqsave(&etdev->TCBSendQLock, flags); /* Goto the next packet */ - pMpTcb = etdev->TxRing.CurrSendHead; + tcb = etdev->tx_ring.send_head; } /* Wake up the queue when we hit a low-water mark */ - if (etdev->TxRing.nBusySend <= (NUM_TCB / 3)) + if (etdev->tx_ring.used <= NUM_TCB / 3) netif_wake_queue(etdev->netdev); spin_unlock_irqrestore(&etdev->TCBSendQLock, flags); } -/** - * et131x_check_send_wait_list - Helper routine for the interrupt handler - * @etdev: pointer to our adapter - * - * Takes packets from the send wait queue and posts them to the device (if - * room available). - */ -static void et131x_check_send_wait_list(struct et131x_adapter *etdev) -{ - unsigned long flags; - - spin_lock_irqsave(&etdev->SendWaitLock, flags); - - while (!list_empty(&etdev->TxRing.SendWaitQueue) && - MP_TCB_RESOURCES_AVAILABLE(etdev)) { - struct list_head *entry; - - entry = etdev->TxRing.SendWaitQueue.next; - - etdev->TxRing.nWaitSend--; - } - - spin_unlock_irqrestore(&etdev->SendWaitLock, flags); -} diff --git a/drivers/staging/et131x/et1310_tx.h b/drivers/staging/et131x/et1310_tx.h index ad0372121de0..4f0ea81978f5 100644 --- a/drivers/staging/et131x/et1310_tx.h +++ b/drivers/staging/et131x/et1310_tx.h @@ -63,167 +63,89 @@ /* Typedefs for Tx Descriptor Ring */ /* - * TXDESC_WORD2_t structure holds part of the control bits in the Tx Descriptor - * ring for the ET-1310 + * word 2 of the control bits in the Tx Descriptor ring for the ET-1310 + * + * 0-15: length of packet + * 16-27: VLAN tag + * 28: VLAN CFI + * 29-31: VLAN priority + * + * word 3 of the control bits in the Tx Descriptor ring for the ET-1310 + * + * 0: last packet in the sequence + * 1: first packet in the sequence + * 2: interrupt the processor when this pkt sent + * 3: Control word - no packet data + * 4: Issue half-duplex backpressure : XON/XOFF + * 5: send pause frame + * 6: Tx frame has error + * 7: append CRC + * 8: MAC override + * 9: pad packet + * 10: Packet is a Huge packet + * 11: append VLAN tag + * 12: IP checksum assist + * 13: TCP checksum assist + * 14: UDP checksum assist */ -typedef union _txdesc_word2_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 vlan_prio:3; /* bits 29-31(VLAN priority) */ - u32 vlan_cfi:1; /* bit 28(cfi) */ - u32 vlan_tag:12; /* bits 16-27(VLAN tag) */ - u32 length_in_bytes:16; /* bits 0-15(packet length) */ -#else - u32 length_in_bytes:16; /* bits 0-15(packet length) */ - u32 vlan_tag:12; /* bits 16-27(VLAN tag) */ - u32 vlan_cfi:1; /* bit 28(cfi) */ - u32 vlan_prio:3; /* bits 29-31(VLAN priority) */ -#endif /* _BIT_FIELDS_HTOL */ - } bits; -} TXDESC_WORD2_t, *PTXDESC_WORD2_t; -/* - * TXDESC_WORD3_t structure holds part of the control bits in the Tx Descriptor - * ring for the ET-1310 - */ -typedef union _txdesc_word3_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 unused:17; /* bits 15-31 */ - u32 udpa:1; /* bit 14(UDP checksum assist) */ - u32 tcpa:1; /* bit 13(TCP checksum assist) */ - u32 ipa:1; /* bit 12(IP checksum assist) */ - u32 vlan:1; /* bit 11(append VLAN tag) */ - u32 hp:1; /* bit 10(Packet is a Huge packet) */ - u32 pp:1; /* bit 9(pad packet) */ - u32 mac:1; /* bit 8(MAC override) */ - u32 crc:1; /* bit 7(append CRC) */ - u32 e:1; /* bit 6(Tx frame has error) */ - u32 pf:1; /* bit 5(send pause frame) */ - u32 bp:1; /* bit 4(Issue half-duplex backpressure (XON/XOFF) */ - u32 cw:1; /* bit 3(Control word - no packet data) */ - u32 ir:1; /* bit 2(interrupt the processor when this pkt sent) */ - u32 f:1; /* bit 1(first packet in the sequence) */ - u32 l:1; /* bit 0(last packet in the sequence) */ -#else - u32 l:1; /* bit 0(last packet in the sequence) */ - u32 f:1; /* bit 1(first packet in the sequence) */ - u32 ir:1; /* bit 2(interrupt the processor when this pkt sent) */ - u32 cw:1; /* bit 3(Control word - no packet data) */ - u32 bp:1; /* bit 4(Issue half-duplex backpressure (XON/XOFF) */ - u32 pf:1; /* bit 5(send pause frame) */ - u32 e:1; /* bit 6(Tx frame has error) */ - u32 crc:1; /* bit 7(append CRC) */ - u32 mac:1; /* bit 8(MAC override) */ - u32 pp:1; /* bit 9(pad packet) */ - u32 hp:1; /* bit 10(Packet is a Huge packet) */ - u32 vlan:1; /* bit 11(append VLAN tag) */ - u32 ipa:1; /* bit 12(IP checksum assist) */ - u32 tcpa:1; /* bit 13(TCP checksum assist) */ - u32 udpa:1; /* bit 14(UDP checksum assist) */ - u32 unused:17; /* bits 15-31 */ -#endif /* _BIT_FIELDS_HTOL */ - } bits; -} TXDESC_WORD3_t, *PTXDESC_WORD3_t; - -/* TX_DESC_ENTRY_t is sructure representing each descriptor on the ring */ -typedef struct _tx_desc_entry_t { - u32 DataBufferPtrHigh; - u32 DataBufferPtrLow; - TXDESC_WORD2_t word2; /* control words how to xmit the */ - TXDESC_WORD3_t word3; /* data (detailed above) */ -} TX_DESC_ENTRY_t, *PTX_DESC_ENTRY_t; - - -/* Typedefs for Tx DMA engine status writeback */ +/* struct tx_desc represents each descriptor on the ring */ +struct tx_desc { + u32 addr_hi; + u32 addr_lo; + u32 len_vlan; /* control words how to xmit the */ + u32 flags; /* data (detailed above) */ +}; /* - * TX_STATUS_BLOCK_t is sructure representing the status of the Tx DMA engine - * it sits in free memory, and is pointed to by 0x101c / 0x1020 + * The status of the Tx DMA engine it sits in free memory, and is pointed to + * by 0x101c / 0x1020. This is a DMA10 type */ -typedef union _tx_status_block_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 unused:21; /* bits 11-31 */ - u32 serv_cpl_wrap:1; /* bit 10 */ - u32 serv_cpl:10; /* bits 0-9 */ -#else - u32 serv_cpl:10; /* bits 0-9 */ - u32 serv_cpl_wrap:1; /* bit 10 */ - u32 unused:21; /* bits 11-31 */ -#endif - } bits; -} TX_STATUS_BLOCK_t, *PTX_STATUS_BLOCK_t; - -/* TCB (Transmit Control Block) */ -typedef struct _MP_TCB { - struct _MP_TCB *Next; - u32 Flags; - u32 Count; - u32 PacketStaleCount; - struct sk_buff *Packet; - u32 PacketLength; - u32 WrIndex; - u32 WrIndexStart; -} MP_TCB, *PMP_TCB; - -/* Structure to hold the skb's in a list */ -typedef struct tx_skb_list_elem { - struct list_head skb_list_elem; - struct sk_buff *skb; -} TX_SKB_LIST_ELEM, *PTX_SKB_LIST_ELEM; - -/* TX_RING_t is sructure representing our local reference(s) to the ring */ -typedef struct _tx_ring_t { + +/* TCB (Transmit Control Block: Host Side) */ +struct tcb { + struct tcb *next; /* Next entry in ring */ + u32 flags; /* Our flags for the packet */ + u32 count; /* Used to spot stuck/lost packets */ + u32 stale; /* Used to spot stuck/lost packets */ + struct sk_buff *skb; /* Network skb we are tied to */ + u32 index; /* Ring indexes */ + u32 index_start; +}; + +/* Structure representing our local reference(s) to the ring */ +struct tx_ring { /* TCB (Transmit Control Block) memory and lists */ - PMP_TCB MpTcbMem; + struct tcb *tcb_ring; /* List of TCBs that are ready to be used */ - PMP_TCB TCBReadyQueueHead; - PMP_TCB TCBReadyQueueTail; + struct tcb *tcb_qhead; + struct tcb *tcb_qtail; /* list of TCBs that are currently being sent. NOTE that access to all - * three of these (including nBusySend) are controlled via the + * three of these (including used) are controlled via the * TCBSendQLock. This lock should be secured prior to incementing / - * decrementing nBusySend, or any queue manipulation on CurrSendHead / - * Tail + * decrementing used, or any queue manipulation on send_head / + * tail */ - PMP_TCB CurrSendHead; - PMP_TCB CurrSendTail; - int32_t nBusySend; - - /* List of packets (not TCBs) that were queued for lack of resources */ - struct list_head SendWaitQueue; - int32_t nWaitSend; + struct tcb *send_head; + struct tcb *send_tail; + int used; /* The actual descriptor ring */ - PTX_DESC_ENTRY_t pTxDescRingVa; - dma_addr_t pTxDescRingPa; - uint64_t pTxDescRingAdjustedPa; - uint64_t TxDescOffset; + struct tx_desc *tx_desc_ring; + dma_addr_t tx_desc_ring_pa; - /* ReadyToSend indicates where we last wrote to in the descriptor ring. */ - u32 txDmaReadyToSend; + /* send_idx indicates where we last wrote to in the descriptor ring. */ + u32 send_idx; /* The location of the write-back status block */ - PTX_STATUS_BLOCK_t pTxStatusVa; - dma_addr_t pTxStatusPa; - - /* A Block of zeroes used to pad packets that are less than 60 bytes */ - void *pTxDummyBlkVa; - dma_addr_t pTxDummyBlkPa; - - TXMAC_ERR_t TxMacErr; - - /* Variables to track the Tx interrupt coalescing features */ - int32_t TxPacketsSinceLastinterrupt; -} TX_RING_t, *PTX_RING_t; + u32 *tx_status; + dma_addr_t tx_status_pa; -/* Forward declaration of the frag-list for the following prototypes */ -typedef struct _MP_FRAG_LIST MP_FRAG_LIST, *PMP_FRAG_LIST; + /* Packets since the last IRQ: used for interrupt coalescing */ + int since_irq; +}; /* Forward declaration of the private adapter structure */ struct et131x_adapter; @@ -231,12 +153,12 @@ struct et131x_adapter; /* PROTOTYPES for et1310_tx.c */ int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter); void et131x_tx_dma_memory_free(struct et131x_adapter *adapter); -void ConfigTxDmaRegs(struct et131x_adapter *pAdapter); +void ConfigTxDmaRegs(struct et131x_adapter *adapter); void et131x_init_send(struct et131x_adapter *adapter); -void et131x_tx_dma_disable(struct et131x_adapter *pAdapter); -void et131x_tx_dma_enable(struct et131x_adapter *pAdapter); -void et131x_handle_send_interrupt(struct et131x_adapter *pAdapter); -void et131x_free_busy_send_packets(struct et131x_adapter *pAdapter); +void et131x_tx_dma_disable(struct et131x_adapter *adapter); +void et131x_tx_dma_enable(struct et131x_adapter *adapter); +void et131x_handle_send_interrupt(struct et131x_adapter *adapter); +void et131x_free_busy_send_packets(struct et131x_adapter *adapter); int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev); #endif /* __ET1310_TX_H__ */ diff --git a/drivers/staging/et131x/et131x_adapter.h b/drivers/staging/et131x/et131x_adapter.h index 1dfe06f1b1a7..cc5a6ba55dcf 100644 --- a/drivers/staging/et131x/et131x_adapter.h +++ b/drivers/staging/et131x/et131x_adapter.h @@ -100,12 +100,6 @@ #define LO_MARK_PERCENT_FOR_PSR 15 #define LO_MARK_PERCENT_FOR_RX 15 -/* Macros specific to the private adapter structure */ -#define MP_TCB_RESOURCES_AVAILABLE(_M) ((_M)->TxRing.nBusySend < NUM_TCB) -#define MP_TCB_RESOURCES_NOT_AVAILABLE(_M) ((_M)->TxRing.nBusySend >= NUM_TCB) - -#define MP_SHOULD_FAIL_SEND(_M) ((_M)->Flags & fMP_ADAPTER_FAIL_SEND_MASK) - /* Counters for error rate monitoring */ typedef struct _MP_ERR_COUNTERS { u32 PktCountTxPackets; @@ -203,7 +197,6 @@ struct et131x_adapter { spinlock_t TCBSendQLock; spinlock_t TCBReadyQLock; spinlock_t SendHWLock; - spinlock_t SendWaitLock; spinlock_t RcvLock; spinlock_t RcvPendLock; @@ -234,9 +227,6 @@ struct et131x_adapter { u32 RegistryRxMemEnd; /* Size of internal rx memory */ u32 RegistryJumboPacket; /* Max supported ethernet packet size */ - /* Validation helpers */ - u8 RegistryNMIDisable; - u8 RegistryPhyLoopbk; /* Enable Phy loopback */ /* Derived from the registry: */ u8 AiForceDpx; /* duplex setting */ @@ -248,7 +238,6 @@ struct et131x_adapter { NETIF_STATUS_MEDIA_DISCONNECT, NETIF_STATUS_MAX } MediaState; - u8 DriverNoPhyAccess; /* Minimize init-time */ struct timer_list ErrorTimer; @@ -259,7 +248,7 @@ struct et131x_adapter { MI_BMSR_t Bmsr; /* Tx Memory Variables */ - TX_RING_t TxRing; + struct tx_ring tx_ring; /* Rx Memory Variables */ RX_RING_t RxRing; diff --git a/drivers/staging/et131x/et131x_defs.h b/drivers/staging/et131x/et131x_defs.h index f98dca5fd26b..d81fc77a501f 100644 --- a/drivers/staging/et131x/et131x_defs.h +++ b/drivers/staging/et131x/et131x_defs.h @@ -102,7 +102,6 @@ /* Some offsets in PCI config space that are actually used. */ #define ET1310_PCI_MAX_PYLD 0x4C -#define ET1310_NMI_DISABLE 0x61 #define ET1310_PCI_MAC_ADDRESS 0xA4 #define ET1310_PCI_EEPROM_STATUS 0xB2 #define ET1310_PCI_ACK_NACK 0xC0 diff --git a/drivers/staging/et131x/et131x_initpci.c b/drivers/staging/et131x/et131x_initpci.c index 9db205667262..0892b6a538db 100644 --- a/drivers/staging/et131x/et131x_initpci.c +++ b/drivers/staging/et131x/et131x_initpci.c @@ -106,17 +106,6 @@ #define PARM_SPEED_DUPLEX_MIN 0 #define PARM_SPEED_DUPLEX_MAX 5 -/* Module parameter for disabling NMI - * et131x_nmi_disable : - * Disable NMI (0-2) [0] - * 0 : - * 1 : - * 2 : - */ -static u32 et131x_nmi_disable; /* 0-2 */ -module_param(et131x_nmi_disable, uint, 0); -MODULE_PARM_DESC(et131x_nmi_disable, "Disable NMI (0-2) [0]"); - /* Module parameter for manual speed setting * Set Link speed and dublex manually (0-5) [0] * 1 : 10Mb Half-Duplex @@ -132,128 +121,88 @@ MODULE_PARM_DESC(et131x_speed_set, "Set Link speed and dublex manually (0-5) [0] \n 1 : 10Mb Half-Duplex \n 2 : 10Mb Full-Duplex \n 3 : 100Mb Half-Duplex \n 4 : 100Mb Full-Duplex \n 5 : 1000Mb Full-Duplex \n 0 : Auto Speed Auto Dublex"); /** - * et131x_find_adapter - Find the adapter and get all the assigned resources + * et131x_hwaddr_init - set up the MAC Address on the ET1310 * @adapter: pointer to our private adapter structure - * - * Returns 0 on success, errno on failure (as defined in errno.h) */ -int et131x_find_adapter(struct et131x_adapter *adapter, struct pci_dev *pdev) +void et131x_hwaddr_init(struct et131x_adapter *adapter) { - int result; - uint8_t eepromStat; - uint8_t maxPayload = 0; - uint8_t read_size_reg; - u8 rev; - - /* Allow disabling of Non-Maskable Interrupts in I/O space, to - * support validation. + /* If have our default mac from init and no mac address from + * EEPROM then we need to generate the last octet and set it on the + * device */ - if (adapter->RegistryNMIDisable) { - uint8_t RegisterVal; - - RegisterVal = inb(ET1310_NMI_DISABLE); - RegisterVal &= 0xf3; - - if (adapter->RegistryNMIDisable == 2) - RegisterVal |= 0xc; - - outb(ET1310_NMI_DISABLE, RegisterVal); + if (adapter->PermanentAddress[0] == 0x00 && + adapter->PermanentAddress[1] == 0x00 && + adapter->PermanentAddress[2] == 0x00 && + adapter->PermanentAddress[3] == 0x00 && + adapter->PermanentAddress[4] == 0x00 && + adapter->PermanentAddress[5] == 0x00) { + /* + * We need to randomly generate the last octet so we + * decrease our chances of setting the mac address to + * same as another one of our cards in the system + */ + get_random_bytes(&adapter->CurrentAddress[5], 1); + /* + * We have the default value in the register we are + * working with so we need to copy the current + * address into the permanent address + */ + memcpy(adapter->PermanentAddress, + adapter->CurrentAddress, ETH_ALEN); + } else { + /* We do not have an override address, so set the + * current address to the permanent address and add + * it to the device + */ + memcpy(adapter->CurrentAddress, + adapter->PermanentAddress, ETH_ALEN); } +} - /* We first need to check the EEPROM Status code located at offset - * 0xB2 of config space - */ - result = pci_read_config_byte(pdev, ET1310_PCI_EEPROM_STATUS, - &eepromStat); - - /* THIS IS A WORKAROUND: - * I need to call this function twice to get my card in a - * LG M1 Express Dual running. I tried also a msleep before this - * function, because I thougth there could be some time condidions - * but it didn't work. Call the whole function twice also work. - */ - result = pci_read_config_byte(pdev, ET1310_PCI_EEPROM_STATUS, - &eepromStat); - if (result != PCIBIOS_SUCCESSFUL) { - dev_err(&pdev->dev, "Could not read PCI config space for " - "EEPROM Status\n"); - return -EIO; - } - /* Determine if the error(s) we care about are present. If they are - * present, we need to fail. - */ - if (eepromStat & 0x4C) { - result = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); - if (result != PCIBIOS_SUCCESSFUL) { - dev_err(&pdev->dev, - "Could not read PCI config space for " - "Revision ID\n"); - return -EIO; - } else if (rev == 0x01) { - int32_t nLoop; - uint8_t temp[4] = { 0xFE, 0x13, 0x10, 0xFF }; - - /* Re-write the first 4 bytes if we have an eeprom - * present and the revision id is 1, this fixes the - * corruption seen with 1310 B Silicon - */ - for (nLoop = 0; nLoop < 3; nLoop++) { - EepromWriteByte(adapter, nLoop, temp[nLoop]); - } - } +/** + * et131x_pci_init - initial PCI setup + * @adapter: pointer to our private adapter structure + * @pdev: our PCI device + * + * Perform the initial setup of PCI registers and if possible initialise + * the MAC address. At this point the I/O registers have yet to be mapped + */ - dev_err(&pdev->dev, "Fatal EEPROM Status Error - 0x%04x\n", eepromStat); +static int et131x_pci_init(struct et131x_adapter *adapter, + struct pci_dev *pdev) +{ + int i; + u8 max_payload; + u8 read_size_reg; - /* This error could mean that there was an error reading the - * eeprom or that the eeprom doesn't exist. We will treat - * each case the same and not try to gather additional - * information that normally would come from the eeprom, like - * MAC Address - */ - adapter->has_eeprom = 0; + if (et131x_init_eeprom(adapter) < 0) return -EIO; - } else - adapter->has_eeprom = 1; - - /* Read the EEPROM for information regarding LED behavior. Refer to - * ET1310_phy.c, et131x_xcvr_init(), for its use. - */ - EepromReadByte(adapter, 0x70, &adapter->eepromData[0]); - EepromReadByte(adapter, 0x71, &adapter->eepromData[1]); - - if (adapter->eepromData[0] != 0xcd) - /* Disable all optional features */ - adapter->eepromData[1] = 0x00; /* Let's set up the PORT LOGIC Register. First we need to know what * the max_payload_size is */ - result = pci_read_config_byte(pdev, ET1310_PCI_MAX_PYLD, &maxPayload); - if (result != PCIBIOS_SUCCESSFUL) { + if (pci_read_config_byte(pdev, ET1310_PCI_MAX_PYLD, &max_payload)) { dev_err(&pdev->dev, "Could not read PCI config space for Max Payload Size\n"); return -EIO; } /* Program the Ack/Nak latency and replay timers */ - maxPayload &= 0x07; /* Only the lower 3 bits are valid */ + max_payload &= 0x07; /* Only the lower 3 bits are valid */ - if (maxPayload < 2) { - const uint16_t AckNak[2] = { 0x76, 0xD0 }; - const uint16_t Replay[2] = { 0x1E0, 0x2ED }; + if (max_payload < 2) { + static const u16 AckNak[2] = { 0x76, 0xD0 }; + static const u16 Replay[2] = { 0x1E0, 0x2ED }; - result = pci_write_config_word(pdev, ET1310_PCI_ACK_NACK, - AckNak[maxPayload]); - if (result != PCIBIOS_SUCCESSFUL) { + if (pci_write_config_word(pdev, ET1310_PCI_ACK_NACK, + AckNak[max_payload])) { dev_err(&pdev->dev, "Could not write PCI config space for ACK/NAK\n"); return -EIO; } - - result = pci_write_config_word(pdev, ET1310_PCI_REPLAY, - Replay[maxPayload]); - if (result != PCIBIOS_SUCCESSFUL) { + if (pci_write_config_word(pdev, ET1310_PCI_REPLAY, + Replay[max_payload])) { dev_err(&pdev->dev, "Could not write PCI config space for Replay Timer\n"); return -EIO; @@ -263,16 +212,14 @@ int et131x_find_adapter(struct et131x_adapter *adapter, struct pci_dev *pdev) /* l0s and l1 latency timers. We are using default values. * Representing 001 for L0s and 010 for L1 */ - result = pci_write_config_byte(pdev, ET1310_PCI_L0L1LATENCY, 0x11); - if (result != PCIBIOS_SUCCESSFUL) { + if (pci_write_config_byte(pdev, ET1310_PCI_L0L1LATENCY, 0x11)) { dev_err(&pdev->dev, "Could not write PCI config space for Latency Timers\n"); return -EIO; } /* Change the max read size to 2k */ - result = pci_read_config_byte(pdev, 0x51, &read_size_reg); - if (result != PCIBIOS_SUCCESSFUL) { + if (pci_read_config_byte(pdev, 0x51, &read_size_reg)) { dev_err(&pdev->dev, "Could not read PCI config space for Max read size\n"); return -EIO; @@ -281,8 +228,7 @@ int et131x_find_adapter(struct et131x_adapter *adapter, struct pci_dev *pdev) read_size_reg &= 0x8f; read_size_reg |= 0x40; - result = pci_write_config_byte(pdev, 0x51, read_size_reg); - if (result != PCIBIOS_SUCCESSFUL) { + if (pci_write_config_byte(pdev, 0x51, read_size_reg)) { dev_err(&pdev->dev, "Could not write PCI config space for Max read size\n"); return -EIO; @@ -291,19 +237,19 @@ int et131x_find_adapter(struct et131x_adapter *adapter, struct pci_dev *pdev) /* Get MAC address from config space if an eeprom exists, otherwise * the MAC address there will not be valid */ - if (adapter->has_eeprom) { - int i; - - for (i = 0; i < ETH_ALEN; i++) { - result = pci_read_config_byte( - pdev, ET1310_PCI_MAC_ADDRESS + i, - adapter->PermanentAddress + i); - if (result != PCIBIOS_SUCCESSFUL) { - dev_err(&pdev->dev, ";Could not read PCI config space for MAC address\n"); - return -EIO; - } + if (!adapter->has_eeprom) { + et131x_hwaddr_init(adapter); + return 0; + } + + for (i = 0; i < ETH_ALEN; i++) { + if (pci_read_config_byte(pdev, ET1310_PCI_MAC_ADDRESS + i, + adapter->PermanentAddress + i)) { + dev_err(&pdev->dev, "Could not read PCI config space for MAC address\n"); + return -EIO; } } + memcpy(adapter->CurrentAddress, adapter->PermanentAddress, ETH_ALEN); return 0; } @@ -383,52 +329,34 @@ void ConfigGlobalRegs(struct et131x_adapter *etdev) { struct _GLOBAL_t __iomem *regs = &etdev->regs->global; - if (etdev->RegistryPhyLoopbk == false) { - if (etdev->RegistryJumboPacket < 2048) { - /* Tx / RxDMA and Tx/Rx MAC interfaces have a 1k word - * block of RAM that the driver can split between Tx - * and Rx as it desires. Our default is to split it - * 50/50: - */ - writel(0, ®s->rxq_start_addr); - writel(PARM_RX_MEM_END_DEF, ®s->rxq_end_addr); - writel(PARM_RX_MEM_END_DEF + 1, ®s->txq_start_addr); - writel(INTERNAL_MEM_SIZE - 1, ®s->txq_end_addr); - } else if (etdev->RegistryJumboPacket < 8192) { - /* For jumbo packets > 2k but < 8k, split 50-50. */ - writel(0, ®s->rxq_start_addr); - writel(INTERNAL_MEM_RX_OFFSET, ®s->rxq_end_addr); - writel(INTERNAL_MEM_RX_OFFSET + 1, ®s->txq_start_addr); - writel(INTERNAL_MEM_SIZE - 1, ®s->txq_end_addr); - } else { - /* 9216 is the only packet size greater than 8k that - * is available. The Tx buffer has to be big enough - * for one whole packet on the Tx side. We'll make - * the Tx 9408, and give the rest to Rx - */ - writel(0x0000, ®s->rxq_start_addr); - writel(0x01b3, ®s->rxq_end_addr); - writel(0x01b4, ®s->txq_start_addr); - writel(INTERNAL_MEM_SIZE - 1,®s->txq_end_addr); - } + writel(0, ®s->rxq_start_addr); + writel(INTERNAL_MEM_SIZE - 1, ®s->txq_end_addr); - /* Initialize the loopback register. Disable all loopbacks. */ - writel(0, ®s->loopback); + if (etdev->RegistryJumboPacket < 2048) { + /* Tx / RxDMA and Tx/Rx MAC interfaces have a 1k word + * block of RAM that the driver can split between Tx + * and Rx as it desires. Our default is to split it + * 50/50: + */ + writel(PARM_RX_MEM_END_DEF, ®s->rxq_end_addr); + writel(PARM_RX_MEM_END_DEF + 1, ®s->txq_start_addr); + } else if (etdev->RegistryJumboPacket < 8192) { + /* For jumbo packets > 2k but < 8k, split 50-50. */ + writel(INTERNAL_MEM_RX_OFFSET, ®s->rxq_end_addr); + writel(INTERNAL_MEM_RX_OFFSET + 1, ®s->txq_start_addr); } else { - /* For PHY Line loopback, the memory is configured as if Tx - * and Rx both have all the memory. This is because the - * RxMAC will write data into the space, and the TxMAC will - * read it out. + /* 9216 is the only packet size greater than 8k that + * is available. The Tx buffer has to be big enough + * for one whole packet on the Tx side. We'll make + * the Tx 9408, and give the rest to Rx */ - writel(0, ®s->rxq_start_addr); - writel(INTERNAL_MEM_SIZE - 1, ®s->rxq_end_addr); - writel(0, ®s->txq_start_addr); - writel(INTERNAL_MEM_SIZE - 1, ®s->txq_end_addr); - - /* Initialize the loopback register (MAC loopback). */ - writel(ET_LOOP_MAC, ®s->loopback); + writel(0x01b3, ®s->rxq_end_addr); + writel(0x01b4, ®s->txq_start_addr); } + /* Initialize the loopback register. Disable all loopbacks. */ + writel(0, ®s->loopback); + /* MSI Register */ writel(0, ®s->msi_config); @@ -498,57 +426,18 @@ int et131x_adapter_setup(struct et131x_adapter *etdev) } /** - * et131x_setup_hardware_properties - set up the MAC Address on the ET1310 - * @adapter: pointer to our private adapter structure - */ -void et131x_setup_hardware_properties(struct et131x_adapter *adapter) -{ - /* If have our default mac from registry and no mac address from - * EEPROM then we need to generate the last octet and set it on the - * device - */ - if (adapter->PermanentAddress[0] == 0x00 && - adapter->PermanentAddress[1] == 0x00 && - adapter->PermanentAddress[2] == 0x00 && - adapter->PermanentAddress[3] == 0x00 && - adapter->PermanentAddress[4] == 0x00 && - adapter->PermanentAddress[5] == 0x00) { - /* - * We need to randomly generate the last octet so we - * decrease our chances of setting the mac address to - * same as another one of our cards in the system - */ - get_random_bytes(&adapter->CurrentAddress[5], 1); - /* - * We have the default value in the register we are - * working with so we need to copy the current - * address into the permanent address - */ - memcpy(adapter->PermanentAddress, - adapter->CurrentAddress, ETH_ALEN); - } else { - /* We do not have an override address, so set the - * current address to the permanent address and add - * it to the device - */ - memcpy(adapter->CurrentAddress, - adapter->PermanentAddress, ETH_ALEN); - } -} - -/** * et131x_soft_reset - Issue a soft reset to the hardware, complete for ET1310 * @adapter: pointer to our private adapter structure */ void et131x_soft_reset(struct et131x_adapter *adapter) { /* Disable MAC Core */ - writel(0xc00f0000, &adapter->regs->mac.cfg1.value); + writel(0xc00f0000, &adapter->regs->mac.cfg1); /* Set everything to a reset value */ writel(0x7F, &adapter->regs->global.sw_reset); - writel(0x000f0000, &adapter->regs->mac.cfg1.value); - writel(0x00000000, &adapter->regs->mac.cfg1.value); + writel(0x000f0000, &adapter->regs->mac.cfg1); + writel(0x00000000, &adapter->regs->mac.cfg1); } /** @@ -588,36 +477,32 @@ void et131x_align_allocated_memory(struct et131x_adapter *adapter, */ int et131x_adapter_memory_alloc(struct et131x_adapter *adapter) { - int status = 0; - - do { - /* Allocate memory for the Tx Ring */ - status = et131x_tx_dma_memory_alloc(adapter); - if (status != 0) { - dev_err(&adapter->pdev->dev, - "et131x_tx_dma_memory_alloc FAILED\n"); - break; - } + int status; - /* Receive buffer memory allocation */ - status = et131x_rx_dma_memory_alloc(adapter); - if (status != 0) { - dev_err(&adapter->pdev->dev, - "et131x_rx_dma_memory_alloc FAILED\n"); - et131x_tx_dma_memory_free(adapter); - break; - } + /* Allocate memory for the Tx Ring */ + status = et131x_tx_dma_memory_alloc(adapter); + if (status != 0) { + dev_err(&adapter->pdev->dev, + "et131x_tx_dma_memory_alloc FAILED\n"); + return status; + } + /* Receive buffer memory allocation */ + status = et131x_rx_dma_memory_alloc(adapter); + if (status != 0) { + dev_err(&adapter->pdev->dev, + "et131x_rx_dma_memory_alloc FAILED\n"); + et131x_tx_dma_memory_free(adapter); + return status; + } - /* Init receive data structures */ - status = et131x_init_recv(adapter); - if (status != 0) { - dev_err(&adapter->pdev->dev, - "et131x_init_recv FAILED\n"); - et131x_tx_dma_memory_free(adapter); - et131x_rx_dma_memory_free(adapter); - break; - } - } while (0); + /* Init receive data structures */ + status = et131x_init_recv(adapter); + if (status != 0) { + dev_err(&adapter->pdev->dev, + "et131x_init_recv FAILED\n"); + et131x_tx_dma_memory_free(adapter); + et131x_rx_dma_memory_free(adapter); + } return status; } @@ -632,22 +517,50 @@ void et131x_adapter_memory_free(struct et131x_adapter *adapter) et131x_rx_dma_memory_free(adapter); } + + /** - * et131x_config_parse + * et131x_adapter_init * @etdev: pointer to the private adapter struct + * @pdev: pointer to the PCI device * - * Parses a configuration from some location (module parameters, for example) - * into the private adapter struct. This really has no sensible analogy in - * Linux as sysfs parameters are dynamic. Several things that were hee could - * go into sysfs, but other stuff like speed handling is part of the mii - * interfaces/ethtool. + * Initialize the data structures for the et131x_adapter object and link + * them together with the platform provided device structures. */ -void et131x_config_parse(struct et131x_adapter *etdev) + + +static struct et131x_adapter *et131x_adapter_init(struct net_device *netdev, + struct pci_dev *pdev) { static const u8 default_mac[] = { 0x00, 0x05, 0x3d, 0x00, 0x02, 0x00 }; static const u8 duplex[] = { 0, 1, 2, 1, 2, 2 }; static const u16 speed[] = { 0, 10, 10, 100, 100, 1000 }; + struct et131x_adapter *etdev; + + /* Setup the fundamental net_device and private adapter structure elements */ + SET_NETDEV_DEV(netdev, &pdev->dev); + + /* Allocate private adapter struct and copy in relevant information */ + etdev = netdev_priv(netdev); + etdev->pdev = pci_dev_get(pdev); + etdev->netdev = netdev; + + /* Do the same for the netdev struct */ + netdev->irq = pdev->irq; + netdev->base_addr = pci_resource_start(pdev, 0); + + /* Initialize spinlocks here */ + spin_lock_init(&etdev->Lock); + spin_lock_init(&etdev->TCBSendQLock); + spin_lock_init(&etdev->TCBReadyQLock); + spin_lock_init(&etdev->SendHWLock); + spin_lock_init(&etdev->RcvLock); + spin_lock_init(&etdev->RcvPendLock); + spin_lock_init(&etdev->FbrLock); + spin_lock_init(&etdev->PHYLock); + + /* Parse configuration parameters into the private adapter struct */ if (et131x_speed_set) dev_info(&etdev->pdev->dev, "Speed set manually to : %d \n", et131x_speed_set); @@ -655,8 +568,6 @@ void et131x_config_parse(struct et131x_adapter *etdev) etdev->SpeedDuplex = et131x_speed_set; etdev->RegistryJumboPacket = 1514; /* 1514-9216 */ - etdev->RegistryNMIDisable = et131x_nmi_disable; - /* Set the MAC address to a default */ memcpy(etdev->CurrentAddress, default_mac, ETH_ALEN); @@ -674,40 +585,10 @@ void et131x_config_parse(struct et131x_adapter *etdev) etdev->AiForceSpeed = speed[etdev->SpeedDuplex]; etdev->AiForceDpx = duplex[etdev->SpeedDuplex]; /* Auto FDX */ -} - - -/** - * et131x_pci_remove - * @pdev: a pointer to the device's pci_dev structure - * - * Registered in the pci_driver structure, this function is called when the - * PCI subsystem detects that a PCI device which matches the information - * contained in the pci_device_id table has been removed. - */ - -void __devexit et131x_pci_remove(struct pci_dev *pdev) -{ - struct net_device *netdev; - struct et131x_adapter *adapter; - /* Retrieve the net_device pointer from the pci_dev struct, as well - * as the private adapter struct - */ - netdev = (struct net_device *) pci_get_drvdata(pdev); - adapter = netdev_priv(netdev); - - /* Perform device cleanup */ - unregister_netdev(netdev); - et131x_adapter_memory_free(adapter); - iounmap(adapter->regs); - pci_dev_put(adapter->pdev); - free_netdev(netdev); - pci_release_regions(pdev); - pci_disable_device(pdev); + return etdev; } - /** * et131x_pci_setup - Perform device initialization * @pdev: a pointer to the device's pci_dev structure @@ -721,34 +602,31 @@ void __devexit et131x_pci_remove(struct pci_dev *pdev) * a device insertion routine. */ -int __devinit et131x_pci_setup(struct pci_dev *pdev, +static int __devinit et131x_pci_setup(struct pci_dev *pdev, const struct pci_device_id *ent) { - int result = 0; + int result = -EBUSY; int pm_cap; bool pci_using_dac; - struct net_device *netdev = NULL; - struct et131x_adapter *adapter = NULL; + struct net_device *netdev; + struct et131x_adapter *adapter; /* Enable the device via the PCI subsystem */ - result = pci_enable_device(pdev); - if (result != 0) { - dev_err(&adapter->pdev->dev, + if (pci_enable_device(pdev) != 0) { + dev_err(&pdev->dev, "pci_enable_device() failed\n"); - goto out; + return -EIO; } /* Perform some basic PCI checks */ if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { - dev_err(&adapter->pdev->dev, + dev_err(&pdev->dev, "Can't find PCI device's base address\n"); - result = -ENODEV; - goto out; + goto err_disable; } - result = pci_request_regions(pdev, DRIVER_NAME); - if (result != 0) { - dev_err(&adapter->pdev->dev, + if (pci_request_regions(pdev, DRIVER_NAME)) { + dev_err(&pdev->dev, "Can't get PCI resources\n"); goto err_disable; } @@ -763,27 +641,26 @@ int __devinit et131x_pci_setup(struct pci_dev *pdev, */ pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); if (pm_cap == 0) { - dev_err(&adapter->pdev->dev, + dev_err(&pdev->dev, "Cannot find Power Management capabilities\n"); result = -EIO; goto err_release_res; } /* Check the DMA addressing support of this device */ - if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) { + if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { pci_using_dac = true; - result = - pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL); + result = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); if (result != 0) { dev_err(&pdev->dev, "Unable to obtain 64 bit DMA for consistent allocations\n"); goto err_release_res; } - } else if (!pci_set_dma_mask(pdev, 0xffffffffULL)) { + } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { pci_using_dac = false; } else { - dev_err(&adapter->pdev->dev, + dev_err(&pdev->dev, "No usable DMA addressing method\n"); result = -EIO; goto err_release_res; @@ -792,87 +669,22 @@ int __devinit et131x_pci_setup(struct pci_dev *pdev, /* Allocate netdev and private adapter structs */ netdev = et131x_device_alloc(); if (netdev == NULL) { - dev_err(&adapter->pdev->dev, - "Couldn't alloc netdev struct\n"); + dev_err(&pdev->dev, "Couldn't alloc netdev struct\n"); result = -ENOMEM; goto err_release_res; } - - /* Setup the fundamental net_device and private adapter structure elements */ - SET_NETDEV_DEV(netdev, &pdev->dev); - /* - if (pci_using_dac) { - netdev->features |= NETIF_F_HIGHDMA; - } - */ - - /* - * NOTE - Turn this on when we're ready to deal with SG-DMA - * - * NOTE: According to "Linux Device Drivers", 3rd ed, Rubini et al, - * if checksumming is not performed in HW, then the kernel will not - * use SG. - * From pp 510-511: - * - * "Note that the kernel does not perform scatter/gather I/O to your - * device if it does not also provide some form of checksumming as - * well. The reason is that, if the kernel has to make a pass over a - * fragmented ("nonlinear") packet to calculate the checksum, it - * might as well copy the data and coalesce the packet at the same - * time." - * - * This has been verified by setting the flags below and still not - * receiving a scattered buffer from the network stack, so leave it - * off until checksums are calculated in HW. - */ - /* netdev->features |= NETIF_F_SG; */ - /* netdev->features |= NETIF_F_NO_CSUM; */ - /* netdev->features |= NETIF_F_LLTX; */ - - /* Allocate private adapter struct and copy in relevant information */ - adapter = netdev_priv(netdev); - adapter->pdev = pci_dev_get(pdev); - adapter->netdev = netdev; - - /* Do the same for the netdev struct */ - netdev->irq = pdev->irq; - netdev->base_addr = pdev->resource[0].start; - - /* Initialize spinlocks here */ - spin_lock_init(&adapter->Lock); - spin_lock_init(&adapter->TCBSendQLock); - spin_lock_init(&adapter->TCBReadyQLock); - spin_lock_init(&adapter->SendHWLock); - spin_lock_init(&adapter->SendWaitLock); - spin_lock_init(&adapter->RcvLock); - spin_lock_init(&adapter->RcvPendLock); - spin_lock_init(&adapter->FbrLock); - spin_lock_init(&adapter->PHYLock); - - /* Parse configuration parameters into the private adapter struct */ - et131x_config_parse(adapter); - - /* Find the physical adapter - * - * NOTE: This is the equivalent of the MpFindAdapter() routine; can we - * lump it's init with the device specific init below into a - * single init function? - */ - /* while (et131x_find_adapter(adapter, pdev) != 0); */ - et131x_find_adapter(adapter, pdev); + adapter = et131x_adapter_init(netdev, pdev); + /* Initialise the PCI setup for the device */ + et131x_pci_init(adapter, pdev); /* Map the bus-relative registers to system virtual memory */ - - adapter->regs = ioremap_nocache(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); + adapter->regs = pci_ioremap_bar(pdev, 0); if (adapter->regs == NULL) { dev_err(&pdev->dev, "Cannot map device registers\n"); result = -ENOMEM; goto err_free_dev; } - /* Perform device-specific initialization here (See code below) */ - /* If Phy COMA mode was enabled when we went down, disable it here. */ writel(ET_PMCSR_INIT, &adapter->regs->global.pm_csr); @@ -892,20 +704,12 @@ int __devinit et131x_pci_setup(struct pci_dev *pdev, /* Init send data structures */ et131x_init_send(adapter); - /* Register the interrupt - * - * NOTE - This is being done in the open routine, where most other - * Linux drivers setup IRQ handlers. Make sure device - * interrupts are not turned on before the IRQ is registered!! - * - * What we will do here is setup the task structure for the - * ISR's deferred handler + /* + * Set up the task structure for the ISR's deferred handler */ INIT_WORK(&adapter->task, et131x_isr_handler); - /* Determine MAC Address, and copy into the net_device struct */ - et131x_setup_hardware_properties(adapter); - + /* Copy address into the net_device struct */ memcpy(netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN); /* Setup et1310 as per the documentation */ @@ -944,10 +748,7 @@ int __devinit et131x_pci_setup(struct pci_dev *pdev, * been initialized, just in case it needs to be quickly restored. */ pci_set_drvdata(pdev, netdev); - pci_save_state(adapter->pdev); - -out: return result; err_mem_free: @@ -961,7 +762,37 @@ err_release_res: pci_release_regions(pdev); err_disable: pci_disable_device(pdev); - goto out; + return result; +} + +/** + * et131x_pci_remove + * @pdev: a pointer to the device's pci_dev structure + * + * Registered in the pci_driver structure, this function is called when the + * PCI subsystem detects that a PCI device which matches the information + * contained in the pci_device_id table has been removed. + */ + +static void __devexit et131x_pci_remove(struct pci_dev *pdev) +{ + struct net_device *netdev; + struct et131x_adapter *adapter; + + /* Retrieve the net_device pointer from the pci_dev struct, as well + * as the private adapter struct + */ + netdev = (struct net_device *) pci_get_drvdata(pdev); + adapter = netdev_priv(netdev); + + /* Perform device cleanup */ + unregister_netdev(netdev); + et131x_adapter_memory_free(adapter); + iounmap(adapter->regs); + pci_dev_put(adapter->pdev); + free_netdev(netdev); + pci_release_regions(pdev); + pci_disable_device(pdev); } static struct pci_device_id et131x_pci_table[] __devinitdata = { @@ -989,7 +820,7 @@ static struct pci_driver et131x_driver = { * * Returns 0 on success, errno on failure (as defined in errno.h) */ -static int et131x_init_module(void) +static int __init et131x_init_module(void) { if (et131x_speed_set < PARM_SPEED_DUPLEX_MIN || et131x_speed_set > PARM_SPEED_DUPLEX_MAX) { @@ -1002,7 +833,7 @@ static int et131x_init_module(void) /** * et131x_cleanup_module - The entry point called on driver cleanup */ -static void et131x_cleanup_module(void) +static void __exit et131x_cleanup_module(void) { pci_unregister_driver(&et131x_driver); } @@ -1010,7 +841,6 @@ static void et131x_cleanup_module(void) module_init(et131x_init_module); module_exit(et131x_cleanup_module); - /* Modinfo parameters (filled out using defines from et131x_version.h) */ MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_INFO); diff --git a/drivers/staging/et131x/et131x_initpci.h b/drivers/staging/et131x/et131x_initpci.h index 8131d6a65c2a..7269569a874b 100644 --- a/drivers/staging/et131x/et131x_initpci.h +++ b/drivers/staging/et131x/et131x_initpci.h @@ -67,7 +67,7 @@ void et131x_align_allocated_memory(struct et131x_adapter *adapter, int et131x_adapter_setup(struct et131x_adapter *adapter); int et131x_adapter_memory_alloc(struct et131x_adapter *adapter); void et131x_adapter_memory_free(struct et131x_adapter *adapter); -void et131x_setup_hardware_properties(struct et131x_adapter *adapter); +void et131x_hwaddr_init(struct et131x_adapter *adapter); void et131x_soft_reset(struct et131x_adapter *adapter); #endif /* __ET131X_INITPCI_H__ */ diff --git a/drivers/staging/et131x/et131x_isr.c b/drivers/staging/et131x/et131x_isr.c index f80189d7cb6d..ccd9bc22e185 100644 --- a/drivers/staging/et131x/et131x_isr.c +++ b/drivers/staging/et131x/et131x_isr.c @@ -109,9 +109,6 @@ void et131x_enable_interrupts(struct et131x_adapter *adapter) else mask = INT_MASK_ENABLE_NO_FLOW; - if (adapter->DriverNoPhyAccess) - mask |= ET_INTR_PHY; - adapter->CachedMaskValue = mask; writel(mask, &adapter->regs->global.int_mask); } @@ -182,15 +179,15 @@ irqreturn_t et131x_isr(int irq, void *dev_id) /* This is our interrupt, so process accordingly */ if (status & ET_INTR_WATCHDOG) { - PMP_TCB pMpTcb = adapter->TxRing.CurrSendHead; + struct tcb *tcb = adapter->tx_ring.send_head; - if (pMpTcb) - if (++pMpTcb->PacketStaleCount > 1) + if (tcb) + if (++tcb->stale > 1) status |= ET_INTR_TXDMA_ISR; if (adapter->RxRing.UnfinishedReceives) status |= ET_INTR_RXDMA_XFR_DONE; - else if (pMpTcb == NULL) + else if (tcb == NULL) writel(0, &adapter->regs->global.watchdog_timer); status &= ~ET_INTR_WATCHDOG; @@ -400,8 +397,7 @@ void et131x_isr_handler(struct work_struct *work) /* Let's move on to the TxMac */ if (status & ET_INTR_TXMAC) { - etdev->TxRing.TxMacErr.value = - readl(&iomem->txmac.err.value); + u32 err = readl(&iomem->txmac.err.value); /* * When any of the errors occur and TXMAC generates @@ -415,7 +411,7 @@ void et131x_isr_handler(struct work_struct *work) */ dev_warn(&etdev->pdev->dev, "TXMAC interrupt, error 0x%08x\n", - etdev->TxRing.TxMacErr.value); + err); /* If we are debugging, we want to see this error, * otherwise we just want the device to be reset and diff --git a/drivers/staging/et131x/et131x_netdev.c b/drivers/staging/et131x/et131x_netdev.c index 8c7612f63f91..24d97b4fa6fb 100644 --- a/drivers/staging/et131x/et131x_netdev.c +++ b/drivers/staging/et131x/et131x_netdev.c @@ -519,7 +519,7 @@ int et131x_tx(struct sk_buff *skb, struct net_device *netdev) void et131x_tx_timeout(struct net_device *netdev) { struct et131x_adapter *etdev = netdev_priv(netdev); - PMP_TCB pMpTcb; + struct tcb *tcb; unsigned long flags; /* Just skip this part if the adapter is doing link detection */ @@ -541,28 +541,19 @@ void et131x_tx_timeout(struct net_device *netdev) /* Is send stuck? */ spin_lock_irqsave(&etdev->TCBSendQLock, flags); - pMpTcb = etdev->TxRing.CurrSendHead; + tcb = etdev->tx_ring.send_head; - if (pMpTcb != NULL) { - pMpTcb->Count++; - - if (pMpTcb->Count > NIC_SEND_HANG_THRESHOLD) { - TX_DESC_ENTRY_t StuckDescriptors[10]; - - if (INDEX10(pMpTcb->WrIndex) > 7) { - memcpy(StuckDescriptors, - etdev->TxRing.pTxDescRingVa + - INDEX10(pMpTcb->WrIndex) - 6, - sizeof(TX_DESC_ENTRY_t) * 10); - } + if (tcb != NULL) { + tcb->count++; + if (tcb->count > NIC_SEND_HANG_THRESHOLD) { spin_unlock_irqrestore(&etdev->TCBSendQLock, flags); dev_warn(&etdev->pdev->dev, - "Send stuck - reset. pMpTcb->WrIndex %x, Flags 0x%08x\n", - pMpTcb->WrIndex, - pMpTcb->Flags); + "Send stuck - reset. tcb->WrIndex %x, Flags 0x%08x\n", + tcb->index, + tcb->flags); et131x_close(netdev); et131x_open(netdev); @@ -622,7 +613,7 @@ int et131x_change_mtu(struct net_device *netdev, int new_mtu) et131x_init_send(adapter); - et131x_setup_hardware_properties(adapter); + et131x_hwaddr_init(adapter); memcpy(netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN); /* Init the device with the new settings */ @@ -709,9 +700,7 @@ int et131x_set_mac_addr(struct net_device *netdev, void *new_mac) et131x_init_send(adapter); - et131x_setup_hardware_properties(adapter); - /* memcpy( netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN ); */ - /* blux: no, do not override our nice address */ + et131x_hwaddr_init(adapter); /* Init the device with the new settings */ et131x_adapter_setup(adapter); |