diff options
author | jfv <jfv@FreeBSD.org> | 2010-01-27 20:12:04 +0000 |
---|---|---|
committer | jfv <jfv@FreeBSD.org> | 2010-01-27 20:12:04 +0000 |
commit | f3b3ede9be1a20d78ac5f23b94dde56dd83faee2 (patch) | |
tree | e890e089de0e0553d8a220b6a620982f84d49fb1 | |
parent | 37cc0bd2abcf0afd8ba8923846fba6f69c0a3232 (diff) | |
download | FreeBSD-src-f3b3ede9be1a20d78ac5f23b94dde56dd83faee2.zip FreeBSD-src-f3b3ede9be1a20d78ac5f23b94dde56dd83faee2.tar.gz |
Add a link tasklet so updates can be sleepable.
-rw-r--r-- | sys/dev/e1000/if_igb.c | 28 | ||||
-rw-r--r-- | sys/dev/e1000/if_igb.h | 3 |
2 files changed, 24 insertions, 7 deletions
diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c index 92ccdae..70fc661 100644 --- a/sys/dev/e1000/if_igb.c +++ b/sys/dev/e1000/if_igb.c @@ -244,6 +244,7 @@ static void igb_add_rx_process_limit(struct adapter *, const char *, const char *, int *, int); static void igb_handle_rxtx(void *context, int pending); static void igb_handle_que(void *context, int pending); +static void igb_handle_link(void *context, int pending); /* These are MSIX only irq handlers */ static void igb_msix_que(void *); @@ -1203,6 +1204,15 @@ igb_handle_que(void *context, int pending) E1000_WRITE_REG(&adapter->hw, E1000_EIMS, que->eims); } +/* Deal with link in a sleepable context */ +static void +igb_handle_link(void *context, int pending) +{ + struct adapter *adapter = context; + + adapter->hw.mac.get_link_status = 1; + igb_update_link_status(adapter); +} /********************************************************************* * @@ -1239,10 +1249,8 @@ igb_irq_fast(void *arg) taskqueue_enqueue(adapter->tq, &adapter->rxtx_task); /* Link status change */ - if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { - adapter->hw.mac.get_link_status = 1; - igb_update_link_status(adapter); - } + if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) + taskqueue_enqueue(adapter->tq, &adapter->link_task); if (reg_icr & E1000_ICR_RXO) adapter->rx_overruns++; @@ -1352,8 +1360,7 @@ igb_msix_link(void *arg) icr = E1000_READ_REG(&adapter->hw, E1000_ICR); if (!(icr & E1000_ICR_LSC)) goto spurious; - adapter->hw.mac.get_link_status = 1; - igb_update_link_status(adapter); + taskqueue_enqueue(adapter->tq, &adapter->link_task); spurious: /* Rearm */ @@ -1986,6 +1993,8 @@ igb_allocate_legacy(struct adapter *adapter) * processing contexts. */ TASK_INIT(&adapter->rxtx_task, 0, igb_handle_rxtx, adapter); + /* Make tasklet for deferred link handling */ + TASK_INIT(&adapter->link_task, 0, igb_handle_link, adapter); adapter->tq = taskqueue_create_fast("igb_taskq", M_NOWAIT, taskqueue_thread_enqueue, &adapter->tq); taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s taskq", @@ -2072,6 +2081,13 @@ igb_allocate_msix(struct adapter *adapter) } adapter->linkvec = vector; + /* Make tasklet for deferred handling */ + TASK_INIT(&adapter->link_task, 0, igb_handle_link, adapter); + adapter->tq = taskqueue_create_fast("igb_link", M_NOWAIT, + taskqueue_thread_enqueue, &adapter->tq); + taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s link", + device_get_nameunit(adapter->dev)); + return (0); } diff --git a/sys/dev/e1000/if_igb.h b/sys/dev/e1000/if_igb.h index f14d734..fbcf4a0 100644 --- a/sys/dev/e1000/if_igb.h +++ b/sys/dev/e1000/if_igb.h @@ -372,6 +372,7 @@ struct adapter { int linkvec; int link_mask; + struct task link_task; int link_irq; struct ifmedia media; @@ -383,7 +384,7 @@ struct adapter { struct mtx core_mtx; int igb_insert_vlan_header; struct task rxtx_task; - struct taskqueue *tq; /* private task queue */ + struct taskqueue *tq; /* adapter task queue */ u16 num_queues; eventhandler_tag vlan_attach; |