summaryrefslogtreecommitdiffstats
path: root/sys/mips
diff options
context:
space:
mode:
authorjmallett <jmallett@FreeBSD.org>2010-09-25 01:18:01 +0000
committerjmallett <jmallett@FreeBSD.org>2010-09-25 01:18:01 +0000
commitdf0d735bfefbd56b7c7cbca4590c651f83e3c831 (patch)
tree71a8762ca1e70b1e2fa53c045880ca24c48261d6 /sys/mips
parentadf20f5d89c25bc46f4028a5305d8b93695e82ff (diff)
downloadFreeBSD-src-df0d735bfefbd56b7c7cbca4590c651f83e3c831.zip
FreeBSD-src-df0d735bfefbd56b7c7cbca4590c651f83e3c831.tar.gz
Handle link updates in a task.
Diffstat (limited to 'sys/mips')
-rw-r--r--sys/mips/cavium/octe/cavium-ethernet.h2
-rw-r--r--sys/mips/cavium/octe/ethernet-rgmii.c21
-rw-r--r--sys/mips/cavium/octe/ethernet-sgmii.c20
-rw-r--r--sys/mips/cavium/octe/ethernet-xaui.c20
-rw-r--r--sys/mips/cavium/octe/ethernet.c46
5 files changed, 51 insertions, 58 deletions
diff --git a/sys/mips/cavium/octe/cavium-ethernet.h b/sys/mips/cavium/octe/cavium-ethernet.h
index 0ab2680..d472719 100644
--- a/sys/mips/cavium/octe/cavium-ethernet.h
+++ b/sys/mips/cavium/octe/cavium-ethernet.h
@@ -75,6 +75,8 @@ typedef struct {
struct ifqueue tx_free_queue[16];
+ int need_link_update;
+ struct task link_task;
struct ifmedia media;
int if_flags;
diff --git a/sys/mips/cavium/octe/ethernet-rgmii.c b/sys/mips/cavium/octe/ethernet-rgmii.c
index d5d704c..ac55de8 100644
--- a/sys/mips/cavium/octe/ethernet-rgmii.c
+++ b/sys/mips/cavium/octe/ethernet-rgmii.c
@@ -136,27 +136,8 @@ static void cvm_oct_rgmii_poll(struct ifnet *ifp)
link_info = cvmx_helper_link_autoconf(priv->port);
priv->link_info = link_info.u64;
+ priv->need_link_update = 1;
mtx_unlock_spin(&global_register_lock);
-
- /* Tell Linux */
- if (link_info.s.link_up) {
-
- if_link_state_change(ifp, LINK_STATE_UP);
- if (priv->queue != -1)
- DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, queue %2d\n",
- if_name(ifp), link_info.s.speed,
- (link_info.s.full_duplex) ? "Full" : "Half",
- priv->port, priv->queue);
- else
- DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n",
- if_name(ifp), link_info.s.speed,
- (link_info.s.full_duplex) ? "Full" : "Half",
- priv->port);
- } else {
-
- if_link_state_change(ifp, LINK_STATE_DOWN);
- DEBUGPRINT("%s: Link down\n", if_name(ifp));
- }
}
diff --git a/sys/mips/cavium/octe/ethernet-sgmii.c b/sys/mips/cavium/octe/ethernet-sgmii.c
index 69549a1..17e6be7 100644
--- a/sys/mips/cavium/octe/ethernet-sgmii.c
+++ b/sys/mips/cavium/octe/ethernet-sgmii.c
@@ -93,25 +93,7 @@ static void cvm_oct_sgmii_poll(struct ifnet *ifp)
link_info = cvmx_helper_link_autoconf(priv->port);
priv->link_info = link_info.u64;
-
- /* Tell Linux */
- if (link_info.s.link_up) {
-
- if_link_state_change(ifp, LINK_STATE_UP);
- if (priv->queue != -1)
- DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, queue %2d\n",
- if_name(ifp), link_info.s.speed,
- (link_info.s.full_duplex) ? "Full" : "Half",
- priv->port, priv->queue);
- else
- DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n",
- if_name(ifp), link_info.s.speed,
- (link_info.s.full_duplex) ? "Full" : "Half",
- priv->port);
- } else {
- if_link_state_change(ifp, LINK_STATE_DOWN);
- DEBUGPRINT("%s: Link down\n", if_name(ifp));
- }
+ priv->need_link_update = 1;
}
int cvm_oct_sgmii_init(struct ifnet *ifp)
diff --git a/sys/mips/cavium/octe/ethernet-xaui.c b/sys/mips/cavium/octe/ethernet-xaui.c
index 4eb4be7..455aec6 100644
--- a/sys/mips/cavium/octe/ethernet-xaui.c
+++ b/sys/mips/cavium/octe/ethernet-xaui.c
@@ -92,25 +92,7 @@ static void cvm_oct_xaui_poll(struct ifnet *ifp)
link_info = cvmx_helper_link_autoconf(priv->port);
priv->link_info = link_info.u64;
-
- /* Tell Linux */
- if (link_info.s.link_up) {
-
- if_link_state_change(ifp, LINK_STATE_UP);
- if (priv->queue != -1)
- DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, queue %2d\n",
- if_name(ifp), link_info.s.speed,
- (link_info.s.full_duplex) ? "Full" : "Half",
- priv->port, priv->queue);
- else
- DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n",
- if_name(ifp), link_info.s.speed,
- (link_info.s.full_duplex) ? "Full" : "Half",
- priv->port);
- } else {
- if_link_state_change(ifp, LINK_STATE_DOWN);
- DEBUGPRINT("%s: Link down\n", if_name(ifp));
- }
+ priv->need_link_update = 1;
}
diff --git a/sys/mips/cavium/octe/ethernet.c b/sys/mips/cavium/octe/ethernet.c
index 1f7901f..bdcb1cb 100644
--- a/sys/mips/cavium/octe/ethernet.c
+++ b/sys/mips/cavium/octe/ethernet.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <sys/socket.h>
#include <sys/module.h>
#include <sys/smp.h>
+#include <sys/taskqueue.h>
#include <net/ethernet.h>
#include <net/if.h>
@@ -129,6 +130,40 @@ static struct callout cvm_oct_poll_timer;
*/
struct ifnet *cvm_oct_device[TOTAL_NUMBER_OF_PORTS];
+/**
+ * Task to handle link status changes.
+ */
+static struct taskqueue *cvm_oct_link_taskq;
+
+/**
+ * Function to update link status.
+ */
+static void cvm_oct_update_link(void *context, int pending)
+{
+ cvm_oct_private_t *priv = (cvm_oct_private_t *)context;
+ struct ifnet *ifp = priv->ifp;
+ cvmx_helper_link_info_t link_info;
+
+ link_info.u64 = priv->link_info;
+
+ if (link_info.s.link_up) {
+ if_link_state_change(ifp, LINK_STATE_UP);
+ if (priv->queue != -1)
+ DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, queue %2d\n",
+ if_name(ifp), link_info.s.speed,
+ (link_info.s.full_duplex) ? "Full" : "Half",
+ priv->port, priv->queue);
+ else
+ DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n",
+ if_name(ifp), link_info.s.speed,
+ (link_info.s.full_duplex) ? "Full" : "Half",
+ priv->port);
+ } else {
+ if_link_state_change(ifp, LINK_STATE_DOWN);
+ DEBUGPRINT("%s: Link down\n", if_name(ifp));
+ }
+ priv->need_link_update = 0;
+}
/**
* Periodic timer tick for slow management operations
@@ -149,6 +184,10 @@ static void cvm_do_timer(void *arg)
if (MDIO_TRYLOCK()) {
priv->poll(cvm_oct_device[port]);
MDIO_UNLOCK();
+
+ if (priv->need_link_update) {
+ taskqueue_enqueue(cvm_oct_link_taskq, &priv->link_task);
+ }
}
}
@@ -323,6 +362,11 @@ int cvm_oct_init_module(device_t bus)
memset(cvm_oct_device, 0, sizeof(cvm_oct_device));
+ cvm_oct_link_taskq = taskqueue_create("octe link", M_NOWAIT,
+ taskqueue_thread_enqueue, &cvm_oct_link_taskq);
+ taskqueue_start_threads(&cvm_oct_link_taskq, 1, PI_NET,
+ "octe link taskq");
+
/* Initialize the FAU used for counting packet buffers that need to be freed */
cvmx_fau_atomic_write32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
@@ -345,6 +389,7 @@ int cvm_oct_init_module(device_t bus)
priv->imode = CVMX_HELPER_INTERFACE_MODE_DISABLED;
priv->port = CVMX_PIP_NUM_INPUT_PORTS;
priv->queue = -1;
+ TASK_INIT(&priv->link_task, 0, cvm_oct_update_link, priv);
device_set_desc(dev, "Cavium Octeon POW Ethernet\n");
@@ -398,6 +443,7 @@ int cvm_oct_init_module(device_t bus)
priv->fau = fau - cvmx_pko_get_num_queues(port) * 4;
for (qos = 0; qos < cvmx_pko_get_num_queues(port); qos++)
cvmx_fau_atomic_write32(priv->fau+qos*4, 0);
+ TASK_INIT(&priv->link_task, 0, cvm_oct_update_link, priv);
switch (priv->imode) {
OpenPOWER on IntegriCloud