void notify_function_ptr(void *rx_data, void *tx_data, u_int8_t device_in_use) { struct igb_ring *rx_ring = (struct igb_ring *) rx_data; struct igb_ring *tx_ring = (struct igb_ring *) tx_data; struct igb_ring *xx_ring = (rx_ring != NULL) ? rx_ring : tx_ring; struct igb_adapter *adapter = netdev_priv(xx_ring->netdev); if(likely(device_in_use)) { /* We start using this device */ try_module_get(THIS_MODULE); /* ++ */ if (rx_ring != NULL) igb_irq_disable_queues(adapter, ((u64)1 << rx_ring->queue_index)); } else { /* We're done using this device */ if (rx_ring != NULL) /* I need interrupts for purging buckets when queues are not in use */ igb_irq_enable_queues(adapter, rx_ring->queue_index); module_put(THIS_MODULE); /* -- */ } if (rx_ring != NULL) rx_ring->dna.queue_in_use = device_in_use; if (tx_ring != NULL) tx_ring->dna.queue_in_use = device_in_use; if(unlikely(enable_debug)) printk("[DNA] %s(): %s@%d is %sIN use\n", __FUNCTION__, xx_ring->netdev->name, xx_ring->queue_index, device_in_use ? "" : "NOT "); }
void notify_function_ptr(void *data, u_int8_t device_in_use) { struct igb_ring *rx_ring = (struct igb_ring*)data; struct igb_adapter *adapter = netdev_priv(rx_ring->netdev); if(unlikely(enable_debug)) printk("%s(): device_in_use = %d\n",__FUNCTION__, device_in_use); /* I need interrupts for purging buckets when queues are not in use */ igb_irq_enable_queues(adapter, rx_ring->queue_index); if(likely(device_in_use)) { /* We start using this device */ try_module_get(THIS_MODULE); /* ++ */ rx_ring->dna.queue_in_use = 1; if(unlikely(enable_debug)) printk("[DNA] %s(): %s@%d is IN use\n", __FUNCTION__, rx_ring->netdev->name, rx_ring->queue_index); igb_irq_disable_queues(adapter, ((u64)1 << rx_ring->queue_index)); } else { /* We're done using this device */ /* resetting the ring */ /* we *must* reset the right direction only (doing this in userspace) dna_cleanup_rx_ring(rx_ring); dna_cleanup_tx_ring(tx_ring); */ module_put(THIS_MODULE); /* -- */ rx_ring->dna.queue_in_use = 0; igb_irq_enable_queues(adapter, rx_ring->queue_index); if(unlikely(enable_debug)) printk("[DNA] %s(): %s@%d is NOT IN use\n", __FUNCTION__, rx_ring->netdev->name, rx_ring->queue_index); } }
int wait_packet_function_ptr(void *data, int mode) { struct igb_ring *rx_ring = (struct igb_ring*)data; struct igb_adapter *adapter = netdev_priv(rx_ring->netdev); struct e1000_hw *hw = &adapter->hw; if(unlikely(enable_debug)) printk("%s(): enter [mode=%d/%s][queueId=%d][next_to_clean=%u][next_to_use=%d]\n", __FUNCTION__, mode, mode == 1 ? "enable int" : "disable int", rx_ring->queue_index, rx_ring->next_to_clean, rx_ring->next_to_use); if(!rx_ring->dna.memory_allocated) return(0); if(mode == 1 /* Enable interrupt */) { union e1000_adv_rx_desc *rx_desc; u32 staterr; u8 reg_idx = rx_ring->reg_idx; u16 i = E1000_READ_REG(hw, E1000_RDT(reg_idx)); /* Very important: update the value from the register set from userland * Here i is the last I've read (zero-copy implementation) */ if(++i == rx_ring->count) i = 0; /* Here i is the next I have to read */ rx_ring->next_to_clean = i; rx_desc = IGB_RX_DESC(rx_ring, i); prefetch(rx_desc); staterr = le32_to_cpu(rx_desc->wb.upper.status_error); if(unlikely(enable_debug)) { printk("%s(): Check if a packet is arrived [idx=%d][staterr=%d][len=%d]\n", __FUNCTION__, i, staterr, rx_desc->wb.upper.length); print_adv_rx_descr(rx_desc); } if(!(staterr & E1000_RXD_STAT_DD)) { rx_ring->dna.rx_tx.rx.interrupt_received = 0; if(!rx_ring->dna.rx_tx.rx.interrupt_enabled) { igb_irq_enable_queues(adapter, rx_ring->queue_index); if(unlikely(enable_debug)) printk("%s(): Enabled interrupts, queue = %d\n", __FUNCTION__, rx_ring->queue_index); rx_ring->dna.rx_tx.rx.interrupt_enabled = 1; if(unlikely(enable_debug)) printk("%s(): Packet not arrived yet: enabling " "interrupts, queue=%d, i=%d\n", __FUNCTION__,rx_ring->queue_index, i); } /* Refresh the value */ staterr = le32_to_cpu(rx_desc->wb.upper.status_error); } else { rx_ring->dna.rx_tx.rx.interrupt_received = 1; } if(unlikely(enable_debug)) printk("%s(): Packet received: %d\n", __FUNCTION__, staterr & E1000_RXD_STAT_DD); return(staterr & E1000_RXD_STAT_DD); } else { /* Disable interrupts */ igb_irq_disable_queues(adapter, ((u64)1 << rx_ring->queue_index)); rx_ring->dna.rx_tx.rx.interrupt_enabled = 0; if(unlikely(enable_debug)) printk("%s(): Disabled interrupts, queue = %d\n", __FUNCTION__, rx_ring->queue_index); return(0); } }