struct netxen_ring_ctx *ctx_desc;
struct pci_dev *ctx_desc_pdev;
dma_addr_t ctx_desc_phys_addr;
+ int intr_scheme;
int (*enable_phy_interrupts) (struct netxen_adapter *);
int (*disable_phy_interrupts) (struct netxen_adapter *);
void (*handle_phy_intr) (struct netxen_adapter *);
static inline void netxen_nic_disable_int(struct netxen_adapter *adapter)
{
- /*
- * ISR_INT_MASK: Can be read from window 0 or 1.
- */
- writel(0x7ff, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK));
+ uint32_t mask = 0x7ff;
+ int retries = 32;
+
+ DPRINTK(1, INFO, "Entered ISR Disable \n");
+
+ switch (adapter->portnum) {
+ case 0:
+ writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
+ break;
+ case 1:
+ writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
+ break;
+ case 2:
+ writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
+ break;
+ case 3:
+ writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
+ break;
+ }
+
+ if (adapter->intr_scheme != -1 &&
+ adapter->intr_scheme != INTR_SCHEME_PERPORT) {
+ writel(mask,
+ (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)));
+ }
+
+ /* Window = 0 or 1 */
+ if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
+ do {
+ writel(0xffffffff, (void *)
+ (PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_STATUS)));
+ mask = readl((void *)
+ (pci_base_offset(adapter, ISR_INT_VECTOR)));
+ if (!(mask & 0x80))
+ break;
+ udelay(10);
+ } while (--retries);
+
+ if (!retries) {
+ printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n",
+ netxen_nic_driver_name);
+ }
+ }
+
+ DPRINTK(1, INFO, "Done with Disable Int\n");
+ return;
}
static inline void netxen_nic_enable_int(struct netxen_adapter *adapter)
{
u32 mask;
- switch (adapter->ahw.board_type) {
- case NETXEN_NIC_GBE:
- mask = 0x77b;
+ DPRINTK(1, INFO, "Entered ISR Enable \n");
+
+ if (adapter->intr_scheme != -1 &&
+ adapter->intr_scheme != INTR_SCHEME_PERPORT) {
+ switch (adapter->ahw.board_type) {
+ case NETXEN_NIC_GBE:
+ mask = 0x77b;
+ break;
+ case NETXEN_NIC_XGBE:
+ mask = 0x77f;
+ break;
+ default:
+ mask = 0x7ff;
+ break;
+ }
+
+ writel(mask,
+ (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)));
+ }
+ switch (adapter->portnum) {
+ case 0:
+ writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
break;
- case NETXEN_NIC_XGBE:
- mask = 0x77f;
+ case 1:
+ writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
break;
- default:
- mask = 0x7ff;
+ case 2:
+ writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
+ break;
+ case 3:
+ writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
break;
}
- writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK));
-
if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
mask = 0xbff;
- writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
- writel(mask, PCI_OFFSET_SECOND_RANGE(adapter,
- ISR_INT_TARGET_MASK));
+ if (adapter->intr_scheme != -1 &&
+ adapter->intr_scheme != INTR_SCHEME_PERPORT) {
+ writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
+ }
+ writel(mask,
+ (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_MASK)));
}
+
+ DPRINTK(1, INFO, "Done with enable Int\n");
+
+ return;
}
/*
adapter->netdev = netdev;
adapter->pdev = pdev;
+
+ /* this will be read from FW later */
+ adapter->intr_scheme = -1;
+
+ /* This will be reset for mezz cards */
adapter->portnum = pci_func_id;
+ adapter->status &= ~NETXEN_NETDEV_STATUS;
netdev->open = netxen_nic_open;
netdev->stop = netxen_nic_close;
netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev)
{
u32 ret = 0;
+ u32 our_int = 0;
DPRINTK(INFO, "Entered handle ISR\n");
adapter->stats.ints++;
if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
- int count = 0;
- u32 mask;
- u32 our_int = 0;
our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
/* not our interrupt */
if ((our_int & (0x80 << adapter->portnum)) == 0)
return ret;
- netxen_nic_disable_int(adapter);
- /* Window = 0 or 1 */
- do {
- writel(0xffffffff, PCI_OFFSET_SECOND_RANGE(adapter,
- ISR_INT_TARGET_STATUS));
- mask = readl(pci_base_offset(adapter, ISR_INT_VECTOR));
- } while (((mask & 0x80) != 0) && (++count < 32));
- if ((mask & 0x80) != 0)
- printk("Could not disable interrupt completely\n");
+ }
+ netxen_nic_disable_int(adapter);
+
+ if (adapter->intr_scheme == INTR_SCHEME_PERPORT) {
+ /* claim interrupt */
+ if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
+ writel(our_int & ~((u32)(0x80 << adapter->portnum)),
+ NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
+ }
}
if (netxen_nic_rx_has_work(adapter) || netxen_nic_tx_has_work(adapter)) {
} else {
static unsigned int intcount = 0;
if ((++intcount & 0xfff) == 0xfff)
- printk(KERN_ERR
+ DPRINTK(KERN_ERR
"%s: %s interrupt %d while in poll\n",
netxen_nic_driver_name, netdev->name,
intcount);
#define CRB_V2P_3 NETXEN_NIC_REG(0x29c)
#define CRB_V2P(port) (CRB_V2P_0+((port)*4))
#define CRB_DRIVER_VERSION NETXEN_NIC_REG(0x2a0)
+/* sw int status/mask registers */
+#define CRB_SW_INT_MASK_0 NETXEN_NIC_REG(0x1d8)
+#define CRB_SW_INT_MASK_1 NETXEN_NIC_REG(0x1e0)
+#define CRB_SW_INT_MASK_2 NETXEN_NIC_REG(0x1e4)
+#define CRB_SW_INT_MASK_3 NETXEN_NIC_REG(0x1e8)
+
+/*
+ * capabilities register, can be used to selectively enable/disable features
+ * for backward compability
+ */
+#define CRB_NIC_CAPABILITIES_HOST NETXEN_NIC_REG(0x1a8)
+#define CRB_NIC_CAPABILITIES_FW NETXEN_NIC_REG(0x1dc)
+
+#define INTR_SCHEME_PERPORT 0x1
/* used for ethtool tests */
#define CRB_SCRATCHPAD_TEST NETXEN_NIC_REG(0x280)