BNX2X: IRQs implemented
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 19 Feb 2015 22:10:37 +0000 (17:10 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Mon, 2 Mar 2015 16:59:10 +0000 (11:59 -0500)
IRQs are registered okay, but we were hanging here:

[bnx2x]:[bnx2x_state_wait:285()]waiting for state to become 1
[bnx2x]:[bnx2x_sp_task:5648()]sp task invoked
[bnx2x]:[bnx2x_sp_task:5657()]status 0
[bnx2x]:[bnx2x_sp_task:5658()]setting interrupt_occurred to 0
[bnx2x]:[bnx2x_state_wait:303()]timeout waiting for state 1

The issue is that we should be receiving an FP IRQ at this point, and we
needed to be consistent with whether or not we have CNIC_SUPPORT.  If we
do, then the code needs to reserve an extra MSIX vector in the
pci_devices table for the CNIC.  The actual card will know about it
(since we tell it elsewhere), and then the FP's won't begin until MSIX
vector 2 (the third one).

Also, since we do various hackery, we need to make sure the driver knows
we're using MSIX.  We'll tell it later, based on the flag.

Btw, the current pr_fmt seems a bit obnoxious.  Damned if you do, damned if you
don't.

kern/drivers/net/bnx2x/akaros_compat.h
kern/drivers/net/bnx2x/bnx2x_cmn.c
kern/drivers/net/bnx2x/bnx2x_main.c
kern/drivers/net/bnx2x/bnx2x_sp.c

index 0f9d965..4c4f57e 100644 (file)
@@ -165,6 +165,9 @@ typedef int pm_message_t;
 #define down_interruptible(sem) ({sem_down(sem); 0;})
 #define down_timeout(sem, timeout) ({sem_down(sem); 0;})
 
+#define local_bh_disable() cmb()
+#define local_bh_enable() cmb()
+
 /* Linux printk front ends */
 #ifndef pr_fmt
 #define pr_fmt(fmt) "bnx2x:" fmt
@@ -603,13 +606,17 @@ static int pcie_capability_read_word(struct pci_device *dev, int pos,
 #define napi_hash_add(...)
 #define napi_enable(...)
 #define napi_disable(...)
+#define napi_schedule(...)
+#define napi_schedule_irqoff(...)
 /* picks a random, valid mac addr for dev */
 #define eth_hw_addr_random(...)
 /* checks if the MAC is not 0 and not multicast (all 1s) */
 #define is_valid_ether_addr(...) (TRUE)
 
 #define EPROBE_DEFER 1
-#define NET_SKB_PAD 32 // we'll probably delete code using this
+#define NET_SKB_PAD 32         /* we'll probably delete code using this */
+#define MAX_SKB_FRAGS 16       /* we'll probably delete code using this */
+#define VLAN_VID_MASK 0x0fff /* VLAN Identifier */
 
 /* Could spatch this:
        if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
index 38107cb..7984934 100644 (file)
@@ -1143,8 +1143,6 @@ next_cqe:
 
 static void bnx2x_msix_fp_int(struct hw_trapframe *hw_tf, void *fp_cookie)
 {
-panic("Not implemented");
-#if 0 // AKAROS_PORT
        struct bnx2x_fastpath *fp = fp_cookie;
        struct bnx2x *bp = fp->bp;
        uint8_t cos;
@@ -1165,10 +1163,10 @@ panic("Not implemented");
                prefetch(fp->txdata_ptr[cos]->tx_cons_sb);
 
        prefetch(&fp->sb_running_index[SM_RX_ID]);
+       /* TODO XME: wake a ktask or o/w poll the device.  we're in hard IRQ */
        napi_schedule_irqoff(&bnx2x_fp(bp, fp->index, napi));
 
        return;
-#endif
 }
 
 /* HW Lock for shared dual port PHYs */
@@ -1774,10 +1772,13 @@ no_msix:
 #endif
 }
 
+static void bullshit_handler(struct hw_trapframe *hw_tf, void *cnic_turd)
+{
+       printk("bnx2x CNIC IRQ fired.  Probably a bug!\n");
+}
+
 static int bnx2x_req_msix_irqs(struct bnx2x *bp)
 {
-panic("Not implemented");
-#if 0 // AKAROS_PORT
        int i, rc, offset = 0;
 
        /* no default status block for vf */
@@ -1791,8 +1792,15 @@ panic("Not implemented");
                }
        }
 
-       if (CNIC_SUPPORT(bp))
+       if (CNIC_SUPPORT(bp)) {
                offset++;
+               // AKAROS_PORT
+               rc = register_irq(0, bullshit_handler, 0, pci_to_tbdf(bp->pdev));
+               if (rc) {
+                       BNX2X_ERR("Fucked up getting a CNIC MSIX vector!");
+                       return -EBUSY;
+               }
+       }
 
        for_each_eth_queue(bp, i) {
                struct bnx2x_fastpath *fp = &bp->fp[i];
@@ -1827,7 +1835,6 @@ panic("Not implemented");
                            i - 1, bp->msix_table[offset + i - 1].vector);
        }
        return 0;
-#endif
 }
 
 int bnx2x_enable_msi(struct bnx2x *bp)
@@ -1871,9 +1878,8 @@ panic("Not implemented");
 
 static int bnx2x_setup_irqs(struct bnx2x *bp)
 {
-       int rc = 0;
-panic("Not implemented");
-#if 0 // AKAROS_PORT
+       return bnx2x_req_msix_irqs(bp);
+#if 0 // AKAROS_PORT we just register_irq
        if (bp->flags & USING_MSIX_FLAG &&
            !(bp->flags & USING_SINGLE_MSIX_FLAG)) {
                rc = bnx2x_req_msix_irqs(bp);
@@ -2239,6 +2245,7 @@ void bnx2x_squeeze_objects(struct bnx2x *bp)
         * we take a lock surrounding both the initial send and the CONTs,
         * as we don't want a true completion to disrupt us in the middle.
         */
+// KPF HERE (prob not init) XME (devether qlock. really the first time?)
        qlock(&bp->dev->qlock);
        rc = bnx2x_config_mcast(bp, &rparam, BNX2X_MCAST_CMD_DEL);
        if (rc < 0)
index a469eb3..7fc4109 100644 (file)
@@ -3173,8 +3173,6 @@ static void bnx2x_pf_rx_q_prep(struct bnx2x *bp,
        struct bnx2x_fastpath *fp, struct rxq_pause_params *pause,
        struct bnx2x_rxq_setup_params *rxq_init)
 {
-panic("Not implemented");
-#if 0 // AKAROS_PORT
        uint8_t max_sge = 0;
        uint16_t sge_sz = 0;
        uint16_t tpa_agg_size = 0;
@@ -3188,6 +3186,7 @@ panic("Not implemented");
                                pause->sge_th_hi + FW_PREFETCH_CNT >
                                MAX_RX_SGE_CNT * NUM_RX_SGE_PAGES);
 
+               /* TODO XME this is based on MAX_SKB_FRAGS */
                tpa_agg_size = TPA_AGG_SIZE;
                max_sge = SGE_PAGE_ALIGN(bp->dev->maxmtu) >>
                        SGE_PAGE_SHIFT;
@@ -3257,7 +3256,6 @@ panic("Not implemented");
                rxq_init->silent_removal_value = bp->afex_def_vlan_tag;
                rxq_init->silent_removal_mask = VLAN_VID_MASK;
        }
-#endif
 }
 
 static void bnx2x_pf_tx_q_prep(struct bnx2x *bp,
@@ -5424,8 +5422,6 @@ static struct bnx2x_queue_sp_obj *bnx2x_cid_to_q_obj(
 
 static void bnx2x_eq_int(struct bnx2x *bp)
 {
-panic("Not implemented");
-#if 0 // AKAROS_PORT
        uint16_t hw_cons, sw_cons, sw_prod;
        union event_ring_elem *elem;
        uint8_t echo;
@@ -5643,13 +5639,10 @@ next_spqe:
 
        /* update producer */
        bnx2x_update_eq_prod(bp, bp->eq_prod);
-#endif
 }
 
 static void bnx2x_sp_task(struct work_struct *work)
 {
-panic("Not implemented");
-#if 0 // AKAROS_PORT
        struct bnx2x *bp = container_of(work, struct bnx2x, sp_task.work);
 
        DP(BNX2X_MSG_SP, "sp task invoked\n");
@@ -5681,6 +5674,8 @@ panic("Not implemented");
                                 * we are going to change the local NAPI list.
                                 */
                                local_bh_disable();
+                               /* TODO XME: wake a ktask or o/w poll the device.  we're already
+                                * an RKM at this point */
                                napi_schedule(&bnx2x_fcoe(bp, napi));
                                local_bh_enable();
                        }
@@ -5709,7 +5704,6 @@ panic("Not implemented");
                bnx2x_link_report(bp);
                bnx2x_fw_command(bp, DRV_MSG_CODE_AFEX_VIFSET_ACK, 0);
        }
-#endif
 }
 
 void bnx2x_msix_sp_int(struct hw_trapframe *hw_tf, void *dev_instance)
@@ -8489,8 +8483,11 @@ int bnx2x_set_int_mode(struct bnx2x *bp)
        /* This tries to set up MSIX in advance, registering vectors and whatnot.
         * The bulk is in bnx2x_enable_msix.
         *
-        * We can check later if it worked after register_irq() */
-       // XME: when do we register the handler?
+        * We can check later if it worked after register_irq()
+        *
+        * We're going to try and use MSIX, so lets set it now.  Code in a few
+        * places checks this. */
+       bp->flags |= USING_MSIX_FLAG;
        return 0;
 #if 0 // AKAROS_PORT
        int rc = 0;
index a3e7818..0c941c1 100644 (file)
@@ -293,6 +293,7 @@ static inline int bnx2x_state_wait(struct bnx2x *bp, int state,
                        return 0;
                }
 
+/* HANGING HERE FOR SOME STATES */
                kthread_usleep(1000);
 
                if (bp->panic)