00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 FILE_LICENCE ( GPL2_ONLY );
00028
00029 #include <stdint.h>
00030 #include <errno.h>
00031 #include <stdio.h>
00032 #include <unistd.h>
00033 #include <gpxe/ethernet.h>
00034 #include <gpxe/if_ether.h>
00035 #include <gpxe/iobuf.h>
00036 #include <gpxe/malloc.h>
00037 #include <gpxe/pci.h>
00038 #include <byteswap.h>
00039 #include <mii.h>
00040
00041 #include "sky2.h"
00042
00043 #define DRV_NAME "sky2"
00044 #define DRV_VERSION "1.22"
00045 #define PFX DRV_NAME " "
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 #define RX_LE_SIZE 128
00061 #define RX_LE_BYTES (RX_LE_SIZE*sizeof(struct sky2_rx_le))
00062 #define RX_RING_ALIGN 4096
00063 #define RX_PENDING (RX_LE_SIZE/6 - 2)
00064
00065 #define TX_RING_SIZE 128
00066 #define TX_PENDING (TX_RING_SIZE - 1)
00067 #define TX_RING_ALIGN 4096
00068 #define MAX_SKB_TX_LE 4
00069
00070 #define STATUS_RING_SIZE 512
00071 #define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le))
00072 #define STATUS_RING_ALIGN 4096
00073 #define PHY_RETRIES 1000
00074
00075 #define SKY2_EEPROM_MAGIC 0x9955aabb
00076
00077
00078 #define RING_NEXT(x,s) (((x)+1) & ((s)-1))
00079
00080 static struct pci_device_id sky2_id_table[] = {
00081 PCI_ROM(0x1148, 0x9000, "sk9sxx", "Syskonnect SK-9Sxx", 0),
00082 PCI_ROM(0x1148, 0x9e00, "sk9exx", "Syskonnect SK-9Exx", 0),
00083 PCI_ROM(0x1186, 0x4b00, "dge560t", "D-Link DGE-560T", 0),
00084 PCI_ROM(0x1186, 0x4001, "dge550sx", "D-Link DGE-550SX", 0),
00085 PCI_ROM(0x1186, 0x4b02, "dge560sx", "D-Link DGE-560SX", 0),
00086 PCI_ROM(0x1186, 0x4b03, "dge550t", "D-Link DGE-550T", 0),
00087 PCI_ROM(0x11ab, 0x4340, "m88e8021", "Marvell 88E8021", 0),
00088 PCI_ROM(0x11ab, 0x4341, "m88e8022", "Marvell 88E8022", 0),
00089 PCI_ROM(0x11ab, 0x4342, "m88e8061", "Marvell 88E8061", 0),
00090 PCI_ROM(0x11ab, 0x4343, "m88e8062", "Marvell 88E8062", 0),
00091 PCI_ROM(0x11ab, 0x4344, "m88e8021b", "Marvell 88E8021", 0),
00092 PCI_ROM(0x11ab, 0x4345, "m88e8022b", "Marvell 88E8022", 0),
00093 PCI_ROM(0x11ab, 0x4346, "m88e8061b", "Marvell 88E8061", 0),
00094 PCI_ROM(0x11ab, 0x4347, "m88e8062b", "Marvell 88E8062", 0),
00095 PCI_ROM(0x11ab, 0x4350, "m88e8035", "Marvell 88E8035", 0),
00096 PCI_ROM(0x11ab, 0x4351, "m88e8036", "Marvell 88E8036", 0),
00097 PCI_ROM(0x11ab, 0x4352, "m88e8038", "Marvell 88E8038", 0),
00098 PCI_ROM(0x11ab, 0x4353, "m88e8039", "Marvell 88E8039", 0),
00099 PCI_ROM(0x11ab, 0x4354, "m88e8040", "Marvell 88E8040", 0),
00100 PCI_ROM(0x11ab, 0x4355, "m88e8040t", "Marvell 88E8040T", 0),
00101 PCI_ROM(0x11ab, 0x4356, "m88ec033", "Marvel 88EC033", 0),
00102 PCI_ROM(0x11ab, 0x4357, "m88e8042", "Marvell 88E8042", 0),
00103 PCI_ROM(0x11ab, 0x435a, "m88e8048", "Marvell 88E8048", 0),
00104 PCI_ROM(0x11ab, 0x4360, "m88e8052", "Marvell 88E8052", 0),
00105 PCI_ROM(0x11ab, 0x4361, "m88e8050", "Marvell 88E8050", 0),
00106 PCI_ROM(0x11ab, 0x4362, "m88e8053", "Marvell 88E8053", 0),
00107 PCI_ROM(0x11ab, 0x4363, "m88e8055", "Marvell 88E8055", 0),
00108 PCI_ROM(0x11ab, 0x4364, "m88e8056", "Marvell 88E8056", 0),
00109 PCI_ROM(0x11ab, 0x4365, "m88e8070", "Marvell 88E8070", 0),
00110 PCI_ROM(0x11ab, 0x4366, "m88ec036", "Marvell 88EC036", 0),
00111 PCI_ROM(0x11ab, 0x4367, "m88ec032", "Marvell 88EC032", 0),
00112 PCI_ROM(0x11ab, 0x4368, "m88ec034", "Marvell 88EC034", 0),
00113 PCI_ROM(0x11ab, 0x4369, "m88ec042", "Marvell 88EC042", 0),
00114 PCI_ROM(0x11ab, 0x436a, "m88e8058", "Marvell 88E8058", 0),
00115 PCI_ROM(0x11ab, 0x436b, "m88e8071", "Marvell 88E8071", 0),
00116 PCI_ROM(0x11ab, 0x436c, "m88e8072", "Marvell 88E8072", 0),
00117 PCI_ROM(0x11ab, 0x436d, "m88e8055b", "Marvell 88E8055", 0),
00118 PCI_ROM(0x11ab, 0x4370, "m88e8075", "Marvell 88E8075", 0),
00119 PCI_ROM(0x11ab, 0x4380, "m88e8057", "Marvell 88E8057", 0)
00120 };
00121
00122
00123 static const unsigned txqaddr[] = { Q_XA1, Q_XA2 };
00124 static const unsigned rxqaddr[] = { Q_R1, Q_R2 };
00125 static const u32 portirq_msk[] = { Y2_IS_PORT_1, Y2_IS_PORT_2 };
00126
00127 static void sky2_set_multicast(struct net_device *dev);
00128
00129
00130 static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val)
00131 {
00132 int i;
00133
00134 gma_write16(hw, port, GM_SMI_DATA, val);
00135 gma_write16(hw, port, GM_SMI_CTRL,
00136 GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg));
00137
00138 for (i = 0; i < PHY_RETRIES; i++) {
00139 u16 ctrl = gma_read16(hw, port, GM_SMI_CTRL);
00140 if (ctrl == 0xffff)
00141 goto io_error;
00142
00143 if (!(ctrl & GM_SMI_CT_BUSY))
00144 return 0;
00145
00146 udelay(10);
00147 }
00148
00149 DBG(PFX "%s: phy write timeout\n", hw->dev[port]->name);
00150 return -ETIMEDOUT;
00151
00152 io_error:
00153 DBG(PFX "%s: phy I/O error\n", hw->dev[port]->name);
00154 return -EIO;
00155 }
00156
00157 static int __gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg, u16 *val)
00158 {
00159 int i;
00160
00161 gma_write16(hw, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(PHY_ADDR_MARV)
00162 | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
00163
00164 for (i = 0; i < PHY_RETRIES; i++) {
00165 u16 ctrl = gma_read16(hw, port, GM_SMI_CTRL);
00166 if (ctrl == 0xffff)
00167 goto io_error;
00168
00169 if (ctrl & GM_SMI_CT_RD_VAL) {
00170 *val = gma_read16(hw, port, GM_SMI_DATA);
00171 return 0;
00172 }
00173
00174 udelay(10);
00175 }
00176
00177 DBG(PFX "%s: phy read timeout\n", hw->dev[port]->name);
00178 return -ETIMEDOUT;
00179 io_error:
00180 DBG(PFX "%s: phy I/O error\n", hw->dev[port]->name);
00181 return -EIO;
00182 }
00183
00184 static inline u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg)
00185 {
00186 u16 v = 0;
00187 __gm_phy_read(hw, port, reg, &v);
00188 return v;
00189 }
00190
00191
00192 static void sky2_power_on(struct sky2_hw *hw)
00193 {
00194
00195 sky2_write8(hw, B0_POWER_CTRL,
00196 PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON);
00197
00198
00199 sky2_write32(hw, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS);
00200
00201 if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
00202
00203 sky2_write8(hw, B2_Y2_CLK_GATE,
00204 Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS |
00205 Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS |
00206 Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS);
00207 else
00208 sky2_write8(hw, B2_Y2_CLK_GATE, 0);
00209
00210 if (hw->flags & SKY2_HW_ADV_POWER_CTL) {
00211 u32 reg;
00212
00213 sky2_pci_write32(hw, PCI_DEV_REG3, 0);
00214
00215 reg = sky2_pci_read32(hw, PCI_DEV_REG4);
00216
00217 reg &= P_ASPM_CONTROL_MSK;
00218 sky2_pci_write32(hw, PCI_DEV_REG4, reg);
00219
00220 reg = sky2_pci_read32(hw, PCI_DEV_REG5);
00221
00222 reg &= P_CTL_TIM_VMAIN_AV_MSK;
00223 sky2_pci_write32(hw, PCI_DEV_REG5, reg);
00224
00225 sky2_pci_write32(hw, PCI_CFG_REG_1, 0);
00226
00227
00228 reg = sky2_read32(hw, B2_GP_IO);
00229 reg |= GLB_GPIO_STAT_RACE_DIS;
00230 sky2_write32(hw, B2_GP_IO, reg);
00231
00232 sky2_read32(hw, B2_GP_IO);
00233 }
00234 }
00235
00236 static void sky2_power_aux(struct sky2_hw *hw)
00237 {
00238 if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
00239 sky2_write8(hw, B2_Y2_CLK_GATE, 0);
00240 else
00241
00242 sky2_write8(hw, B2_Y2_CLK_GATE,
00243 Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS |
00244 Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS |
00245 Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS);
00246
00247
00248 if (sky2_read16(hw, B0_CTST) & Y2_VAUX_AVAIL)
00249 sky2_write8(hw, B0_POWER_CTRL,
00250 (PC_VAUX_ENA | PC_VCC_ENA |
00251 PC_VAUX_ON | PC_VCC_OFF));
00252 }
00253
00254 static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port)
00255 {
00256 u16 reg;
00257
00258
00259 sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
00260
00261 gma_write16(hw, port, GM_MC_ADDR_H1, 0);
00262 gma_write16(hw, port, GM_MC_ADDR_H2, 0);
00263 gma_write16(hw, port, GM_MC_ADDR_H3, 0);
00264 gma_write16(hw, port, GM_MC_ADDR_H4, 0);
00265
00266 reg = gma_read16(hw, port, GM_RX_CTRL);
00267 reg |= GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA;
00268 gma_write16(hw, port, GM_RX_CTRL, reg);
00269 }
00270
00271
00272 static const u16 copper_fc_adv[] = {
00273 [FC_NONE] = 0,
00274 [FC_TX] = PHY_M_AN_ASP,
00275 [FC_RX] = PHY_M_AN_PC,
00276 [FC_BOTH] = PHY_M_AN_PC | PHY_M_AN_ASP,
00277 };
00278
00279
00280 static const u16 fiber_fc_adv[] = {
00281 [FC_NONE] = PHY_M_P_NO_PAUSE_X,
00282 [FC_TX] = PHY_M_P_ASYM_MD_X,
00283 [FC_RX] = PHY_M_P_SYM_MD_X,
00284 [FC_BOTH] = PHY_M_P_BOTH_MD_X,
00285 };
00286
00287
00288 static const u16 gm_fc_disable[] = {
00289 [FC_NONE] = GM_GPCR_FC_RX_DIS | GM_GPCR_FC_TX_DIS,
00290 [FC_TX] = GM_GPCR_FC_RX_DIS,
00291 [FC_RX] = GM_GPCR_FC_TX_DIS,
00292 [FC_BOTH] = 0,
00293 };
00294
00295
00296 static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
00297 {
00298 struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
00299 u16 ctrl, ct1000, adv, pg, ledctrl, ledover, reg;
00300
00301 if (sky2->autoneg == AUTONEG_ENABLE &&
00302 !(hw->flags & SKY2_HW_NEWER_PHY)) {
00303 u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
00304
00305 ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
00306 PHY_M_EC_MAC_S_MSK);
00307 ectrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ);
00308
00309
00310 if (hw->chip_id == CHIP_ID_YUKON_EC)
00311
00312 ectrl |= PHY_M_EC_DSC_2(2) | PHY_M_EC_DOWN_S_ENA;
00313 else
00314
00315 ectrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);
00316
00317 gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl);
00318 }
00319
00320 ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
00321 if (sky2_is_copper(hw)) {
00322 if (!(hw->flags & SKY2_HW_GIGABIT)) {
00323
00324 ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO) >> 1;
00325
00326 if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
00327 hw->chip_rev == CHIP_REV_YU_FE2_A0) {
00328 u16 spec;
00329
00330
00331 spec = gm_phy_read(hw, port, PHY_MARV_FE_SPEC_2);
00332 spec |= PHY_M_FESC_SEL_CL_A;
00333 gm_phy_write(hw, port, PHY_MARV_FE_SPEC_2, spec);
00334 }
00335 } else {
00336
00337 ctrl &= ~PHY_M_PC_EN_DET_MSK;
00338
00339
00340 ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO);
00341
00342
00343 if (sky2->autoneg == AUTONEG_ENABLE
00344 && (hw->flags & SKY2_HW_NEWER_PHY)) {
00345
00346 ctrl &= ~PHY_M_PC_DSC_MSK;
00347 ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA;
00348 }
00349 }
00350 } else {
00351
00352
00353
00354 ctrl &= ~PHY_M_PC_MDIX_MSK;
00355 }
00356
00357 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
00358
00359
00360 if (hw->chip_id == CHIP_ID_YUKON_XL && (hw->flags & SKY2_HW_FIBRE_PHY)) {
00361 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
00362
00363
00364 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
00365 ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
00366 ctrl &= ~PHY_M_MAC_MD_MSK;
00367 ctrl |= PHY_M_MAC_MODE_SEL(PHY_M_MAC_MD_1000BX);
00368 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
00369
00370 if (hw->pmd_type == 'P') {
00371
00372 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 1);
00373
00374
00375 ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
00376 ctrl |= PHY_M_FIB_SIGD_POL;
00377 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
00378 }
00379
00380 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
00381 }
00382
00383 ctrl = PHY_CT_RESET;
00384 ct1000 = 0;
00385 adv = PHY_AN_CSMA;
00386 reg = 0;
00387
00388 if (sky2->autoneg == AUTONEG_ENABLE) {
00389 if (sky2_is_copper(hw)) {
00390 if (sky2->advertising & ADVERTISED_1000baseT_Full)
00391 ct1000 |= PHY_M_1000C_AFD;
00392 if (sky2->advertising & ADVERTISED_1000baseT_Half)
00393 ct1000 |= PHY_M_1000C_AHD;
00394 if (sky2->advertising & ADVERTISED_100baseT_Full)
00395 adv |= PHY_M_AN_100_FD;
00396 if (sky2->advertising & ADVERTISED_100baseT_Half)
00397 adv |= PHY_M_AN_100_HD;
00398 if (sky2->advertising & ADVERTISED_10baseT_Full)
00399 adv |= PHY_M_AN_10_FD;
00400 if (sky2->advertising & ADVERTISED_10baseT_Half)
00401 adv |= PHY_M_AN_10_HD;
00402
00403 adv |= copper_fc_adv[sky2->flow_mode];
00404 } else {
00405 if (sky2->advertising & ADVERTISED_1000baseT_Full)
00406 adv |= PHY_M_AN_1000X_AFD;
00407 if (sky2->advertising & ADVERTISED_1000baseT_Half)
00408 adv |= PHY_M_AN_1000X_AHD;
00409
00410 adv |= fiber_fc_adv[sky2->flow_mode];
00411 }
00412
00413
00414 ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
00415 } else {
00416
00417 ct1000 = PHY_M_1000C_MSE;
00418
00419
00420 reg |= GM_GPCR_AU_ALL_DIS;
00421
00422 switch (sky2->speed) {
00423 case SPEED_1000:
00424 ctrl |= PHY_CT_SP1000;
00425 reg |= GM_GPCR_SPEED_1000;
00426 break;
00427 case SPEED_100:
00428 ctrl |= PHY_CT_SP100;
00429 reg |= GM_GPCR_SPEED_100;
00430 break;
00431 }
00432
00433 if (sky2->duplex == DUPLEX_FULL) {
00434 reg |= GM_GPCR_DUP_FULL;
00435 ctrl |= PHY_CT_DUP_MD;
00436 } else if (sky2->speed < SPEED_1000)
00437 sky2->flow_mode = FC_NONE;
00438
00439
00440 reg |= gm_fc_disable[sky2->flow_mode];
00441
00442
00443 if (sky2->flow_mode & FC_RX)
00444 sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
00445 else
00446 sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
00447 }
00448
00449 gma_write16(hw, port, GM_GP_CTRL, reg);
00450
00451 if (hw->flags & SKY2_HW_GIGABIT)
00452 gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000);
00453
00454 gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv);
00455 gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
00456
00457
00458 ledctrl = PHY_M_LED_PULS_DUR(PULS_170MS);
00459 ledover = 0;
00460
00461 switch (hw->chip_id) {
00462 case CHIP_ID_YUKON_FE:
00463
00464 ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) << 1;
00465
00466 ctrl = gm_phy_read(hw, port, PHY_MARV_FE_LED_PAR);
00467
00468
00469 ctrl &= ~PHY_M_FELP_LED1_MSK;
00470
00471 ctrl |= PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_ACT_BL);
00472 gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl);
00473 break;
00474
00475 case CHIP_ID_YUKON_FE_P:
00476
00477 ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
00478 ctrl |= PHY_M_PC_ENA_LIP_NP;
00479
00480
00481 ctrl &= ~(PHY_M_PC_ENA_ENE_DT | PHY_M_PC_DIS_SCRAMB);
00482 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
00483
00484
00485 ctrl = PHY_M_FELP_LED2_CTRL(LED_PAR_CTRL_ACT_BL) |
00486 PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_LINK) |
00487 PHY_M_FELP_LED0_CTRL(LED_PAR_CTRL_SPEED);
00488
00489 gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl);
00490 break;
00491
00492 case CHIP_ID_YUKON_XL:
00493 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
00494
00495
00496 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
00497
00498
00499 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
00500 (PHY_M_LEDC_LOS_CTRL(1) |
00501 PHY_M_LEDC_INIT_CTRL(7) |
00502 PHY_M_LEDC_STA1_CTRL(7) |
00503 PHY_M_LEDC_STA0_CTRL(7)));
00504
00505
00506 gm_phy_write(hw, port, PHY_MARV_PHY_STAT,
00507 (PHY_M_POLC_LS1_P_MIX(4) |
00508 PHY_M_POLC_IS0_P_MIX(4) |
00509 PHY_M_POLC_LOS_CTRL(2) |
00510 PHY_M_POLC_INIT_CTRL(2) |
00511 PHY_M_POLC_STA1_CTRL(2) |
00512 PHY_M_POLC_STA0_CTRL(2)));
00513
00514
00515 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
00516 break;
00517
00518 case CHIP_ID_YUKON_EC_U:
00519 case CHIP_ID_YUKON_EX:
00520 case CHIP_ID_YUKON_SUPR:
00521 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
00522
00523
00524 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
00525
00526
00527 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
00528 (PHY_M_LEDC_LOS_CTRL(1) |
00529 PHY_M_LEDC_INIT_CTRL(8) |
00530 PHY_M_LEDC_STA1_CTRL(7) |
00531 PHY_M_LEDC_STA0_CTRL(7)));
00532
00533
00534 gm_phy_write(hw, port, PHY_MARV_INT_MASK,
00535 ledctrl | PHY_M_LED_BLINK_RT(BLINK_84MS));
00536
00537 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
00538 break;
00539
00540 default:
00541
00542 ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL;
00543
00544
00545 ledover |= PHY_M_LED_MO_RX(MO_LED_OFF);
00546 }
00547
00548 if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_UL_2) {
00549
00550 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 255);
00551
00552
00553 gm_phy_write(hw, port, 0x18, 0xaa99);
00554 gm_phy_write(hw, port, 0x17, 0x2011);
00555
00556 if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
00557
00558 gm_phy_write(hw, port, 0x18, 0xa204);
00559 gm_phy_write(hw, port, 0x17, 0x2002);
00560 }
00561
00562
00563 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
00564 } else if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
00565 hw->chip_rev == CHIP_REV_YU_FE2_A0) {
00566
00567 gm_phy_write(hw, port, PHY_MARV_PAGE_ADDR, 17);
00568 gm_phy_write(hw, port, PHY_MARV_PAGE_DATA, 0x3f60);
00569 } else if (hw->chip_id != CHIP_ID_YUKON_EX &&
00570 hw->chip_id < CHIP_ID_YUKON_SUPR) {
00571
00572 gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
00573
00574 if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) {
00575
00576 ledover |= PHY_M_LED_MO_100(MO_LED_ON);
00577 }
00578
00579 if (ledover)
00580 gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
00581
00582 }
00583
00584
00585 if (sky2->autoneg == AUTONEG_ENABLE)
00586 gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL);
00587 else
00588 gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
00589 }
00590
00591 static const u32 phy_power[] = { PCI_Y2_PHY1_POWD, PCI_Y2_PHY2_POWD };
00592 static const u32 coma_mode[] = { PCI_Y2_PHY1_COMA, PCI_Y2_PHY2_COMA };
00593
00594 static void sky2_phy_power_up(struct sky2_hw *hw, unsigned port)
00595 {
00596 u32 reg1;
00597
00598 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
00599 reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
00600 reg1 &= ~phy_power[port];
00601
00602 if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
00603 reg1 |= coma_mode[port];
00604
00605 sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
00606 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
00607 sky2_pci_read32(hw, PCI_DEV_REG1);
00608
00609 if (hw->chip_id == CHIP_ID_YUKON_FE)
00610 gm_phy_write(hw, port, PHY_MARV_CTRL, PHY_CT_ANE);
00611 else if (hw->flags & SKY2_HW_ADV_POWER_CTL)
00612 sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
00613 }
00614
00615 static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port)
00616 {
00617 u32 reg1;
00618 u16 ctrl;
00619
00620
00621 sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
00622
00623
00624 sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
00625
00626 if (hw->flags & SKY2_HW_NEWER_PHY) {
00627
00628 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
00629
00630 ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
00631
00632 ctrl &= ~PHY_M_MAC_GMIF_PUP;
00633 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
00634
00635
00636 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
00637 }
00638
00639
00640 gma_write16(hw, port, GM_GP_CTRL,
00641 GM_GPCR_FL_PASS | GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS);
00642
00643 if (hw->chip_id != CHIP_ID_YUKON_EC) {
00644 if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
00645
00646 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
00647
00648 ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
00649
00650 ctrl |= PHY_M_PC_POW_D_ENA;
00651 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
00652
00653
00654 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
00655 }
00656
00657
00658 gm_phy_write(hw, port, PHY_MARV_CTRL, PHY_CT_PDOWN);
00659 }
00660
00661 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
00662 reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
00663 reg1 |= phy_power[port];
00664 sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
00665 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
00666 }
00667
00668 static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port)
00669 {
00670 if ( (hw->chip_id == CHIP_ID_YUKON_EX &&
00671 hw->chip_rev != CHIP_REV_YU_EX_A0) ||
00672 hw->chip_id == CHIP_ID_YUKON_FE_P ||
00673 hw->chip_id == CHIP_ID_YUKON_SUPR) {
00674
00675 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
00676 TX_JUMBO_DIS | TX_STFW_ENA);
00677 } else {
00678 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_ENA);
00679 }
00680 }
00681
00682 static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
00683 {
00684 u16 reg;
00685 u32 rx_reg;
00686 int i;
00687 const u8 *addr = hw->dev[port]->ll_addr;
00688
00689 sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
00690 sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
00691
00692 sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
00693
00694 if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0 && port == 1) {
00695
00696
00697 sky2_write8(hw, SK_REG(0, GMAC_CTRL), GMC_RST_CLR);
00698 do {
00699 sky2_write8(hw, SK_REG(1, GMAC_CTRL), GMC_RST_SET);
00700 sky2_write8(hw, SK_REG(1, GMAC_CTRL), GMC_RST_CLR);
00701 } while (gm_phy_read(hw, 1, PHY_MARV_ID0) != PHY_MARV_ID0_VAL ||
00702 gm_phy_read(hw, 1, PHY_MARV_ID1) != PHY_MARV_ID1_Y2 ||
00703 gm_phy_read(hw, 1, PHY_MARV_INT_MASK) != 0);
00704 }
00705
00706 sky2_read16(hw, SK_REG(port, GMAC_IRQ_SRC));
00707
00708
00709 sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK);
00710
00711 sky2_phy_power_up(hw, port);
00712 sky2_phy_init(hw, port);
00713
00714
00715 reg = gma_read16(hw, port, GM_PHY_ADDR);
00716 gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR);
00717
00718 for (i = GM_MIB_CNT_BASE; i <= GM_MIB_CNT_END; i += 4)
00719 gma_read16(hw, port, i);
00720 gma_write16(hw, port, GM_PHY_ADDR, reg);
00721
00722
00723 gma_write16(hw, port, GM_TX_CTRL, TX_COL_THR(TX_COL_DEF));
00724
00725
00726 gma_write16(hw, port, GM_RX_CTRL,
00727 GM_RXCR_UCF_ENA | GM_RXCR_CRC_DIS | GM_RXCR_MCF_ENA);
00728
00729
00730 gma_write16(hw, port, GM_TX_FLOW_CTRL, 0xffff);
00731
00732
00733 gma_write16(hw, port, GM_TX_PARAM,
00734 TX_JAM_LEN_VAL(TX_JAM_LEN_DEF) |
00735 TX_JAM_IPG_VAL(TX_JAM_IPG_DEF) |
00736 TX_IPG_JAM_DATA(TX_IPG_JAM_DEF) |
00737 TX_BACK_OFF_LIM(TX_BOF_LIM_DEF));
00738
00739
00740 reg = DATA_BLIND_VAL(DATA_BLIND_DEF) |
00741 GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
00742
00743 gma_write16(hw, port, GM_SERIAL_MODE, reg);
00744
00745
00746 gma_set_addr(hw, port, GM_SRC_ADDR_2L, addr);
00747
00748
00749 gma_set_addr(hw, port, GM_SRC_ADDR_1L, addr);
00750
00751
00752 gma_write16(hw, port, GM_TX_IRQ_MSK, 0);
00753 gma_write16(hw, port, GM_RX_IRQ_MSK, 0);
00754 gma_write16(hw, port, GM_TR_IRQ_MSK, 0);
00755
00756
00757 sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
00758 rx_reg = GMF_OPER_ON | GMF_RX_F_FL_ON;
00759 if (hw->chip_id == CHIP_ID_YUKON_EX ||
00760 hw->chip_id == CHIP_ID_YUKON_FE_P)
00761 rx_reg |= GMF_RX_OVER_ON;
00762
00763 sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), rx_reg);
00764
00765 if (hw->chip_id == CHIP_ID_YUKON_XL) {
00766
00767 sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), 0);
00768 } else {
00769
00770 sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR);
00771 }
00772
00773
00774 reg = RX_GMF_FL_THR_DEF + 1;
00775
00776 if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
00777 hw->chip_rev == CHIP_REV_YU_FE2_A0)
00778 reg = 0x178;
00779 sky2_write16(hw, SK_REG(port, RX_GMF_FL_THR), reg);
00780
00781
00782 sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR);
00783 sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
00784
00785
00786 if (!(hw->flags & SKY2_HW_RAM_BUFFER)) {
00787 sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8);
00788 sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8);
00789
00790 sky2_set_tx_stfwd(hw, port);
00791 }
00792
00793 if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
00794 hw->chip_rev == CHIP_REV_YU_FE2_A0) {
00795
00796 reg = sky2_read16(hw, SK_REG(port, TX_GMF_EA));
00797 reg &= ~TX_DYN_WM_ENA;
00798 sky2_write16(hw, SK_REG(port, TX_GMF_EA), reg);
00799 }
00800 }
00801
00802
00803 static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 space)
00804 {
00805 u32 end;
00806
00807
00808 start *= 1024/8;
00809 space *= 1024/8;
00810 end = start + space - 1;
00811
00812 sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
00813 sky2_write32(hw, RB_ADDR(q, RB_START), start);
00814 sky2_write32(hw, RB_ADDR(q, RB_END), end);
00815 sky2_write32(hw, RB_ADDR(q, RB_WP), start);
00816 sky2_write32(hw, RB_ADDR(q, RB_RP), start);
00817
00818 if (q == Q_R1 || q == Q_R2) {
00819 u32 tp = space - space/4;
00820
00821
00822
00823
00824
00825 sky2_write32(hw, RB_ADDR(q, RB_RX_UTHP), tp);
00826 sky2_write32(hw, RB_ADDR(q, RB_RX_LTHP), space/2);
00827
00828 tp = space - 2048/8;
00829 sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp);
00830 sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4);
00831 } else {
00832
00833
00834
00835 sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_STFWD);
00836 }
00837
00838 sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_OP_MD);
00839 sky2_read8(hw, RB_ADDR(q, RB_CTRL));
00840 }
00841
00842
00843 static void sky2_qset(struct sky2_hw *hw, u16 q)
00844 {
00845 sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_RESET);
00846 sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_OPER_INIT);
00847 sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_FIFO_OP_ON);
00848 sky2_write32(hw, Q_ADDR(q, Q_WM), BMU_WM_DEFAULT);
00849 }
00850
00851
00852
00853
00854 static void sky2_prefetch_init(struct sky2_hw *hw, u32 qaddr,
00855 u64 addr, u32 last)
00856 {
00857 sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
00858 sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_RST_CLR);
00859 sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_ADDR_HI), addr >> 32);
00860 sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_ADDR_LO), (u32) addr);
00861 sky2_write16(hw, Y2_QADDR(qaddr, PREF_UNIT_LAST_IDX), last);
00862 sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_OP_ON);
00863
00864 sky2_read32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL));
00865 }
00866
00867 static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2)
00868 {
00869 struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod;
00870
00871 sky2->tx_prod = RING_NEXT(sky2->tx_prod, TX_RING_SIZE);
00872 le->ctrl = 0;
00873 return le;
00874 }
00875
00876 static void tx_init(struct sky2_port *sky2)
00877 {
00878 struct sky2_tx_le *le;
00879
00880 sky2->tx_prod = sky2->tx_cons = 0;
00881
00882 le = get_tx_le(sky2);
00883 le->addr = 0;
00884 le->opcode = OP_ADDR64 | HW_OWNER;
00885 }
00886
00887 static inline struct tx_ring_info *tx_le_re(struct sky2_port *sky2,
00888 struct sky2_tx_le *le)
00889 {
00890 return sky2->tx_ring + (le - sky2->tx_le);
00891 }
00892
00893
00894 static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx)
00895 {
00896
00897 wmb();
00898 sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx);
00899 DBGIO(PFX "queue %#x idx <- %d\n", q, idx);
00900 }
00901
00902
00903 static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2)
00904 {
00905 struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put;
00906
00907 sky2->rx_put = RING_NEXT(sky2->rx_put, RX_LE_SIZE);
00908 le->ctrl = 0;
00909 return le;
00910 }
00911
00912
00913 static void sky2_rx_add(struct sky2_port *sky2, u8 op,
00914 u32 map, unsigned len)
00915 {
00916 struct sky2_rx_le *le;
00917
00918 le = sky2_next_rx(sky2);
00919 le->addr = cpu_to_le32(map);
00920 le->length = cpu_to_le16(len);
00921 le->opcode = op | HW_OWNER;
00922 }
00923
00924
00925 static void sky2_rx_submit(struct sky2_port *sky2,
00926 const struct rx_ring_info *re)
00927 {
00928 sky2_rx_add(sky2, OP_PACKET, re->data_addr, sky2->rx_data_size);
00929 }
00930
00931
00932 static void sky2_rx_map_iob(struct pci_device *pdev __unused,
00933 struct rx_ring_info *re,
00934 unsigned size __unused)
00935 {
00936 struct io_buffer *iob = re->iob;
00937 re->data_addr = virt_to_bus(iob->data);
00938 }
00939
00940
00941
00942 static void rx_set_checksum(struct sky2_port *sky2)
00943 {
00944 struct sky2_rx_le *le = sky2_next_rx(sky2);
00945
00946 le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN);
00947 le->ctrl = 0;
00948 le->opcode = OP_TCPSTART | HW_OWNER;
00949
00950 sky2_write32(sky2->hw,
00951 Q_ADDR(rxqaddr[sky2->port], Q_CSR),
00952 BMU_DIS_RX_CHKSUM);
00953 }
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965 static void sky2_rx_stop(struct sky2_port *sky2)
00966 {
00967 struct sky2_hw *hw = sky2->hw;
00968 unsigned rxq = rxqaddr[sky2->port];
00969 int i;
00970
00971
00972 sky2_write8(hw, RB_ADDR(rxq, RB_CTRL), RB_DIS_OP_MD);
00973
00974 for (i = 0; i < 0xffff; i++)
00975 if (sky2_read8(hw, RB_ADDR(rxq, Q_RSL))
00976 == sky2_read8(hw, RB_ADDR(rxq, Q_RL)))
00977 goto stopped;
00978
00979 DBG(PFX "%s: receiver stop failed\n", sky2->netdev->name);
00980 stopped:
00981 sky2_write32(hw, Q_ADDR(rxq, Q_CSR), BMU_RST_SET | BMU_FIFO_RST);
00982
00983
00984 sky2_write32(hw, Y2_QADDR(rxq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
00985 wmb();
00986 }
00987
00988
00989 static void sky2_rx_clean(struct sky2_port *sky2)
00990 {
00991 unsigned i;
00992
00993 memset(sky2->rx_le, 0, RX_LE_BYTES);
00994 for (i = 0; i < RX_PENDING; i++) {
00995 struct rx_ring_info *re = sky2->rx_ring + i;
00996
00997 if (re->iob) {
00998 free_iob(re->iob);
00999 re->iob = NULL;
01000 }
01001 }
01002 }
01003
01004
01005
01006
01007 static struct io_buffer *sky2_rx_alloc(struct sky2_port *sky2)
01008 {
01009 struct io_buffer *iob;
01010
01011 iob = alloc_iob(sky2->rx_data_size + ETH_DATA_ALIGN);
01012 if (!iob)
01013 return NULL;
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026 if (!(sky2->hw->flags & SKY2_HW_RAM_BUFFER)) {
01027 iob_reserve(iob, ETH_DATA_ALIGN);
01028 }
01029
01030 return iob;
01031 }
01032
01033 static inline void sky2_rx_update(struct sky2_port *sky2, unsigned rxq)
01034 {
01035 sky2_put_idx(sky2->hw, rxq, sky2->rx_put);
01036 }
01037
01038
01039
01040
01041
01042
01043
01044 static int sky2_rx_start(struct sky2_port *sky2)
01045 {
01046 struct sky2_hw *hw = sky2->hw;
01047 struct rx_ring_info *re;
01048 unsigned rxq = rxqaddr[sky2->port];
01049 unsigned i, size, thresh;
01050
01051 sky2->rx_put = sky2->rx_next = 0;
01052 sky2_qset(hw, rxq);
01053
01054
01055 if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP))
01056 sky2_write32(hw, Q_ADDR(rxq, Q_WM), BMU_WM_PEX);
01057
01058
01059
01060 if (hw->chip_id == CHIP_ID_YUKON_EC_U &&
01061 (hw->chip_rev == CHIP_REV_YU_EC_U_A1
01062 || hw->chip_rev == CHIP_REV_YU_EC_U_B0))
01063 sky2_write32(hw, Q_ADDR(rxq, Q_TEST), F_M_RX_RAM_DIS);
01064
01065 sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1);
01066
01067 if (!(hw->flags & SKY2_HW_NEW_LE))
01068 rx_set_checksum(sky2);
01069
01070
01071 size = (ETH_FRAME_LEN + 8) & ~7;
01072
01073
01074 thresh = (size - 8) / sizeof(u32);
01075
01076 sky2->rx_data_size = size;
01077
01078
01079 for (i = 0; i < RX_PENDING; i++) {
01080 re = sky2->rx_ring + i;
01081
01082 re->iob = sky2_rx_alloc(sky2);
01083 if (!re->iob)
01084 goto nomem;
01085
01086 sky2_rx_map_iob(hw->pdev, re, sky2->rx_data_size);
01087 sky2_rx_submit(sky2, re);
01088 }
01089
01090
01091
01092
01093
01094
01095
01096 if (thresh > 0x1ff)
01097 sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_OFF);
01098 else {
01099 sky2_write16(hw, SK_REG(sky2->port, RX_GMF_TR_THR), thresh);
01100 sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON);
01101 }
01102
01103
01104 sky2_rx_update(sky2, rxq);
01105 return 0;
01106 nomem:
01107 sky2_rx_clean(sky2);
01108 return -ENOMEM;
01109 }
01110
01111
01112 static void sky2_free_rings(struct sky2_port *sky2)
01113 {
01114 free_dma(sky2->rx_le, RX_LE_BYTES);
01115 free(sky2->rx_ring);
01116
01117 free_dma(sky2->tx_le, TX_RING_SIZE * sizeof(struct sky2_tx_le));
01118 free(sky2->tx_ring);
01119
01120 sky2->tx_le = NULL;
01121 sky2->rx_le = NULL;
01122
01123 sky2->rx_ring = NULL;
01124 sky2->tx_ring = NULL;
01125 }
01126
01127
01128 static int sky2_up(struct net_device *dev)
01129 {
01130 struct sky2_port *sky2 = netdev_priv(dev);
01131 struct sky2_hw *hw = sky2->hw;
01132 unsigned port = sky2->port;
01133 u32 imask, ramsize;
01134 int err = -ENOMEM;
01135
01136 netdev_link_down(dev);
01137
01138
01139 sky2->tx_le = malloc_dma(TX_RING_SIZE * sizeof(struct sky2_tx_le), TX_RING_ALIGN);
01140 sky2->tx_le_map = virt_to_bus(sky2->tx_le);
01141 if (!sky2->tx_le)
01142 goto err_out;
01143 memset(sky2->tx_le, 0, TX_RING_SIZE * sizeof(struct sky2_tx_le));
01144
01145 sky2->tx_ring = zalloc(TX_RING_SIZE * sizeof(struct tx_ring_info));
01146 if (!sky2->tx_ring)
01147 goto err_out;
01148
01149 tx_init(sky2);
01150
01151 sky2->rx_le = malloc_dma(RX_LE_BYTES, RX_RING_ALIGN);
01152 sky2->rx_le_map = virt_to_bus(sky2->rx_le);
01153 if (!sky2->rx_le)
01154 goto err_out;
01155 memset(sky2->rx_le, 0, RX_LE_BYTES);
01156
01157 sky2->rx_ring = zalloc(RX_PENDING * sizeof(struct rx_ring_info));
01158 if (!sky2->rx_ring)
01159 goto err_out;
01160
01161 sky2_mac_init(hw, port);
01162
01163
01164 ramsize = sky2_read8(hw, B2_E_0) * 4;
01165 if (ramsize > 0) {
01166 u32 rxspace;
01167
01168 hw->flags |= SKY2_HW_RAM_BUFFER;
01169 DBG2(PFX "%s: ram buffer %dK\n", dev->name, ramsize);
01170 if (ramsize < 16)
01171 rxspace = ramsize / 2;
01172 else
01173 rxspace = 8 + (2*(ramsize - 16))/3;
01174
01175 sky2_ramset(hw, rxqaddr[port], 0, rxspace);
01176 sky2_ramset(hw, txqaddr[port], rxspace, ramsize - rxspace);
01177
01178
01179 sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL),
01180 RB_RST_SET);
01181 }
01182
01183 sky2_qset(hw, txqaddr[port]);
01184
01185
01186 if (hw->chip_id == CHIP_ID_YUKON_EX && hw->chip_rev == CHIP_REV_YU_EX_B0)
01187 sky2_write32(hw, Q_ADDR(txqaddr[port], Q_TEST), F_TX_CHK_AUTO_OFF);
01188
01189
01190 if (hw->chip_id == CHIP_ID_YUKON_EC_U
01191 && hw->chip_rev == CHIP_REV_YU_EC_U_A0)
01192 sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), ECU_TXFF_LEV);
01193
01194 sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
01195 TX_RING_SIZE - 1);
01196
01197 err = sky2_rx_start(sky2);
01198 if (err)
01199 goto err_out;
01200
01201
01202 imask = sky2_read32(hw, B0_IMSK);
01203 imask |= portirq_msk[port];
01204 sky2_write32(hw, B0_IMSK, imask);
01205
01206 DBGIO(PFX "%s: le bases: st %p [%x], rx %p [%x], tx %p [%x]\n",
01207 dev->name, hw->st_le, hw->st_dma, sky2->rx_le, sky2->rx_le_map,
01208 sky2->tx_le, sky2->tx_le_map);
01209
01210 sky2_set_multicast(dev);
01211 return 0;
01212
01213 err_out:
01214 sky2_free_rings(sky2);
01215 return err;
01216 }
01217
01218
01219 static inline int tx_dist(unsigned tail, unsigned head)
01220 {
01221 return (head - tail) & (TX_RING_SIZE - 1);
01222 }
01223
01224
01225 static inline int tx_avail(const struct sky2_port *sky2)
01226 {
01227 return TX_PENDING - tx_dist(sky2->tx_cons, sky2->tx_prod);
01228 }
01229
01230
01231
01232
01233
01234
01235
01236
01237 static int sky2_xmit_frame(struct net_device *dev, struct io_buffer *iob)
01238 {
01239 struct sky2_port *sky2 = netdev_priv(dev);
01240 struct sky2_hw *hw = sky2->hw;
01241 struct sky2_tx_le *le = NULL;
01242 struct tx_ring_info *re;
01243 unsigned len;
01244 u32 mapping;
01245 u8 ctrl;
01246
01247 if (tx_avail(sky2) < 1)
01248 return -EBUSY;
01249
01250 len = iob_len(iob);
01251 mapping = virt_to_bus(iob->data);
01252
01253 DBGIO(PFX "%s: tx queued, slot %d, len %d\n", dev->name,
01254 sky2->tx_prod, len);
01255
01256 ctrl = 0;
01257
01258 le = get_tx_le(sky2);
01259 le->addr = cpu_to_le32((u32) mapping);
01260 le->length = cpu_to_le16(len);
01261 le->ctrl = ctrl;
01262 le->opcode = (OP_PACKET | HW_OWNER);
01263
01264 re = tx_le_re(sky2, le);
01265 re->iob = iob;
01266
01267 le->ctrl |= EOP;
01268
01269 sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod);
01270
01271 return 0;
01272 }
01273
01274
01275
01276
01277
01278
01279
01280 static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
01281 {
01282 struct net_device *dev = sky2->netdev;
01283 unsigned idx;
01284
01285 assert(done < TX_RING_SIZE);
01286
01287 for (idx = sky2->tx_cons; idx != done;
01288 idx = RING_NEXT(idx, TX_RING_SIZE)) {
01289 struct sky2_tx_le *le = sky2->tx_le + idx;
01290 struct tx_ring_info *re = sky2->tx_ring + idx;
01291
01292 if (le->ctrl & EOP) {
01293 DBGIO(PFX "%s: tx done %d\n", dev->name, idx);
01294 netdev_tx_complete(dev, re->iob);
01295 }
01296 }
01297
01298 sky2->tx_cons = idx;
01299 mb();
01300 }
01301
01302
01303 static void sky2_tx_clean(struct net_device *dev)
01304 {
01305 struct sky2_port *sky2 = netdev_priv(dev);
01306
01307 sky2_tx_complete(sky2, sky2->tx_prod);
01308 }
01309
01310
01311 static void sky2_down(struct net_device *dev)
01312 {
01313 struct sky2_port *sky2 = netdev_priv(dev);
01314 struct sky2_hw *hw = sky2->hw;
01315 unsigned port = sky2->port;
01316 u16 ctrl;
01317 u32 imask;
01318
01319
01320 if (!sky2->tx_le)
01321 return;
01322
01323 DBG2(PFX "%s: disabling interface\n", dev->name);
01324
01325
01326 imask = sky2_read32(hw, B0_IMSK);
01327 imask &= ~portirq_msk[port];
01328 sky2_write32(hw, B0_IMSK, imask);
01329
01330 sky2_gmac_reset(hw, port);
01331
01332
01333 sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_STOP);
01334 sky2_read32(hw, Q_ADDR(txqaddr[port], Q_CSR));
01335
01336 sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
01337 RB_RST_SET | RB_DIS_OP_MD);
01338
01339 ctrl = gma_read16(hw, port, GM_GP_CTRL);
01340 ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA);
01341 gma_write16(hw, port, GM_GP_CTRL, ctrl);
01342
01343 sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
01344
01345
01346 if (!(hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0
01347 && port == 0 && hw->dev[1]))
01348 sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
01349
01350
01351 sky2_write8(hw, SK_REG(port, TXA_CTRL),
01352 TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
01353
01354
01355 sky2_write32(hw, SK_REG(port, TXA_ITI_INI), 0L);
01356 sky2_write32(hw, SK_REG(port, TXA_LIM_INI), 0L);
01357
01358
01359 sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR),
01360 BMU_RST_SET | BMU_FIFO_RST);
01361
01362
01363 sky2_write32(hw, Y2_QADDR(txqaddr[port], PREF_UNIT_CTRL),
01364 PREF_UNIT_RST_SET);
01365
01366 sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);
01367
01368 sky2_rx_stop(sky2);
01369
01370 sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
01371 sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
01372
01373 sky2_phy_power_down(hw, port);
01374
01375
01376 sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
01377
01378 sky2_tx_clean(dev);
01379 sky2_rx_clean(sky2);
01380
01381 sky2_free_rings(sky2);
01382
01383 return;
01384 }
01385
01386 static u16 sky2_phy_speed(const struct sky2_hw *hw, u16 aux)
01387 {
01388 if (hw->flags & SKY2_HW_FIBRE_PHY)
01389 return SPEED_1000;
01390
01391 if (!(hw->flags & SKY2_HW_GIGABIT)) {
01392 if (aux & PHY_M_PS_SPEED_100)
01393 return SPEED_100;
01394 else
01395 return SPEED_10;
01396 }
01397
01398 switch (aux & PHY_M_PS_SPEED_MSK) {
01399 case PHY_M_PS_SPEED_1000:
01400 return SPEED_1000;
01401 case PHY_M_PS_SPEED_100:
01402 return SPEED_100;
01403 default:
01404 return SPEED_10;
01405 }
01406 }
01407
01408 static void sky2_link_up(struct sky2_port *sky2)
01409 {
01410 struct sky2_hw *hw = sky2->hw;
01411 unsigned port = sky2->port;
01412 u16 reg;
01413 static const char *fc_name[] = {
01414 [FC_NONE] = "none",
01415 [FC_TX] = "tx",
01416 [FC_RX] = "rx",
01417 [FC_BOTH] = "both",
01418 };
01419
01420
01421 reg = gma_read16(hw, port, GM_GP_CTRL);
01422 reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
01423 gma_write16(hw, port, GM_GP_CTRL, reg);
01424
01425 gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
01426
01427 netdev_link_up(sky2->netdev);
01428
01429
01430 sky2_write8(hw, SK_REG(port, LNK_LED_REG),
01431 LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF);
01432
01433 DBG(PFX "%s: Link is up at %d Mbps, %s duplex, flow control %s\n",
01434 sky2->netdev->name, sky2->speed,
01435 sky2->duplex == DUPLEX_FULL ? "full" : "half",
01436 fc_name[sky2->flow_status]);
01437 }
01438
01439 static void sky2_link_down(struct sky2_port *sky2)
01440 {
01441 struct sky2_hw *hw = sky2->hw;
01442 unsigned port = sky2->port;
01443 u16 reg;
01444
01445 gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
01446
01447 reg = gma_read16(hw, port, GM_GP_CTRL);
01448 reg &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
01449 gma_write16(hw, port, GM_GP_CTRL, reg);
01450
01451 netdev_link_down(sky2->netdev);
01452
01453
01454 sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
01455
01456 DBG(PFX "%s: Link is down.\n", sky2->netdev->name);
01457
01458 sky2_phy_init(hw, port);
01459 }
01460
01461 static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
01462 {
01463 struct sky2_hw *hw = sky2->hw;
01464 unsigned port = sky2->port;
01465 u16 advert, lpa;
01466
01467 advert = gm_phy_read(hw, port, PHY_MARV_AUNE_ADV);
01468 lpa = gm_phy_read(hw, port, PHY_MARV_AUNE_LP);
01469 if (lpa & PHY_M_AN_RF) {
01470 DBG(PFX "%s: remote fault\n", sky2->netdev->name);
01471 return -1;
01472 }
01473
01474 if (!(aux & PHY_M_PS_SPDUP_RES)) {
01475 DBG(PFX "%s: speed/duplex mismatch\n", sky2->netdev->name);
01476 return -1;
01477 }
01478
01479 sky2->speed = sky2_phy_speed(hw, aux);
01480 sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
01481
01482
01483
01484
01485
01486 sky2->flow_status = FC_NONE;
01487 if (advert & ADVERTISE_PAUSE_CAP) {
01488 if (lpa & LPA_PAUSE_CAP)
01489 sky2->flow_status = FC_BOTH;
01490 else if (advert & ADVERTISE_PAUSE_ASYM)
01491 sky2->flow_status = FC_RX;
01492 } else if (advert & ADVERTISE_PAUSE_ASYM) {
01493 if ((lpa & LPA_PAUSE_CAP) && (lpa & LPA_PAUSE_ASYM))
01494 sky2->flow_status = FC_TX;
01495 }
01496
01497 if (sky2->duplex == DUPLEX_HALF && sky2->speed < SPEED_1000
01498 && !(hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX))
01499 sky2->flow_status = FC_NONE;
01500
01501 if (sky2->flow_status & FC_TX)
01502 sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
01503 else
01504 sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
01505
01506 return 0;
01507 }
01508
01509
01510 static void sky2_phy_intr(struct sky2_hw *hw, unsigned port)
01511 {
01512 struct net_device *dev = hw->dev[port];
01513 struct sky2_port *sky2 = netdev_priv(dev);
01514 u16 istatus, phystat;
01515
01516 istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT);
01517 phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT);
01518
01519 DBGIO(PFX "%s: phy interrupt status 0x%x 0x%x\n",
01520 sky2->netdev->name, istatus, phystat);
01521
01522 if (sky2->autoneg == AUTONEG_ENABLE && (istatus & PHY_M_IS_AN_COMPL)) {
01523 if (sky2_autoneg_done(sky2, phystat) == 0)
01524 sky2_link_up(sky2);
01525 return;
01526 }
01527
01528 if (istatus & PHY_M_IS_LSP_CHANGE)
01529 sky2->speed = sky2_phy_speed(hw, phystat);
01530
01531 if (istatus & PHY_M_IS_DUP_CHANGE)
01532 sky2->duplex =
01533 (phystat & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
01534
01535 if (istatus & PHY_M_IS_LST_CHANGE) {
01536 if (phystat & PHY_M_PS_LINK_UP)
01537 sky2_link_up(sky2);
01538 else
01539 sky2_link_down(sky2);
01540 }
01541 }
01542
01543
01544 static struct io_buffer *receive_new(struct sky2_port *sky2,
01545 struct rx_ring_info *re,
01546 unsigned int length)
01547 {
01548 struct io_buffer *iob, *niob;
01549 unsigned hdr_space = sky2->rx_data_size;
01550
01551
01552 niob = sky2_rx_alloc(sky2);
01553 if (!niob)
01554 return NULL;
01555
01556 iob = re->iob;
01557
01558 re->iob = niob;
01559 sky2_rx_map_iob(sky2->hw->pdev, re, hdr_space);
01560
01561 iob_put(iob, length);
01562 return iob;
01563 }
01564
01565
01566
01567
01568
01569 static struct io_buffer *sky2_receive(struct net_device *dev,
01570 u16 length, u32 status)
01571 {
01572 struct sky2_port *sky2 = netdev_priv(dev);
01573 struct rx_ring_info *re = sky2->rx_ring + sky2->rx_next;
01574 struct io_buffer *iob = NULL;
01575 u16 count = (status & GMR_FS_LEN) >> 16;
01576
01577 DBGIO(PFX "%s: rx slot %d status 0x%x len %d\n",
01578 dev->name, sky2->rx_next, status, length);
01579
01580 sky2->rx_next = (sky2->rx_next + 1) % RX_PENDING;
01581
01582
01583
01584
01585
01586 if (sky2->hw->chip_id == CHIP_ID_YUKON_FE_P &&
01587 sky2->hw->chip_rev == CHIP_REV_YU_FE2_A0 &&
01588 length == count)
01589 goto okay;
01590
01591 if (status & GMR_FS_ANY_ERR)
01592 goto error;
01593
01594 if (!(status & GMR_FS_RX_OK))
01595 goto resubmit;
01596
01597
01598 if (length != count)
01599 goto len_error;
01600
01601 okay:
01602 iob = receive_new(sky2, re, length);
01603 resubmit:
01604 sky2_rx_submit(sky2, re);
01605
01606 return iob;
01607
01608 len_error:
01609
01610
01611 DBG2(PFX "%s: rx length error: status %#x length %d\n",
01612 dev->name, status, length);
01613
01614
01615
01616 netdev_rx_err(dev, NULL, -EINVAL);
01617 goto resubmit;
01618
01619 error:
01620 if (status & GMR_FS_RX_FF_OV) {
01621 DBG2(PFX "%s: FIFO overflow error\n", dev->name);
01622 netdev_rx_err(dev, NULL, -EBUSY);
01623 goto resubmit;
01624 }
01625
01626 DBG2(PFX "%s: rx error, status 0x%x length %d\n",
01627 dev->name, status, length);
01628 netdev_rx_err(dev, NULL, -EIO);
01629
01630 goto resubmit;
01631 }
01632
01633
01634 static inline void sky2_tx_done(struct net_device *dev, u16 last)
01635 {
01636 struct sky2_port *sky2 = netdev_priv(dev);
01637
01638 sky2_tx_complete(sky2, last);
01639 }
01640
01641
01642 static void sky2_status_intr(struct sky2_hw *hw, u16 idx)
01643 {
01644 unsigned rx[2] = { 0, 0 };
01645
01646 rmb();
01647 do {
01648 struct sky2_port *sky2;
01649 struct sky2_status_le *le = hw->st_le + hw->st_idx;
01650 unsigned port;
01651 struct net_device *dev;
01652 struct io_buffer *iob;
01653 u32 status;
01654 u16 length;
01655 u8 opcode = le->opcode;
01656
01657 if (!(opcode & HW_OWNER))
01658 break;
01659
01660 port = le->css & CSS_LINK_BIT;
01661 dev = hw->dev[port];
01662 sky2 = netdev_priv(dev);
01663 length = le16_to_cpu(le->length);
01664 status = le32_to_cpu(le->status);
01665
01666 hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE);
01667
01668 le->opcode = 0;
01669 switch (opcode & ~HW_OWNER) {
01670 case OP_RXSTAT:
01671 ++rx[port];
01672 iob = sky2_receive(dev, length, status);
01673 if (!iob) {
01674 netdev_rx_err(dev, NULL, -ENOMEM);
01675 break;
01676 }
01677
01678 netdev_rx(dev, iob);
01679 break;
01680
01681 case OP_RXCHKS:
01682 DBG2(PFX "status OP_RXCHKS but checksum offloading disabled\n");
01683 break;
01684
01685 case OP_TXINDEXLE:
01686
01687 assert(TX_RING_SIZE <= 0x1000);
01688 sky2_tx_done(hw->dev[0], status & 0xfff);
01689 if (hw->dev[1])
01690 sky2_tx_done(hw->dev[1],
01691 ((status >> 24) & 0xff)
01692 | (u16)(length & 0xf) << 8);
01693 break;
01694
01695 default:
01696 DBG(PFX "unknown status opcode 0x%x\n", opcode);
01697 }
01698 } while (hw->st_idx != idx);
01699
01700
01701 sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
01702
01703 if (rx[0])
01704 sky2_rx_update(netdev_priv(hw->dev[0]), Q_R1);
01705
01706 if (rx[1])
01707 sky2_rx_update(netdev_priv(hw->dev[1]), Q_R2);
01708 }
01709
01710 static void sky2_hw_error(struct sky2_hw *hw, unsigned port, u32 status)
01711 {
01712 struct net_device *dev = hw->dev[port];
01713
01714 DBGIO(PFX "%s: hw error interrupt status 0x%x\n", dev->name, status);
01715
01716 if (status & Y2_IS_PAR_RD1) {
01717 DBG(PFX "%s: ram data read parity error\n", dev->name);
01718
01719 sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_RD_PERR);
01720 }
01721
01722 if (status & Y2_IS_PAR_WR1) {
01723 DBG(PFX "%s: ram data write parity error\n", dev->name);
01724 sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_WR_PERR);
01725 }
01726
01727 if (status & Y2_IS_PAR_MAC1) {
01728 DBG(PFX "%s: MAC parity error\n", dev->name);
01729 sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_PE);
01730 }
01731
01732 if (status & Y2_IS_PAR_RX1) {
01733 DBG(PFX "%s: RX parity error\n", dev->name);
01734 sky2_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), BMU_CLR_IRQ_PAR);
01735 }
01736
01737 if (status & Y2_IS_TCP_TXA1) {
01738 DBG(PFX "%s: TCP segmentation error\n", dev->name);
01739 sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_CLR_IRQ_TCP);
01740 }
01741 }
01742
01743 static void sky2_hw_intr(struct sky2_hw *hw)
01744 {
01745 u32 status = sky2_read32(hw, B0_HWE_ISRC);
01746 u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK);
01747
01748 status &= hwmsk;
01749
01750 if (status & Y2_IS_TIST_OV)
01751 sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
01752
01753 if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) {
01754 u16 pci_err;
01755
01756 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
01757 pci_err = sky2_pci_read16(hw, PCI_STATUS);
01758 DBG(PFX "PCI hardware error (0x%x)\n", pci_err);
01759
01760 sky2_pci_write16(hw, PCI_STATUS,
01761 pci_err | PCI_STATUS_ERROR_BITS);
01762 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
01763 }
01764
01765 if (status & Y2_IS_PCI_EXP) {
01766
01767 u32 err;
01768
01769 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
01770 err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
01771 sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
01772 0xfffffffful);
01773 DBG(PFX "PCI-Express error (0x%x)\n", err);
01774
01775 sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
01776 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
01777 }
01778
01779 if (status & Y2_HWE_L1_MASK)
01780 sky2_hw_error(hw, 0, status);
01781 status >>= 8;
01782 if (status & Y2_HWE_L1_MASK)
01783 sky2_hw_error(hw, 1, status);
01784 }
01785
01786 static void sky2_mac_intr(struct sky2_hw *hw, unsigned port)
01787 {
01788 struct net_device *dev = hw->dev[port];
01789 u8 status = sky2_read8(hw, SK_REG(port, GMAC_IRQ_SRC));
01790
01791 DBGIO(PFX "%s: mac interrupt status 0x%x\n", dev->name, status);
01792
01793 if (status & GM_IS_RX_CO_OV)
01794 gma_read16(hw, port, GM_RX_IRQ_SRC);
01795
01796 if (status & GM_IS_TX_CO_OV)
01797 gma_read16(hw, port, GM_TX_IRQ_SRC);
01798
01799 if (status & GM_IS_RX_FF_OR) {
01800 sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_CLI_RX_FO);
01801 }
01802
01803 if (status & GM_IS_TX_FF_UR) {
01804 sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_FU);
01805 }
01806 }
01807
01808
01809 static void sky2_le_error(struct sky2_hw *hw, unsigned port,
01810 u16 q, unsigned ring_size __unused)
01811 {
01812 struct net_device *dev = hw->dev[port];
01813 struct sky2_port *sky2 = netdev_priv(dev);
01814 int idx;
01815 const u64 *le = (q == Q_R1 || q == Q_R2)
01816 ? (u64 *) sky2->rx_le : (u64 *) sky2->tx_le;
01817
01818 idx = sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_GET_IDX));
01819 DBG(PFX "%s: descriptor error q=%#x get=%d [%llx] last=%d put=%d should be %d\n",
01820 dev->name, (unsigned) q, idx, (unsigned long long) le[idx],
01821 (int) sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_LAST_IDX)),
01822 (int) sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX)),
01823 le == (u64 *)sky2->rx_le? sky2->rx_put : sky2->tx_prod);
01824
01825 sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_IRQ_CHK);
01826 }
01827
01828
01829 static void sky2_err_intr(struct sky2_hw *hw, u32 status)
01830 {
01831 DBG(PFX "error interrupt status=%#x\n", status);
01832
01833 if (status & Y2_IS_HW_ERR)
01834 sky2_hw_intr(hw);
01835
01836 if (status & Y2_IS_IRQ_MAC1)
01837 sky2_mac_intr(hw, 0);
01838
01839 if (status & Y2_IS_IRQ_MAC2)
01840 sky2_mac_intr(hw, 1);
01841
01842 if (status & Y2_IS_CHK_RX1)
01843 sky2_le_error(hw, 0, Q_R1, RX_LE_SIZE);
01844
01845 if (status & Y2_IS_CHK_RX2)
01846 sky2_le_error(hw, 1, Q_R2, RX_LE_SIZE);
01847
01848 if (status & Y2_IS_CHK_TXA1)
01849 sky2_le_error(hw, 0, Q_XA1, TX_RING_SIZE);
01850
01851 if (status & Y2_IS_CHK_TXA2)
01852 sky2_le_error(hw, 1, Q_XA2, TX_RING_SIZE);
01853 }
01854
01855 static void sky2_poll(struct net_device *dev)
01856 {
01857 struct sky2_port *sky2 = netdev_priv(dev);
01858 struct sky2_hw *hw = sky2->hw;
01859 u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
01860 u16 idx;
01861
01862 if (status & Y2_IS_ERROR)
01863 sky2_err_intr(hw, status);
01864
01865 if (status & Y2_IS_IRQ_PHY1)
01866 sky2_phy_intr(hw, 0);
01867
01868 if (status & Y2_IS_IRQ_PHY2)
01869 sky2_phy_intr(hw, 1);
01870
01871 while ((idx = sky2_read16(hw, STAT_PUT_IDX)) != hw->st_idx) {
01872 sky2_status_intr(hw, idx);
01873 }
01874
01875
01876
01877
01878 if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) {
01879 sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
01880 sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
01881 }
01882 sky2_read32(hw, B0_Y2_SP_LISR);
01883 }
01884
01885
01886 static u32 sky2_mhz(const struct sky2_hw *hw)
01887 {
01888 switch (hw->chip_id) {
01889 case CHIP_ID_YUKON_EC:
01890 case CHIP_ID_YUKON_EC_U:
01891 case CHIP_ID_YUKON_EX:
01892 case CHIP_ID_YUKON_SUPR:
01893 case CHIP_ID_YUKON_UL_2:
01894 return 125;
01895
01896 case CHIP_ID_YUKON_FE:
01897 return 100;
01898
01899 case CHIP_ID_YUKON_FE_P:
01900 return 50;
01901
01902 case CHIP_ID_YUKON_XL:
01903 return 156;
01904
01905 default:
01906 DBG(PFX "unknown chip ID!\n");
01907 return 100;
01908 }
01909 }
01910
01911 static inline u32 sky2_us2clk(const struct sky2_hw *hw, u32 us)
01912 {
01913 return sky2_mhz(hw) * us;
01914 }
01915
01916 static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk)
01917 {
01918 return clk / sky2_mhz(hw);
01919 }
01920
01921 static int sky2_init(struct sky2_hw *hw)
01922 {
01923 u8 t8;
01924
01925
01926 sky2_pci_write32(hw, PCI_DEV_REG3, 0);
01927
01928 sky2_write8(hw, B0_CTST, CS_RST_CLR);
01929
01930 hw->chip_id = sky2_read8(hw, B2_CHIP_ID);
01931 hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4;
01932
01933 switch(hw->chip_id) {
01934 case CHIP_ID_YUKON_XL:
01935 hw->flags = SKY2_HW_GIGABIT | SKY2_HW_NEWER_PHY;
01936 break;
01937
01938 case CHIP_ID_YUKON_EC_U:
01939 hw->flags = SKY2_HW_GIGABIT
01940 | SKY2_HW_NEWER_PHY
01941 | SKY2_HW_ADV_POWER_CTL;
01942 break;
01943
01944 case CHIP_ID_YUKON_EX:
01945 hw->flags = SKY2_HW_GIGABIT
01946 | SKY2_HW_NEWER_PHY
01947 | SKY2_HW_NEW_LE
01948 | SKY2_HW_ADV_POWER_CTL;
01949 break;
01950
01951 case CHIP_ID_YUKON_EC:
01952
01953 if (hw->chip_rev == CHIP_REV_YU_EC_A1) {
01954 DBG(PFX "unsupported revision Yukon-EC rev A1\n");
01955 return -EOPNOTSUPP;
01956 }
01957 hw->flags = SKY2_HW_GIGABIT;
01958 break;
01959
01960 case CHIP_ID_YUKON_FE:
01961 break;
01962
01963 case CHIP_ID_YUKON_FE_P:
01964 hw->flags = SKY2_HW_NEWER_PHY
01965 | SKY2_HW_NEW_LE
01966 | SKY2_HW_AUTO_TX_SUM
01967 | SKY2_HW_ADV_POWER_CTL;
01968 break;
01969
01970 case CHIP_ID_YUKON_SUPR:
01971 hw->flags = SKY2_HW_GIGABIT
01972 | SKY2_HW_NEWER_PHY
01973 | SKY2_HW_NEW_LE
01974 | SKY2_HW_AUTO_TX_SUM
01975 | SKY2_HW_ADV_POWER_CTL;
01976 break;
01977
01978 case CHIP_ID_YUKON_UL_2:
01979 hw->flags = SKY2_HW_GIGABIT
01980 | SKY2_HW_ADV_POWER_CTL;
01981 break;
01982
01983 default:
01984 DBG(PFX "unsupported chip type 0x%x\n", hw->chip_id);
01985 return -EOPNOTSUPP;
01986 }
01987
01988 hw->pmd_type = sky2_read8(hw, B2_PMD_TYP);
01989 if (hw->pmd_type == 'L' || hw->pmd_type == 'S' || hw->pmd_type == 'P')
01990 hw->flags |= SKY2_HW_FIBRE_PHY;
01991
01992 hw->ports = 1;
01993 t8 = sky2_read8(hw, B2_Y2_HW_RES);
01994 if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) {
01995 if (!(sky2_read8(hw, B2_Y2_CLK_GATE) & Y2_STATUS_LNK2_INAC))
01996 ++hw->ports;
01997 }
01998
01999 return 0;
02000 }
02001
02002 static void sky2_reset(struct sky2_hw *hw)
02003 {
02004 u16 status;
02005 int i, cap;
02006 u32 hwe_mask = Y2_HWE_ALL_MASK;
02007
02008
02009 if (hw->chip_id == CHIP_ID_YUKON_EX) {
02010 status = sky2_read16(hw, HCU_CCSR);
02011 status &= ~(HCU_CCSR_AHB_RST | HCU_CCSR_CPU_RST_MODE |
02012 HCU_CCSR_UC_STATE_MSK);
02013 sky2_write16(hw, HCU_CCSR, status);
02014 } else
02015 sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
02016 sky2_write16(hw, B0_CTST, Y2_ASF_DISABLE);
02017
02018
02019 sky2_write8(hw, B0_CTST, CS_RST_SET);
02020 sky2_write8(hw, B0_CTST, CS_RST_CLR);
02021
02022
02023 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
02024
02025
02026 status = sky2_pci_read16(hw, PCI_STATUS);
02027 status |= PCI_STATUS_ERROR_BITS;
02028 sky2_pci_write16(hw, PCI_STATUS, status);
02029
02030 sky2_write8(hw, B0_CTST, CS_MRST_CLR);
02031
02032 cap = pci_find_capability(hw->pdev, PCI_CAP_ID_EXP);
02033 if (cap) {
02034 sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
02035 0xfffffffful);
02036
02037
02038 if (sky2_read32(hw, B0_HWE_ISRC) & Y2_IS_PCI_EXP)
02039 DBG(PFX "ignoring stuck error report bit\n");
02040 else
02041 hwe_mask |= Y2_IS_PCI_EXP;
02042 }
02043
02044 sky2_power_on(hw);
02045 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
02046
02047 for (i = 0; i < hw->ports; i++) {
02048 sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
02049 sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
02050
02051 if (hw->chip_id == CHIP_ID_YUKON_EX ||
02052 hw->chip_id == CHIP_ID_YUKON_SUPR)
02053 sky2_write16(hw, SK_REG(i, GMAC_CTRL),
02054 GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON
02055 | GMC_BYP_RETR_ON);
02056 }
02057
02058
02059 sky2_write32(hw, B2_I2C_IRQ, 1);
02060
02061
02062 sky2_write8(hw, B2_TI_CTRL, TIM_STOP);
02063 sky2_write8(hw, B2_TI_CTRL, TIM_CLR_IRQ);
02064
02065 sky2_write8(hw, B0_Y2LED, LED_STAT_ON);
02066
02067
02068 sky2_write32(hw, B28_DPT_CTRL, DPT_STOP);
02069
02070
02071 sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_STOP);
02072 sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
02073
02074
02075 for (i = 0; i < hw->ports; i++)
02076 sky2_write8(hw, SK_REG(i, TXA_CTRL), TXA_ENA_ARB);
02077
02078
02079 for (i = 0; i < hw->ports; i++) {
02080 sky2_write8(hw, RAM_BUFFER(i, B3_RI_CTRL), RI_RST_CLR);
02081
02082 sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_R1), SK_RI_TO_53);
02083 sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XA1), SK_RI_TO_53);
02084 sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XS1), SK_RI_TO_53);
02085 sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_R1), SK_RI_TO_53);
02086 sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XA1), SK_RI_TO_53);
02087 sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS1), SK_RI_TO_53);
02088 sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_R2), SK_RI_TO_53);
02089 sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XA2), SK_RI_TO_53);
02090 sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XS2), SK_RI_TO_53);
02091 sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_R2), SK_RI_TO_53);
02092 sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XA2), SK_RI_TO_53);
02093 sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53);
02094 }
02095
02096 sky2_write32(hw, B0_HWE_IMSK, hwe_mask);
02097
02098 for (i = 0; i < hw->ports; i++)
02099 sky2_gmac_reset(hw, i);
02100
02101 memset(hw->st_le, 0, STATUS_LE_BYTES);
02102 hw->st_idx = 0;
02103
02104 sky2_write32(hw, STAT_CTRL, SC_STAT_RST_SET);
02105 sky2_write32(hw, STAT_CTRL, SC_STAT_RST_CLR);
02106
02107 sky2_write32(hw, STAT_LIST_ADDR_LO, hw->st_dma);
02108 sky2_write32(hw, STAT_LIST_ADDR_HI, (u64) hw->st_dma >> 32);
02109
02110
02111 sky2_write16(hw, STAT_LAST_IDX, STATUS_RING_SIZE - 1);
02112
02113 sky2_write16(hw, STAT_TX_IDX_TH, 10);
02114 sky2_write8(hw, STAT_FIFO_WM, 16);
02115
02116
02117 if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0)
02118 sky2_write8(hw, STAT_FIFO_ISR_WM, 4);
02119 else
02120 sky2_write8(hw, STAT_FIFO_ISR_WM, 16);
02121
02122 sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000));
02123 sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 20));
02124 sky2_write32(hw, STAT_LEV_TIMER_INI, sky2_us2clk(hw, 100));
02125
02126
02127 sky2_write32(hw, STAT_CTRL, SC_STAT_OP_ON);
02128
02129 sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
02130 sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
02131 sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
02132 }
02133
02134 static u32 sky2_supported_modes(const struct sky2_hw *hw)
02135 {
02136 if (sky2_is_copper(hw)) {
02137 u32 modes = SUPPORTED_10baseT_Half
02138 | SUPPORTED_10baseT_Full
02139 | SUPPORTED_100baseT_Half
02140 | SUPPORTED_100baseT_Full
02141 | SUPPORTED_Autoneg | SUPPORTED_TP;
02142
02143 if (hw->flags & SKY2_HW_GIGABIT)
02144 modes |= SUPPORTED_1000baseT_Half
02145 | SUPPORTED_1000baseT_Full;
02146 return modes;
02147 } else
02148 return SUPPORTED_1000baseT_Half
02149 | SUPPORTED_1000baseT_Full
02150 | SUPPORTED_Autoneg
02151 | SUPPORTED_FIBRE;
02152 }
02153
02154 static void sky2_set_multicast(struct net_device *dev)
02155 {
02156 struct sky2_port *sky2 = netdev_priv(dev);
02157 struct sky2_hw *hw = sky2->hw;
02158 unsigned port = sky2->port;
02159 u16 reg;
02160 u8 filter[8];
02161 int rx_pause;
02162
02163 rx_pause = (sky2->flow_status == FC_RX || sky2->flow_status == FC_BOTH);
02164
02165 reg = gma_read16(hw, port, GM_RX_CTRL);
02166 reg |= GM_RXCR_UCF_ENA;
02167
02168 memset(filter, 0xff, sizeof(filter));
02169
02170 gma_write16(hw, port, GM_MC_ADDR_H1,
02171 (u16) filter[0] | ((u16) filter[1] << 8));
02172 gma_write16(hw, port, GM_MC_ADDR_H2,
02173 (u16) filter[2] | ((u16) filter[3] << 8));
02174 gma_write16(hw, port, GM_MC_ADDR_H3,
02175 (u16) filter[4] | ((u16) filter[5] << 8));
02176 gma_write16(hw, port, GM_MC_ADDR_H4,
02177 (u16) filter[6] | ((u16) filter[7] << 8));
02178
02179 gma_write16(hw, port, GM_RX_CTRL, reg);
02180 }
02181
02182
02183 static struct net_device *sky2_init_netdev(struct sky2_hw *hw,
02184 unsigned port)
02185 {
02186 struct sky2_port *sky2;
02187 struct net_device *dev = alloc_etherdev(sizeof(*sky2));
02188
02189 if (!dev) {
02190 DBG(PFX "etherdev alloc failed\n");
02191 return NULL;
02192 }
02193
02194 dev->dev = &hw->pdev->dev;
02195
02196 sky2 = netdev_priv(dev);
02197 sky2->netdev = dev;
02198 sky2->hw = hw;
02199
02200
02201 sky2->autoneg = AUTONEG_ENABLE;
02202 sky2->flow_mode = FC_BOTH;
02203
02204 sky2->duplex = -1;
02205 sky2->speed = -1;
02206 sky2->advertising = sky2_supported_modes(hw);
02207
02208 hw->dev[port] = dev;
02209
02210 sky2->port = port;
02211
02212
02213 memcpy(dev->hw_addr, (void *)(hw->regs + B2_MAC_1 + port * 8), ETH_ALEN);
02214
02215 return dev;
02216 }
02217
02218 static void sky2_show_addr(struct net_device *dev)
02219 {
02220 DBG2(PFX "%s: addr %s\n", dev->name, netdev_addr(dev));
02221 }
02222
02223 #if DBGLVL_MAX
02224
02225 static const char *sky2_name(u8 chipid, char *buf, int sz)
02226 {
02227 const char *name[] = {
02228 "XL",
02229 "EC Ultra",
02230 "Extreme",
02231 "EC",
02232 "FE",
02233 "FE+",
02234 "Supreme",
02235 "UL 2",
02236 };
02237
02238 if (chipid >= CHIP_ID_YUKON_XL && chipid <= CHIP_ID_YUKON_UL_2)
02239 strncpy(buf, name[chipid - CHIP_ID_YUKON_XL], sz);
02240 else
02241 snprintf(buf, sz, "(chip %#x)", chipid);
02242 return buf;
02243 }
02244 #endif
02245
02246 static void sky2_net_irq(struct net_device *dev, int enable)
02247 {
02248 struct sky2_port *sky2 = netdev_priv(dev);
02249 struct sky2_hw *hw = sky2->hw;
02250
02251 u32 imask = sky2_read32(hw, B0_IMSK);
02252 if (enable)
02253 imask |= portirq_msk[sky2->port];
02254 else
02255 imask &= ~portirq_msk[sky2->port];
02256 sky2_write32(hw, B0_IMSK, imask);
02257 }
02258
02259 static struct net_device_operations sky2_operations = {
02260 .open = sky2_up,
02261 .close = sky2_down,
02262 .transmit = sky2_xmit_frame,
02263 .poll = sky2_poll,
02264 .irq = sky2_net_irq
02265 };
02266
02267 static int sky2_probe(struct pci_device *pdev,
02268 const struct pci_device_id *ent __unused)
02269 {
02270 struct net_device *dev;
02271 struct sky2_hw *hw;
02272 int err;
02273 char buf1[16] __unused;
02274
02275 adjust_pci_device(pdev);
02276
02277 err = -ENOMEM;
02278 hw = zalloc(sizeof(*hw));
02279 if (!hw) {
02280 DBG(PFX "cannot allocate hardware struct\n");
02281 goto err_out;
02282 }
02283
02284 hw->pdev = pdev;
02285
02286 hw->regs = (unsigned long)ioremap(pci_bar_start(pdev, PCI_BASE_ADDRESS_0), 0x4000);
02287 if (!hw->regs) {
02288 DBG(PFX "cannot map device registers\n");
02289 goto err_out_free_hw;
02290 }
02291
02292
02293 hw->st_le = malloc_dma(STATUS_LE_BYTES, STATUS_RING_ALIGN);
02294 if (!hw->st_le)
02295 goto err_out_iounmap;
02296 hw->st_dma = virt_to_bus(hw->st_le);
02297 memset(hw->st_le, 0, STATUS_LE_BYTES);
02298
02299 err = sky2_init(hw);
02300 if (err)
02301 goto err_out_iounmap;
02302
02303 #if DBGLVL_MAX
02304 DBG2(PFX "Yukon-2 %s chip revision %d\n",
02305 sky2_name(hw->chip_id, buf1, sizeof(buf1)), hw->chip_rev);
02306 #endif
02307
02308 sky2_reset(hw);
02309
02310 dev = sky2_init_netdev(hw, 0);
02311 if (!dev) {
02312 err = -ENOMEM;
02313 goto err_out_free_pci;
02314 }
02315
02316 netdev_init(dev, &sky2_operations);
02317
02318 err = register_netdev(dev);
02319 if (err) {
02320 DBG(PFX "cannot register net device\n");
02321 goto err_out_free_netdev;
02322 }
02323
02324 sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
02325
02326 sky2_show_addr(dev);
02327
02328 if (hw->ports > 1) {
02329 struct net_device *dev1;
02330
02331 dev1 = sky2_init_netdev(hw, 1);
02332 if (!dev1)
02333 DBG(PFX "allocation for second device failed\n");
02334 else if ((err = register_netdev(dev1))) {
02335 DBG(PFX "register of second port failed (%d)\n", err);
02336 hw->dev[1] = NULL;
02337 netdev_nullify(dev1);
02338 netdev_put(dev1);
02339 } else
02340 sky2_show_addr(dev1);
02341 }
02342
02343 pci_set_drvdata(pdev, dev);
02344
02345 return 0;
02346
02347 err_out_free_netdev:
02348 netdev_nullify(dev);
02349 netdev_put(dev);
02350 err_out_free_pci:
02351 sky2_write8(hw, B0_CTST, CS_RST_SET);
02352 free_dma(hw->st_le, STATUS_LE_BYTES);
02353 err_out_iounmap:
02354 iounmap((void *)hw->regs);
02355 err_out_free_hw:
02356 free(hw);
02357 err_out:
02358 pci_set_drvdata(pdev, NULL);
02359 return err;
02360 }
02361
02362 static void sky2_remove(struct pci_device *pdev)
02363 {
02364 struct sky2_hw *hw = pci_get_drvdata(pdev);
02365 int i;
02366
02367 if (!hw)
02368 return;
02369
02370 for (i = hw->ports-1; i >= 0; --i)
02371 unregister_netdev(hw->dev[i]);
02372
02373 sky2_write32(hw, B0_IMSK, 0);
02374
02375 sky2_power_aux(hw);
02376
02377 sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
02378 sky2_write8(hw, B0_CTST, CS_RST_SET);
02379 sky2_read8(hw, B0_CTST);
02380
02381 free_dma(hw->st_le, STATUS_LE_BYTES);
02382
02383 for (i = hw->ports-1; i >= 0; --i) {
02384 netdev_nullify(hw->dev[i]);
02385 netdev_put(hw->dev[i]);
02386 }
02387
02388 iounmap((void *)hw->regs);
02389 free(hw);
02390
02391 pci_set_drvdata(pdev, NULL);
02392 }
02393
02394 struct pci_driver sky2_driver __pci_driver = {
02395 .ids = sky2_id_table,
02396 .id_count = (sizeof (sky2_id_table) / sizeof (sky2_id_table[0])),
02397 .probe = sky2_probe,
02398 .remove = sky2_remove
02399 };