#define _SKY2_H
/* PCI config registers */
-#define PCI_DEV_REG1 0x40
-#define PCI_DEV_REG2 0x44
-#define PCI_DEV_STATUS 0x7c
-#define PCI_OS_PCI_X (1<<26)
+enum {
+ PCI_DEV_REG1 = 0x40,
+ PCI_DEV_REG2 = 0x44,
+ PCI_DEV_STATUS = 0x7c,
+ PCI_DEV_REG3 = 0x80,
+ PCI_DEV_REG4 = 0x84,
+ PCI_DEV_REG5 = 0x88,
+};
-#define PEX_LNK_STAT 0xf2
-#define PEX_UNC_ERR_STAT 0x104
-#define PEX_DEV_CTRL 0xe8
+enum {
+ PEX_DEV_CAP = 0xe4,
+ PEX_DEV_CTRL = 0xe8,
+ PEX_DEV_STA = 0xea,
+ PEX_LNK_STAT = 0xf2,
+ PEX_UNC_ERR_STAT= 0x104,
+};
/* Yukon-2 */
enum pci_dev_reg_1 {
PCI_USEDATA64 = 1<<0, /* Use 64Bit Data bus ext */
};
+/* PCI_OUR_REG_4 32 bit Our Register 4 (Yukon-ECU only) */
+enum pci_dev_reg_4 {
+ /* (Link Training & Status State Machine) */
+ P_TIMER_VALUE_MSK = 0xffL<<16, /* Bit 23..16: Timer Value Mask */
+ /* (Active State Power Management) */
+ P_FORCE_ASPM_REQUEST = 1<<15, /* Force ASPM Request (A1 only) */
+ P_ASPM_GPHY_LINK_DOWN = 1<<14, /* GPHY Link Down (A1 only) */
+ P_ASPM_INT_FIFO_EMPTY = 1<<13, /* Internal FIFO Empty (A1 only) */
+ P_ASPM_CLKRUN_REQUEST = 1<<12, /* CLKRUN Request (A1 only) */
+
+ P_ASPM_FORCE_CLKREQ_ENA = 1<<4, /* Force CLKREQ Enable (A1b only) */
+ P_ASPM_CLKREQ_PAD_CTL = 1<<3, /* CLKREQ PAD Control (A1 only) */
+ P_ASPM_A1_MODE_SELECT = 1<<2, /* A1 Mode Select (A1 only) */
+ P_CLK_GATE_PEX_UNIT_ENA = 1<<1, /* Enable Gate PEX Unit Clock */
+ P_CLK_GATE_ROOT_COR_ENA = 1<<0, /* Enable Gate Root Core Clock */
+ P_ASPM_CONTROL_MSK = P_FORCE_ASPM_REQUEST | P_ASPM_GPHY_LINK_DOWN
+ | P_ASPM_CLKRUN_REQUEST | P_ASPM_INT_FIFO_EMPTY,
+};
+
#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
PCI_STATUS_SIG_SYSTEM_ERROR | \
Y2_IS_CHK_TXS1 = 1<<1, /* Descriptor error TXS 1 */
Y2_IS_CHK_TXA1 = 1<<0, /* Descriptor error TXA 1 */
- Y2_IS_BASE = Y2_IS_HW_ERR | Y2_IS_STAT_BMU |
- Y2_IS_POLL_CHK | Y2_IS_TWSI_RDY |
- Y2_IS_IRQ_SW | Y2_IS_TIMINT,
- Y2_IS_PORT_1 = Y2_IS_IRQ_PHY1 | Y2_IS_IRQ_MAC1 |
- Y2_IS_CHK_RX1 | Y2_IS_CHK_TXA1 | Y2_IS_CHK_TXS1,
- Y2_IS_PORT_2 = Y2_IS_IRQ_PHY2 | Y2_IS_IRQ_MAC2 |
- Y2_IS_CHK_RX2 | Y2_IS_CHK_TXA2 | Y2_IS_CHK_TXS2,
+ Y2_IS_BASE = Y2_IS_HW_ERR | Y2_IS_STAT_BMU,
+ Y2_IS_PORT_1 = Y2_IS_IRQ_PHY1 | Y2_IS_IRQ_MAC1
+ | Y2_IS_CHK_TXA1 | Y2_IS_CHK_RX1,
+ Y2_IS_PORT_2 = Y2_IS_IRQ_PHY2 | Y2_IS_IRQ_MAC2
+ | Y2_IS_CHK_TXA2 | Y2_IS_CHK_RX2,
};
/* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */
};
#define Q_ADDR(reg, offs) (B8_Q_REGS + (reg) + (offs))
+/* Q_F 32 bit Flag Register */
+enum {
+ F_ALM_FULL = 1<<27, /* Rx FIFO: almost full */
+ F_EMPTY = 1<<27, /* Tx FIFO: empty flag */
+ F_FIFO_EOF = 1<<26, /* Tag (EOF Flag) bit in FIFO */
+ F_WM_REACHED = 1<<25, /* Watermark reached */
+ F_M_RX_RAM_DIS = 1<<24, /* MAC Rx RAM Read Port disable */
+ F_FIFO_LEVEL = 0x1fL<<16, /* Bit 23..16: # of Qwords in FIFO */
+ F_WATER_MARK = 0x0007ffL, /* Bit 10.. 0: Watermark */
+};
/* Queue Prefetch Unit Offsets, use Y2_QADDR() to address (Yukon-2 only)*/
enum {
BMU_CLR_RESET = BMU_FIFO_RST | BMU_OP_OFF | BMU_RST_CLR,
BMU_OPER_INIT = BMU_CLR_IRQ_PAR | BMU_CLR_IRQ_CHK | BMU_START |
BMU_FIFO_ENA | BMU_OP_ON,
+
+ BMU_WM_DEFAULT = 0x600,
};
/* Tx BMU Control / Status Registers (Yukon-2) */
PHY_BCOM_ID1_C0 = 0x6044,
PHY_BCOM_ID1_C5 = 0x6047,
- PHY_MARV_ID1_B0 = 0x0C23, /* Yukon (PHY 88E1011) */
+ PHY_MARV_ID1_B0 = 0x0C23, /* Yukon (PHY 88E1011) */
PHY_MARV_ID1_B2 = 0x0C25, /* Yukon-Plus (PHY 88E1011) */
- PHY_MARV_ID1_C2 = 0x0CC2, /* Yukon-EC (PHY 88E1111) */
- PHY_MARV_ID1_Y2 = 0x0C91, /* Yukon-2 (PHY 88E1112) */
+ PHY_MARV_ID1_C2 = 0x0CC2, /* Yukon-EC (PHY 88E1111) */
+ PHY_MARV_ID1_Y2 = 0x0C91, /* Yukon-2 (PHY 88E1112) */
+ PHY_MARV_ID1_FE = 0x0C83, /* Yukon-FE (PHY 88E3082 Rev.A1) */
+ PHY_MARV_ID1_ECU= 0x0CB0, /* Yukon-ECU (PHY 88E1149 Rev.B2?) */
};
/* Advertisement register bits */
*/
struct sky2_tx_le {
union {
- u32 addr;
+ __le32 addr;
struct {
- u16 offset;
- u16 start;
+ __le16 offset;
+ __le16 start;
} csum __attribute((packed));
struct {
- u16 size;
- u16 rsvd;
+ __le16 size;
+ __le16 rsvd;
} tso __attribute((packed));
} tx;
- u16 length; /* also vlan tag or checksum start */
+ __le16 length; /* also vlan tag or checksum start */
u8 ctrl;
u8 opcode;
} __attribute((packed));
struct sky2_rx_le {
- u32 addr;
- u16 length;
+ __le32 addr;
+ __le16 length;
u8 ctrl;
u8 opcode;
} __attribute((packed));;
struct sky2_status_le {
- u32 status; /* also checksum */
- u16 length; /* also vlan tag */
+ __le32 status; /* also checksum */
+ __le16 length; /* also vlan tag */
u8 link;
u8 opcode;
} __attribute((packed));
+struct tx_ring_info {
+ struct sk_buff *skb;
+ DECLARE_PCI_UNMAP_ADDR(mapaddr);
+ u16 idx;
+};
+
struct ring_info {
struct sk_buff *skb;
dma_addr_t mapaddr;
- u16 maplen;
- u16 idx;
};
struct sky2_port {
struct net_device *netdev;
unsigned port;
u32 msg_enable;
+ spinlock_t phy_lock;
- struct ring_info *tx_ring;
+ spinlock_t tx_lock ____cacheline_aligned_in_smp;
+ struct tx_ring_info *tx_ring;
struct sky2_tx_le *tx_le;
- spinlock_t tx_lock;
- u32 tx_addr64;
u16 tx_cons; /* next le to check */
u16 tx_prod; /* next le to use */
+ u32 tx_addr64;
u16 tx_pending;
- u16 tx_last_put;
u16 tx_last_mss;
- struct ring_info *rx_ring;
+ struct ring_info *rx_ring ____cacheline_aligned_in_smp;
struct sky2_rx_le *rx_le;
u32 rx_addr64;
u16 rx_next; /* next re to check */
u16 rx_put; /* next le index to use */
u16 rx_pending;
- u16 rx_last_put;
+ u16 rx_bufsize;
#ifdef SKY2_VLAN_TAG_USED
u16 rx_tag;
struct vlan_group *vlgrp;
u8 rx_pause;
u8 tx_pause;
u8 rx_csum;
- u8 wol;
- struct tasklet_struct phy_task;
struct net_device_stats net_stats;
+
};
struct sky2_hw {
void __iomem *regs;
struct pci_dev *pdev;
- u32 intr_mask;
struct net_device *dev[2];
int pm_cap;
struct sky2_status_le *st_le;
u32 st_idx;
dma_addr_t st_dma;
-
- spinlock_t phy_lock;
+ int msi_detected;
+ wait_queue_head_t msi_wait;
};
/* Register accessor for memory mapped device */
return readb(hw->regs + reg);
}
-/* This should probably go away, bus based tweeks suck */
-static inline int is_pciex(const struct sky2_hw *hw)
-{
- u32 status;
- pci_read_config_dword(hw->pdev, PCI_DEV_STATUS, &status);
- return (status & PCI_OS_PCI_X) == 0;
-}
-
static inline void sky2_write32(const struct sky2_hw *hw, unsigned reg, u32 val)
{
writel(val, hw->regs + reg);
gma_write16(hw, port, reg+4,(u16) addr[2] | ((u16) addr[3] << 8));
gma_write16(hw, port, reg+8,(u16) addr[4] | ((u16) addr[5] << 8));
}
+
+/* PCI config space access */
+static inline u32 sky2_pci_read32(const struct sky2_hw *hw, unsigned reg)
+{
+ return sky2_read32(hw, Y2_CFG_SPC + reg);
+}
+
+static inline u16 sky2_pci_read16(const struct sky2_hw *hw, unsigned reg)
+{
+ return sky2_read16(hw, Y2_CFG_SPC + reg);
+}
+
+static inline void sky2_pci_write32(struct sky2_hw *hw, unsigned reg, u32 val)
+{
+ sky2_write32(hw, Y2_CFG_SPC + reg, val);
+}
+
+static inline void sky2_pci_write16(struct sky2_hw *hw, unsigned reg, u16 val)
+{
+ sky2_write16(hw, Y2_CFG_SPC + reg, val);
+}
#endif