Commit bf091f3f authored by Shannon Nelson's avatar Shannon Nelson Committed by David S. Miller

sunvnet: straighten up message event handling logic

The use of gotos for handling the incoming events made this code
harder to read and support than it should be.  This patch straightens
out and clears up the logic.
Signed-off-by: default avatarShannon Nelson <shannon.nelson@oracle.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fd263fb6
...@@ -738,41 +738,37 @@ static int vnet_event_napi(struct vnet_port *port, int budget) ...@@ -738,41 +738,37 @@ static int vnet_event_napi(struct vnet_port *port, int budget)
struct vio_driver_state *vio = &port->vio; struct vio_driver_state *vio = &port->vio;
int tx_wakeup, err; int tx_wakeup, err;
int npkts = 0; int npkts = 0;
int event = (port->rx_event & LDC_EVENT_RESET);
/* we don't expect any other bits */
ldc_ctrl: BUG_ON(port->rx_event & ~(LDC_EVENT_DATA_READY |
if (unlikely(event == LDC_EVENT_RESET || LDC_EVENT_RESET |
event == LDC_EVENT_UP)) { LDC_EVENT_UP));
vio_link_state_change(vio, event);
/* RESET takes precedent over any other event */
if (event == LDC_EVENT_RESET) { if (port->rx_event & LDC_EVENT_RESET) {
vnet_port_reset(port); vio_link_state_change(vio, LDC_EVENT_RESET);
vio_port_up(vio); vnet_port_reset(port);
vio_port_up(vio);
/* If the device is running but its tx queue was
* stopped (due to flow control), restart it. /* If the device is running but its tx queue was
* This is necessary since vnet_port_reset() * stopped (due to flow control), restart it.
* clears the tx drings and thus we may never get * This is necessary since vnet_port_reset()
* back a VIO_TYPE_DATA ACK packet - which is * clears the tx drings and thus we may never get
* the normal mechanism to restart the tx queue. * back a VIO_TYPE_DATA ACK packet - which is
*/ * the normal mechanism to restart the tx queue.
if (netif_running(dev)) */
maybe_tx_wakeup(port); if (netif_running(dev))
} maybe_tx_wakeup(port);
port->rx_event = 0; port->rx_event = 0;
return 0; return 0;
} }
/* We may have multiple LDC events in rx_event. Unroll send_events() */
event = (port->rx_event & LDC_EVENT_UP);
port->rx_event &= ~(LDC_EVENT_RESET | LDC_EVENT_UP);
if (event == LDC_EVENT_UP)
goto ldc_ctrl;
event = port->rx_event;
if (!(event & LDC_EVENT_DATA_READY))
return 0;
/* we dont expect any other bits than RESET, UP, DATA_READY */ if (port->rx_event & LDC_EVENT_UP) {
BUG_ON(event != LDC_EVENT_DATA_READY); vio_link_state_change(vio, LDC_EVENT_UP);
port->rx_event = 0;
return 0;
}
err = 0; err = 0;
tx_wakeup = 0; tx_wakeup = 0;
...@@ -795,25 +791,25 @@ static int vnet_event_napi(struct vnet_port *port, int budget) ...@@ -795,25 +791,25 @@ static int vnet_event_napi(struct vnet_port *port, int budget)
pkt->start_idx = vio_dring_next(dr, pkt->start_idx = vio_dring_next(dr,
port->napi_stop_idx); port->napi_stop_idx);
pkt->end_idx = -1; pkt->end_idx = -1;
goto napi_resume; } else {
} err = ldc_read(vio->lp, &msgbuf, sizeof(msgbuf));
err = ldc_read(vio->lp, &msgbuf, sizeof(msgbuf)); if (unlikely(err < 0)) {
if (unlikely(err < 0)) { if (err == -ECONNRESET)
if (err == -ECONNRESET) vio_conn_reset(vio);
vio_conn_reset(vio); break;
break; }
if (err == 0)
break;
viodbg(DATA, "TAG [%02x:%02x:%04x:%08x]\n",
msgbuf.tag.type,
msgbuf.tag.stype,
msgbuf.tag.stype_env,
msgbuf.tag.sid);
err = vio_validate_sid(vio, &msgbuf.tag);
if (err < 0)
break;
} }
if (err == 0)
break;
viodbg(DATA, "TAG [%02x:%02x:%04x:%08x]\n",
msgbuf.tag.type,
msgbuf.tag.stype,
msgbuf.tag.stype_env,
msgbuf.tag.sid);
err = vio_validate_sid(vio, &msgbuf.tag);
if (err < 0)
break;
napi_resume:
if (likely(msgbuf.tag.type == VIO_TYPE_DATA)) { if (likely(msgbuf.tag.type == VIO_TYPE_DATA)) {
if (msgbuf.tag.stype == VIO_SUBTYPE_INFO) { if (msgbuf.tag.stype == VIO_SUBTYPE_INFO) {
if (!sunvnet_port_is_up_common(port)) { if (!sunvnet_port_is_up_common(port)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment