bna: Port enable disable sync and txq priority fix
Rasesh Mody [Thu, 23 Dec 2010 21:45:02 +0000 (21:45 +0000)]
Change Details:
- Fixed port enable/disable sync through a change in LL port state
machine
- Change txq->priority masking to 0x7 (3 bits) from 0x3 (2 bits)

Signed-off-by: Debashis Dutt <ddutt@brocade.com>
Signed-off-by: Rasesh Mody <rmody@brocade.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

drivers/net/bna/bna.h
drivers/net/bna/bna_ctrl.c
drivers/net/bna/bna_txrx.c
drivers/net/bna/bna_types.h

index df6676b..fd93f76 100644 (file)
@@ -390,8 +390,8 @@ void bna_mbox_send(struct bna *bna, struct bna_mbox_qe *mbox_qe);
 
 /* API for RX */
 int bna_port_mtu_get(struct bna_port *port);
-void bna_llport_admin_up(struct bna_llport *llport);
-void bna_llport_admin_down(struct bna_llport *llport);
+void bna_llport_rx_started(struct bna_llport *llport);
+void bna_llport_rx_stopped(struct bna_llport *llport);
 
 /* API for BNAD */
 void bna_port_enable(struct bna_port *port);
index 07b2659..68e4c5e 100644 (file)
@@ -59,14 +59,70 @@ bna_port_cb_link_down(struct bna_port *port, int status)
        port->link_cbfn(port->bna->bnad, BNA_LINK_DOWN);
 }
 
+static inline int
+llport_can_be_up(struct bna_llport *llport)
+{
+       int ready = 0;
+       if (llport->type == BNA_PORT_T_REGULAR)
+               ready = ((llport->flags & BNA_LLPORT_F_ADMIN_UP) &&
+                        (llport->flags & BNA_LLPORT_F_RX_STARTED) &&
+                        (llport->flags & BNA_LLPORT_F_PORT_ENABLED));
+       else
+               ready = ((llport->flags & BNA_LLPORT_F_ADMIN_UP) &&
+                        (llport->flags & BNA_LLPORT_F_RX_STARTED) &&
+                        !(llport->flags & BNA_LLPORT_F_PORT_ENABLED));
+       return ready;
+}
+
+#define llport_is_up llport_can_be_up
+
+enum bna_llport_event {
+       LLPORT_E_START                  = 1,
+       LLPORT_E_STOP                   = 2,
+       LLPORT_E_FAIL                   = 3,
+       LLPORT_E_UP                     = 4,
+       LLPORT_E_DOWN                   = 5,
+       LLPORT_E_FWRESP_UP_OK           = 6,
+       LLPORT_E_FWRESP_UP_FAIL         = 7,
+       LLPORT_E_FWRESP_DOWN            = 8
+};
+
+static void
+bna_llport_cb_port_enabled(struct bna_llport *llport)
+{
+       llport->flags |= BNA_LLPORT_F_PORT_ENABLED;
+
+       if (llport_can_be_up(llport))
+               bfa_fsm_send_event(llport, LLPORT_E_UP);
+}
+
+static void
+bna_llport_cb_port_disabled(struct bna_llport *llport)
+{
+       int llport_up = llport_is_up(llport);
+
+       llport->flags &= ~BNA_LLPORT_F_PORT_ENABLED;
+
+       if (llport_up)
+               bfa_fsm_send_event(llport, LLPORT_E_DOWN);
+}
+
 /**
  * MBOX
  */
 static int
 bna_is_aen(u8 msg_id)
 {
-       return msg_id == BFI_LL_I2H_LINK_DOWN_AEN ||
-              msg_id == BFI_LL_I2H_LINK_UP_AEN;
+       switch (msg_id) {
+       case BFI_LL_I2H_LINK_DOWN_AEN:
+       case BFI_LL_I2H_LINK_UP_AEN:
+       case BFI_LL_I2H_PORT_ENABLE_AEN:
+       case BFI_LL_I2H_PORT_DISABLE_AEN:
+               return 1;
+
+       default:
+               return 0;
+       }
 }
 
 static void
@@ -81,6 +137,12 @@ bna_mbox_aen_callback(struct bna *bna, struct bfi_mbmsg *msg)
        case BFI_LL_I2H_LINK_DOWN_AEN:
                bna_port_cb_link_down(&bna->port, aen->reason);
                break;
+       case BFI_LL_I2H_PORT_ENABLE_AEN:
+               bna_llport_cb_port_enabled(&bna->port.llport);
+               break;
+       case BFI_LL_I2H_PORT_DISABLE_AEN:
+               bna_llport_cb_port_disabled(&bna->port.llport);
+               break;
        default:
                break;
        }
@@ -251,16 +313,6 @@ static void bna_llport_start(struct bna_llport *llport);
 static void bna_llport_stop(struct bna_llport *llport);
 static void bna_llport_fail(struct bna_llport *llport);
 
-enum bna_llport_event {
-       LLPORT_E_START                  = 1,
-       LLPORT_E_STOP                   = 2,
-       LLPORT_E_FAIL                   = 3,
-       LLPORT_E_UP                     = 4,
-       LLPORT_E_DOWN                   = 5,
-       LLPORT_E_FWRESP_UP              = 6,
-       LLPORT_E_FWRESP_DOWN            = 7
-};
-
 enum bna_llport_state {
        BNA_LLPORT_STOPPED              = 1,
        BNA_LLPORT_DOWN                 = 2,
@@ -320,7 +372,7 @@ bna_llport_sm_stopped(struct bna_llport *llport,
                /* No-op */
                break;
 
-       case LLPORT_E_FWRESP_UP:
+       case LLPORT_E_FWRESP_UP_OK:
        case LLPORT_E_FWRESP_DOWN:
                /**
                 * These events are received due to flushing of mbox when
@@ -366,6 +418,7 @@ bna_llport_sm_down(struct bna_llport *llport,
 static void
 bna_llport_sm_up_resp_wait_entry(struct bna_llport *llport)
 {
+       BUG_ON(!llport_can_be_up(llport));
        /**
         * NOTE: Do not call bna_fw_llport_up() here. That will over step
         * mbox due to down_resp_wait -> up_resp_wait transition on event
@@ -390,10 +443,14 @@ bna_llport_sm_up_resp_wait(struct bna_llport *llport,
                bfa_fsm_set_state(llport, bna_llport_sm_down_resp_wait);
                break;
 
-       case LLPORT_E_FWRESP_UP:
+       case LLPORT_E_FWRESP_UP_OK:
                bfa_fsm_set_state(llport, bna_llport_sm_up);
                break;
 
+       case LLPORT_E_FWRESP_UP_FAIL:
+               bfa_fsm_set_state(llport, bna_llport_sm_down);
+               break;
+
        case LLPORT_E_FWRESP_DOWN:
                /* down_resp_wait -> up_resp_wait transition on LLPORT_E_UP */
                bna_fw_llport_up(llport);
@@ -431,11 +488,12 @@ bna_llport_sm_down_resp_wait(struct bna_llport *llport,
                bfa_fsm_set_state(llport, bna_llport_sm_up_resp_wait);
                break;
 
-       case LLPORT_E_FWRESP_UP:
+       case LLPORT_E_FWRESP_UP_OK:
                /* up_resp_wait->down_resp_wait transition on LLPORT_E_DOWN */
                bna_fw_llport_down(llport);
                break;
 
+       case LLPORT_E_FWRESP_UP_FAIL:
        case LLPORT_E_FWRESP_DOWN:
                bfa_fsm_set_state(llport, bna_llport_sm_down);
                break;
@@ -496,11 +554,12 @@ bna_llport_sm_last_resp_wait(struct bna_llport *llport,
                /* No-op */
                break;
 
-       case LLPORT_E_FWRESP_UP:
+       case LLPORT_E_FWRESP_UP_OK:
                /* up_resp_wait->last_resp_wait transition on LLPORT_T_STOP */
                bna_fw_llport_down(llport);
                break;
 
+       case LLPORT_E_FWRESP_UP_FAIL:
        case LLPORT_E_FWRESP_DOWN:
                bfa_fsm_set_state(llport, bna_llport_sm_stopped);
                break;
@@ -541,7 +600,14 @@ bna_fw_cb_llport_up(void *arg, int status)
        struct bna_llport *llport = (struct bna_llport *)arg;
 
        bfa_q_qe_init(&llport->mbox_qe.qe);
-       bfa_fsm_send_event(llport, LLPORT_E_FWRESP_UP);
+       if (status == BFI_LL_CMD_FAIL) {
+               if (llport->type == BNA_PORT_T_REGULAR)
+                       llport->flags &= ~BNA_LLPORT_F_PORT_ENABLED;
+               else
+                       llport->flags &= ~BNA_LLPORT_F_ADMIN_UP;
+               bfa_fsm_send_event(llport, LLPORT_E_FWRESP_UP_FAIL);
+       } else
+               bfa_fsm_send_event(llport, LLPORT_E_FWRESP_UP_OK);
 }
 
 static void
@@ -588,13 +654,14 @@ bna_port_cb_llport_stopped(struct bna_port *port,
 static void
 bna_llport_init(struct bna_llport *llport, struct bna *bna)
 {
-       llport->flags |= BNA_LLPORT_F_ENABLED;
+       llport->flags |= BNA_LLPORT_F_ADMIN_UP;
+       llport->flags |= BNA_LLPORT_F_PORT_ENABLED;
        llport->type = BNA_PORT_T_REGULAR;
        llport->bna = bna;
 
        llport->link_status = BNA_LINK_DOWN;
 
-       llport->admin_up_count = 0;
+       llport->rx_started_count = 0;
 
        llport->stop_cbfn = NULL;
 
@@ -606,7 +673,8 @@ bna_llport_init(struct bna_llport *llport, struct bna *bna)
 static void
 bna_llport_uninit(struct bna_llport *llport)
 {
-       llport->flags &= ~BNA_LLPORT_F_ENABLED;
+       llport->flags &= ~BNA_LLPORT_F_ADMIN_UP;
+       llport->flags &= ~BNA_LLPORT_F_PORT_ENABLED;
 
        llport->bna = NULL;
 }
@@ -628,6 +696,8 @@ bna_llport_stop(struct bna_llport *llport)
 static void
 bna_llport_fail(struct bna_llport *llport)
 {
+       /* Reset the physical port status to enabled */
+       llport->flags |= BNA_LLPORT_F_PORT_ENABLED;
        bfa_fsm_send_event(llport, LLPORT_E_FAIL);
 }
 
@@ -638,25 +708,31 @@ bna_llport_state_get(struct bna_llport *llport)
 }
 
 void
-bna_llport_admin_up(struct bna_llport *llport)
+bna_llport_rx_started(struct bna_llport *llport)
 {
-       llport->admin_up_count++;
+       llport->rx_started_count++;
+
+       if (llport->rx_started_count == 1) {
+
+               llport->flags |= BNA_LLPORT_F_RX_STARTED;
 
-       if (llport->admin_up_count == 1) {
-               llport->flags |= BNA_LLPORT_F_RX_ENABLED;
-               if (llport->flags & BNA_LLPORT_F_ENABLED)
+               if (llport_can_be_up(llport))
                        bfa_fsm_send_event(llport, LLPORT_E_UP);
        }
 }
 
 void
-bna_llport_admin_down(struct bna_llport *llport)
+bna_llport_rx_stopped(struct bna_llport *llport)
 {
-       llport->admin_up_count--;
+       int llport_up = llport_is_up(llport);
+
+       llport->rx_started_count--;
+
+       if (llport->rx_started_count == 0) {
+
+               llport->flags &= ~BNA_LLPORT_F_RX_STARTED;
 
-       if (llport->admin_up_count == 0) {
-               llport->flags &= ~BNA_LLPORT_F_RX_ENABLED;
-               if (llport->flags & BNA_LLPORT_F_ENABLED)
+               if (llport_up)
                        bfa_fsm_send_event(llport, LLPORT_E_DOWN);
        }
 }
index ad93fdb..fb6cf1f 100644 (file)
@@ -1947,7 +1947,7 @@ bna_rx_sm_started_entry(struct bna_rx *rx)
                bna_ib_ack(&rxp->cq.ib->door_bell, 0);
        }
 
-       bna_llport_admin_up(&rx->bna->port.llport);
+       bna_llport_rx_started(&rx->bna->port.llport);
 }
 
 void
@@ -1955,13 +1955,13 @@ bna_rx_sm_started(struct bna_rx *rx, enum bna_rx_event event)
 {
        switch (event) {
        case RX_E_FAIL:
-               bna_llport_admin_down(&rx->bna->port.llport);
+               bna_llport_rx_stopped(&rx->bna->port.llport);
                bfa_fsm_set_state(rx, bna_rx_sm_stopped);
                rx_ib_fail(rx);
                bna_rxf_fail(&rx->rxf);
                break;
        case RX_E_STOP:
-               bna_llport_admin_down(&rx->bna->port.llport);
+               bna_llport_rx_stopped(&rx->bna->port.llport);
                bfa_fsm_set_state(rx, bna_rx_sm_rxf_stop_wait);
                break;
        default:
@@ -3373,7 +3373,7 @@ __bna_txq_start(struct bna_tx *tx, struct bna_txq *txq)
 
        txq_cfg.cns_ptr2_n_q_state = BNA_Q_IDLE_STATE;
        txq_cfg.nxt_qid_n_fid_n_pri = (((tx->txf.txf_id & 0x3f) << 3) |
-                       (txq->priority & 0x3));
+                       (txq->priority & 0x7));
        txq_cfg.wvc_n_cquota_n_rquota =
                        ((((u32)BFI_TX_MAX_WRR_QUOTA & 0xfff) << 12) |
                        (BFI_TX_MAX_WRR_QUOTA & 0xfff));
index 6877310..d79fd98 100644 (file)
@@ -249,8 +249,9 @@ enum bna_link_status {
 };
 
 enum bna_llport_flags {
-       BNA_LLPORT_F_ENABLED    = 1,
-       BNA_LLPORT_F_RX_ENABLED = 2
+       BNA_LLPORT_F_ADMIN_UP           = 1,
+       BNA_LLPORT_F_PORT_ENABLED       = 2,
+       BNA_LLPORT_F_RX_STARTED         = 4
 };
 
 enum bna_port_flags {
@@ -405,7 +406,7 @@ struct bna_llport {
 
        enum bna_link_status link_status;
 
-       int                     admin_up_count;
+       int                     rx_started_count;
 
        void (*stop_cbfn)(struct bna_port *, enum bna_cb_status);