--- if_em.c-1.44.2.3.orig Tue Nov 9 05:06:14 2004 +++ if_em.c Fri Nov 19 19:01:11 2004 @@ -182,6 +182,9 @@ static int em_sysctl_int_delay(SYSCTL_H static void em_add_int_delay_sysctl(struct adapter *, const char *, const char *, struct em_int_delay_info *, int, int); +#if 1 +static int em_sysctl_throttle_valve(SYSCTL_HANDLER_ARGS); +#endif /********************************************************************* * FreeBSD Device Interface Entry Points @@ -358,6 +361,13 @@ em_attach(device_t dev) &adapter->tx_abs_int_delay, E1000_REG_OFFSET(&adapter->hw, TADV), em_tx_abs_int_delay_dflt); +#if 1 + SYSCTL_ADD_PROC(&adapter->sysctl_ctx, + SYSCTL_CHILDREN(adapter->sysctl_tree), OID_AUTO, + "int_throttle_valve", CTLTYPE_INT|CTLFLAG_RW, + adapter, 0, em_sysctl_throttle_valve, "IU", + "interrupt throttling rate"); +#endif } /* Parameters (to be read from user) */ @@ -403,6 +413,10 @@ em_attach(device_t dev) */ adapter->hw.report_tx_early = 1; +#if 1 +#define MAX_INTS_PER_SEC 8000 + adapter->throttle_valve = MAX_INTS_PER_SEC; +#endif if (em_allocate_pci_resources(adapter)) { printf("em%d: Allocation of PCI resources failed\n", @@ -2608,12 +2622,16 @@ em_initialize_receive_unit(struct adapte if(adapter->hw.mac_type >= em_82540) { E1000_WRITE_REG(&adapter->hw, RADV, adapter->rx_abs_int_delay.value); - +#if 1 + E1000_WRITE_REG(&adapter->hw, ITR, + 1000000000 / (adapter->throttle_valve * 256)); +#else /* Set the interrupt throttling rate. Value is calculated * as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns) */ #define MAX_INTS_PER_SEC 8000 #define DEFAULT_ITR 1000000000/(MAX_INTS_PER_SEC * 256) E1000_WRITE_REG(&adapter->hw, ITR, DEFAULT_ITR); +#endif } /* Setup the Base and Length of the Rx Descriptor Ring */ @@ -3383,4 +3401,35 @@ em_add_int_delay_sysctl(struct adapter * SYSCTL_CHILDREN(adapter->sysctl_tree), OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, info, 0, em_sysctl_int_delay, "I", description); +} + +static int +em_sysctl_throttle_valve(SYSCTL_HANDLER_ARGS) +{ + struct adapter *adapter; + int error; + u_int32_t valve; + int s; + int value; + + adapter = (struct adapter *)arg1; + valve = adapter->throttle_valve; + error = sysctl_handle_int(oidp, &valve, 0, req); + if (error != 0 || req->newptr == NULL) + return error; + adapter->throttle_valve = valve; + + s = splimp(); + + /* Set the interrupt throttling rate. Value is calculated + * as ITR = 1/(INTS_PER_SEC * 256ns) */ + if(valve > 0) + value = 1000000000/(valve * 256); + else + value = 0; + E1000_WRITE_REG(&adapter->hw, ITR, value); + + splx(s); + + return 0; } --- if_em.h-1.25.2.1.orig Fri Nov 19 19:00:03 2004 +++ if_em.h Fri Nov 19 18:18:57 2004 @@ -353,6 +353,9 @@ u_int16_t link_speed; u_int16_t link_duplex; u_int32_t smartspeed; +#if 1 + u_int32_t throttle_valve; +#endif struct em_int_delay_info tx_int_delay; struct em_int_delay_info tx_abs_int_delay; struct em_int_delay_info rx_int_delay;