From: Michael Bringmann <michael.bringm...@lsi.com> Signed-off-by: Michael Bringmann <michael.bringm...@lsi.com> --- drivers/rapidio/devices/lsi/axxia-rio-ds.c | 539 ++++++++++++++------------- drivers/rapidio/devices/lsi/axxia-rio-ds.h | 330 +--------------- drivers/rapidio/devices/lsi/axxia-rio-irq.c | 6 +- drivers/rapidio/devices/lsi/axxia-rio.c | 6 +- drivers/rapidio/devices/lsi/axxia-rio.h | 3 +- include/linux/rio-axxia.h | 322 ++++++++++++++++ 6 files changed, 634 insertions(+), 572 deletions(-) create mode 100644 include/linux/rio-axxia.h
diff --git a/drivers/rapidio/devices/lsi/axxia-rio-ds.c b/drivers/rapidio/devices/lsi/axxia-rio-ds.c index 2627b07..0e5be61 100755 --- a/drivers/rapidio/devices/lsi/axxia-rio-ds.c +++ b/drivers/rapidio/devices/lsi/axxia-rio-ds.c @@ -44,24 +44,23 @@ /* #define ALLOC_BUF_BY_KERNEL 1 */ static inline void __ib_virt_m_dbg( - struct rio_ds_ibds_vsid_m_stats *ptr_ib_stats, + struct axxia_rio_ds_ibds_vsid_m_stats *ptr_ib_stats, u32 virt_m_stat); static inline void __ob_dse_dbg( - struct rio_ds_obds_dse_stats *ptr_ob_stats, + struct axxia_rio_ds_obds_dse_stats *ptr_ob_stats, u32 dse_stat); static inline void __ob_dse_dw_dbg( - struct rio_ds_obds_dse_stats *ptr_ob_stats, + struct axxia_rio_ds_obds_dse_stats *ptr_ob_stats, u32 dw0); static inline void __ib_dse_dw_dbg( - struct rio_ds_ibds_vsid_m_stats *ptr_ib_stats, + struct axxia_rio_ds_ibds_vsid_m_stats *ptr_ib_stats, u32 dw0); - static inline void __ib_virt_m_dbg( - struct rio_ds_ibds_vsid_m_stats *ptr_ib_stats, + struct axxia_rio_ds_ibds_vsid_m_stats *ptr_ib_stats, u32 virt_m_stat) { if (virt_m_stat & IB_VIRT_M_STAT_ERROR_MASK) { @@ -92,7 +91,7 @@ static inline void __ib_virt_m_dbg( } static inline void __ob_dse_dbg( - struct rio_ds_obds_dse_stats *ptr_ob_stats, + struct axxia_rio_ds_obds_dse_stats *ptr_ob_stats, u32 dse_stat) { if (dse_stat & OB_DSE_STAT_ERROR_MASK) { @@ -111,7 +110,7 @@ static inline void __ob_dse_dbg( } static inline void __ob_dse_dw_dbg( - struct rio_ds_obds_dse_stats *ptr_ob_stats, + struct axxia_rio_ds_obds_dse_stats *ptr_ob_stats, u32 dw0) { if (dw0 & OB_DSE_DESC_ERROR_MASK) { @@ -123,7 +122,7 @@ static inline void __ob_dse_dw_dbg( } static inline void __ib_dse_dw_dbg( - struct rio_ds_ibds_vsid_m_stats *ptr_ib_stats, + struct axxia_rio_ds_ibds_vsid_m_stats *ptr_ib_stats, u32 dw0) { if (dw0 & IB_DSE_DESC_ERROR_MASK) { @@ -154,16 +153,16 @@ static inline void __ib_dse_dw_dbg( * Returns %0 on success ****************************************************************************/ int axxia_data_stream_global_cfg( - struct rio_mport *mport, + struct rio_mport *mport, int mtu, int ibds_avsid_mapping) { - struct rio_priv *priv = mport->priv; - struct rio_ds_priv *ptr_ds_priv = &(priv->ds_priv_data); - struct ibds_virt_m_cfg *ptr_virt_m_cfg; - struct rio_obds_dse_cfg *ptr_dse_cfg; - int reg_val; - u32 mtu_value = 0; + struct rio_priv *priv = mport->priv; + struct axxia_rio_ds_cfg *ptr_ds_cfg = &(priv->ds_cfg_data); + struct axxia_ibds_virt_m_cfg *ptr_virt_m_cfg; + struct axxia_rio_obds_dse_cfg *ptr_dse_cfg; + int reg_val; + u32 mtu_value = 0; int i; /* sanity check */ @@ -176,13 +175,13 @@ int axxia_data_stream_global_cfg( ** IBDS ALIAS M is used. */ for (i = 0; i < RIO_MAX_NUM_IBDS_VSID_M; i++) { - ptr_virt_m_cfg = &(ptr_ds_priv->ibds_vsid_m_cfg[i]); + ptr_virt_m_cfg = &(ptr_ds_cfg->ibds_vsid_m_cfg[i]); if (ptr_virt_m_cfg->in_use == RIO_DS_TRUE) return -EINVAL; } for (i = 0; i < RIO_MAX_NUM_OBDS_DSE; i++) { - ptr_dse_cfg = &(ptr_ds_priv->obds_dse_cfg[i]); + ptr_dse_cfg = &(ptr_ds_cfg->obds_dse_cfg[i]); if (ptr_dse_cfg->in_use == RIO_DS_TRUE) return -EINVAL; } @@ -203,8 +202,8 @@ int axxia_data_stream_global_cfg( __rio_local_write_config_32(mport, RAB_IBDS_VSID_ALIAS, reg_val); /* save information in the system */ - ptr_ds_priv->mtu = mtu; - ptr_ds_priv->ibds_avsid_mapping = ibds_avsid_mapping; + ptr_ds_cfg->mtu = mtu; + ptr_ds_cfg->ibds_avsid_mapping = ibds_avsid_mapping; return 0; } @@ -240,7 +239,6 @@ int axxia_open_ob_data_stream( int num_header_entries, int num_data_entries) { - struct rio_priv *priv = mport->priv; int rc = 0; struct rio_priv *priv = mport->priv; @@ -280,19 +278,20 @@ int open_ob_data_stream( int num_data_entries) { struct rio_priv *priv = mport->priv; - struct rio_ds_priv *ptr_ds_priv = &(priv->ds_priv_data); - struct rio_obds_dse_cfg *ptr_dse_cfg; - u32 temp; - void *ptr; + struct axxia_rio_ds_priv *ptr_ds_priv = &(priv->ds_priv_data); + struct axxia_rio_ds_cfg *ptr_ds_cfg = &(priv->ds_cfg_data); + struct axxia_rio_obds_dse_cfg *ptr_dse_cfg; + u32 temp; + void *ptr; struct rio_irq_handler *h; - u32 des_chain_start_addr_phy_low, des_chain_start_addr_phy_hi; - u32 dse_ctrl; + u32 des_chain_start_addr_phy_low, des_chain_start_addr_phy_hi; + u32 dse_ctrl; unsigned long dse_chain_start_addr_phy; int rc = 0; /* Check if the dse_id is in use */ - ptr_dse_cfg = &(ptr_ds_priv->obds_dse_cfg[dse_id]); + ptr_dse_cfg = &(ptr_ds_cfg->obds_dse_cfg[dse_id]); if (ptr_dse_cfg->in_use) return -EINVAL; @@ -302,7 +301,7 @@ int open_ob_data_stream( return -EINVAL; } else { ptr = kzalloc((num_header_entries * - sizeof(struct rio_ds_hdr_desc) + + sizeof(struct axxia_rio_ds_hdr_desc) + RIO_DS_DESC_ALIGNMENT), GFP_KERNEL); if (!ptr) { @@ -329,9 +328,9 @@ int open_ob_data_stream( /* allocate data descriptors */ if (num_data_entries) { ptr = kzalloc((num_data_entries * - sizeof(struct rio_ods_data_desc) + - RIO_DS_DESC_ALIGNMENT), - GFP_KERNEL); + sizeof(struct axxia_rio_ods_data_desc) + + RIO_DS_DESC_ALIGNMENT), + GFP_KERNEL); if (!ptr) return -ENOMEM; @@ -406,11 +405,10 @@ int open_ob_data_stream( * * This function adds a descriptor and a data buffer to a descriptor chain. * - * To keep the correct order of a data stream, data descripors of the same - * stream ID goes to the same DSE descriptor chain. However, each DSE can - * handle multiple data streams. To make it simple, a data stream with - * stream ID goes to (stream ID % (totoal number of DSEs)) descriptor - * chain. + * To keep the correct order of a data stream, data descriptors of the same + * stream ID goes to the same DSE descriptor chain. However, each DSE can + * handle multiple data streams. To make it simple, a data stream with + * stream ID goes to (stream ID % (totoal number of DSEs)) descriptor chain. * * Under the current implementation, only header descriptor is supported. * @@ -440,18 +438,20 @@ int axxia_add_ob_data_stream( int data_len) { struct rio_priv *priv = mport->priv; - struct rio_ds_priv *ptr_ds_priv; - struct rio_obds_dse_cfg *ptr_dse_cfg; - struct rio_ds_hdr_desc *ptr_hdr_desc; - u16 hdr_write_ptr, next_desc_index; + struct axxia_rio_ds_priv *ptr_ds_priv; + struct axxia_rio_ds_cfg *ptr_ds_cfg; + struct axxia_rio_obds_dse_cfg *ptr_dse_cfg; + struct axxia_rio_ds_hdr_desc *ptr_hdr_desc; + u16 hdr_write_ptr, next_desc_index; u16 dse_id; u32 dse_ctrl, dse_stat; - u32 next_desc_high, data_buf_high; + u32 next_desc_high, data_buf_high; unsigned long next_desc_ptr_phy, data_buf_phy; int rc = 0; /* sanity check - TBD */ ptr_ds_priv = &(priv->ds_priv_data); + ptr_ds_cfg = &(priv->ds_cfg_data); /* ** There are maximum of 16 DSEs, each DSE can handle one @@ -459,8 +459,8 @@ int axxia_add_ob_data_stream( ** different stream_id can be chained in the same ** descriptor chain. */ - dse_id = (stream_id % (ptr_ds_priv->num_obds_dses)); - ptr_dse_cfg = &(ptr_ds_priv->obds_dse_cfg[dse_id]); + dse_id = (stream_id % (ptr_ds_cfg->num_obds_dses)); + ptr_dse_cfg = &(ptr_ds_cfg->obds_dse_cfg[dse_id]); /* if the DSE has not been configured, return an error */ if (ptr_dse_cfg->in_use == RIO_DS_FALSE) @@ -579,7 +579,7 @@ int axxia_add_ob_data_stream( __rio_local_read_config_32(mport, RAB_OBDSE_STAT(dse_id), &dse_stat); - /* if (dse_stat & OB_DSE_STAT_SLEEPING) TBD */ { + /* if (dse_stat & OB_DSE_STAT_SLEEPING) TBD */ { /* start, wake up the engine */ __rio_local_read_config_32(mport, RAB_OBDSE_CTRL(dse_id), @@ -619,11 +619,12 @@ EXPORT_SYMBOL(axxia_add_ob_data_stream); */ void ob_dse_irq_handler(struct rio_irq_handler *h, u32 state) { - struct rio_mport *mport = h->mport; - struct rio_priv *priv = mport->priv; - struct rio_ds_priv *ptr_ds_priv; - struct rio_obds_dse_cfg *ptr_dse_cfg; - struct rio_ds_hdr_desc *ptr_hdr_desc = h->data; + struct rio_mport *mport = h->mport; + struct rio_priv *priv = mport->priv; + struct axxia_rio_ds_priv *ptr_ds_priv; + struct axxia_rio_ds_cfg *ptr_ds_cfg; + struct axxia_rio_obds_dse_cfg *ptr_dse_cfg; + struct axxia_rio_ds_hdr_desc *ptr_hdr_desc = h->data; u32 dse_stat, dse_id; u16 hdr_read_ptr; u32 is_hdr_desc_done = 1; @@ -648,7 +649,6 @@ void ob_dse_irq_handler(struct rio_irq_handler *h, u32 state) /* find out DSE stats */ __rio_local_read_config_32(mport, RAB_OBDSE_STAT(dse_id), &dse_stat); - /* ** The ARM could also got interrupted with dse_stat sticky status ** bits not being set. TBD @@ -657,12 +657,13 @@ void ob_dse_irq_handler(struct rio_irq_handler *h, u32 state) return; ptr_ds_priv = &(priv->ds_priv_data); + ptr_ds_cfg = &(priv->ds_cfg_data); /** * Wait for all pending transactions to finish before doing descriptor * updates */ - ptr_dse_cfg = &(ptr_ds_priv->obds_dse_cfg[dse_id]); + ptr_dse_cfg = &(ptr_ds_cfg->obds_dse_cfg[dse_id]); spin_lock_irqsave(&ptr_dse_cfg->lock, flags); /* @@ -744,15 +745,16 @@ int axxia_close_ob_data_stream( struct rio_mport *mport, int dse_id) { - struct rio_priv *priv = mport->priv; - struct rio_ds_priv *ptr_ds_priv = &(priv->ds_priv_data); - struct rio_obds_dse_cfg *ptr_dse_cfg; - struct rio_ds_hdr_desc *ptr_hdr_desc; + struct rio_priv *priv = mport->priv; + struct axxia_rio_ds_priv *ptr_ds_priv = &(priv->ds_priv_data); + struct axxia_rio_ds_cfg *ptr_ds_cfg = &(priv->ds_cfg_data); + struct axxia_rio_obds_dse_cfg *ptr_dse_cfg; + struct axxia_rio_ds_hdr_desc *ptr_hdr_desc; u32 dse_ctrl, i; axxia_api_lock(priv); - ptr_dse_cfg = &(ptr_ds_priv->obds_dse_cfg[dse_id]); + ptr_dse_cfg = &(ptr_ds_cfg->obds_dse_cfg[dse_id]); if (ptr_dse_cfg->in_use == RIO_DS_FALSE) { axxia_api_unlock(priv); @@ -872,10 +874,11 @@ int open_ib_data_stream( int desc_dbuf_size, int num_entries) { - struct rio_priv *priv = mport->priv; - struct rio_ds_priv *ptr_ds_priv = &(priv->ds_priv_data); - struct ibds_virt_m_cfg *ptr_virt_m_cfg; - struct rio_ids_data_desc *ptr_data_desc; + struct rio_priv *priv = mport->priv; + struct axxia_rio_ds_priv *ptr_ds_priv = &(priv->ds_priv_data); + struct axxia_rio_ds_cfg *ptr_ds_cfg = &(priv->ds_cfg_data); + struct axxia_ibds_virt_m_cfg *ptr_virt_m_cfg; + struct axxia_rio_ids_data_desc *ptr_data_desc; struct rio_irq_handler *h; void *ptr; u32 temp; @@ -895,36 +898,36 @@ int open_ib_data_stream( ** 6 - 32K, 7 - 64K */ switch (desc_dbuf_size) { - case RIO_IBDS_DATA_BUF_1K: - hw_desc_size = 1; - break; + case RIO_IBDS_DATA_BUF_1K: + hw_desc_size = 1; + break; - case RIO_IBDS_DATA_BUF_2K: - hw_desc_size = 2; - break; + case RIO_IBDS_DATA_BUF_2K: + hw_desc_size = 2; + break; - case RIO_IBDS_DATA_BUF_4K: - hw_desc_size = 3; - break; + case RIO_IBDS_DATA_BUF_4K: + hw_desc_size = 3; + break; - case RIO_IBDS_DATA_BUF_8K: - hw_desc_size = 4; - break; + case RIO_IBDS_DATA_BUF_8K: + hw_desc_size = 4; + break; - case RIO_IBDS_DATA_BUF_16K: - hw_desc_size = 5; - break; + case RIO_IBDS_DATA_BUF_16K: + hw_desc_size = 5; + break; - case RIO_IBDS_DATA_BUF_32K: - hw_desc_size = 6; - break; + case RIO_IBDS_DATA_BUF_32K: + hw_desc_size = 6; + break; - case RIO_IBDS_DATA_BUF_64K: - hw_desc_size = 0; - break; + case RIO_IBDS_DATA_BUF_64K: + hw_desc_size = 0; + break; - default: - return -EINVAL; + default: + return -EINVAL; } /* TBD ASR_SPINLOCK_INTERRUPT_DISABLE(&priv->ioLock, lflags); */ @@ -947,7 +950,7 @@ int open_ib_data_stream( ** 4K, 8K, 16K, 32K, or 64K. */ /* get a internal VSID M based on virt_vsid */ - ptr_virt_m_cfg = &(ptr_ds_priv->ibds_vsid_m_cfg[virt_vsid]); + ptr_virt_m_cfg = &(ptr_ds_cfg->ibds_vsid_m_cfg[virt_vsid]); /* ** If the descriptor chain is already opened, return OK @@ -965,8 +968,8 @@ int open_ib_data_stream( /* allocate data descriptor buffers */ ptr = kzalloc((num_int_entries) * - sizeof(struct rio_ids_data_desc) + - sizeof(struct rio_ids_data_desc) + + sizeof(struct axxia_rio_ids_data_desc) + + sizeof(struct axxia_rio_ids_data_desc) + RIO_DS_DESC_ALIGNMENT, GFP_KERNEL); if (ptr == NULL) { @@ -983,7 +986,7 @@ int open_ib_data_stream( } ptr_virt_m_cfg->ptr_ibds_data_desc = - (struct rio_ids_data_desc *)ptr; + (struct axxia_rio_ids_data_desc *)ptr; } ptr_virt_m_cfg->in_use = RIO_DS_TRUE; @@ -995,7 +998,7 @@ int open_ib_data_stream( /* init the data descriptor */ memset((void *)ptr_data_desc, 0, - sizeof(struct rio_ids_data_desc)); + sizeof(struct axxia_rio_ids_data_desc)); /* dw0 - desc_size, bits [4:6] ** the desc_size is not actual size, it is numbered value @@ -1121,20 +1124,20 @@ int axxia_add_ibds_buffer( void *buf, int buf_size) { - struct rio_priv *priv = mport->priv; - struct rio_ds_priv *ptr_ds_priv = &(priv->ds_priv_data); - struct ibds_virt_m_cfg *ptr_virt_m_cfg; - struct rio_ids_data_desc *ptr_data_desc; - u32 m_id; - u8 found_one = RIO_DS_FALSE; - u32 vsid_addr_reg; - u32 vsid; - u16 virt_vsid; - u32 alias_reg; - u32 vsid_m_stats; - - unsigned long data_addr_phy; - u32 data_addr_hi; + struct rio_priv *priv = mport->priv; + struct axxia_rio_ds_cfg *ptr_ds_cfg = &(priv->ds_cfg_data); + struct axxia_ibds_virt_m_cfg *ptr_virt_m_cfg; + struct axxia_rio_ids_data_desc *ptr_data_desc; + u32 m_id; + u8 found_one = RIO_DS_FALSE; + u32 vsid_addr_reg; + u32 vsid; + u16 virt_vsid; + u32 alias_reg; + u32 vsid_m_stats; + + unsigned long data_addr_phy; + u32 data_addr_hi; unsigned long iflags; @@ -1154,7 +1157,7 @@ int axxia_add_ibds_buffer( for (m_id = 0; m_id < RIO_MAX_NUM_IBDS_VSID_M; m_id++) { - ptr_virt_m_cfg = &(ptr_ds_priv->ibds_vsid_m_cfg[m_id]); + ptr_virt_m_cfg = &(ptr_ds_cfg->ibds_vsid_m_cfg[m_id]); if ((ptr_virt_m_cfg->virt_vsid == virt_vsid) && (ptr_virt_m_cfg->in_use == RIO_DS_TRUE)) { @@ -1257,21 +1260,21 @@ EXPORT_SYMBOL(axxia_add_ibds_buffer); * * Handles inbound data streaming interrupts. Executes a callback, * if available, on each successfully received data stream - * */ void ib_dse_vsid_m_irq_handler(struct rio_irq_handler *h, u32 state) { - struct rio_mport *mport = h->mport; - struct rio_priv *priv = mport->priv; - struct rio_ds_priv *ptr_ds_priv = &(priv->ds_priv_data); - struct ibds_virt_m_cfg *ptr_virt_m_cfg; - struct rio_ids_data_desc *ptr_data_desc; - u32 dse_stat, vsid_m_stats; - u8 virt_vsid, dse_id; - u16 data_write_ptr; + struct rio_mport *mport = h->mport; + struct rio_priv *priv = mport->priv; + struct axxia_rio_ds_priv *ptr_ds_priv = &(priv->ds_priv_data); + struct axxia_rio_ds_cfg *ptr_ds_cfg = &(priv->ds_cfg_data); + struct axxia_ibds_virt_m_cfg *ptr_virt_m_cfg; + struct axxia_rio_ids_data_desc *ptr_data_desc; + u32 dse_stat, vsid_m_stats; + u8 virt_vsid, dse_id; + u16 data_write_ptr; unsigned long flags; - u32 is_desc_done = 1; - u8 i; + u32 is_desc_done = 1; + u8 i; for (i = 0; i < 32; i++) { /* if the corresponding interrupt bit is set */ @@ -1289,130 +1292,139 @@ void ib_dse_vsid_m_irq_handler(struct rio_irq_handler *h, u32 state) */ if ((vsid_m_stats & 0x1FF)) { - /* check if the chain transfer complete */ + /* Check if the chain transfer complete */ ptr_virt_m_cfg = - &(ptr_ds_priv->ibds_vsid_m_cfg[virt_vsid]); + &(ptr_ds_cfg->ibds_vsid_m_cfg[virt_vsid]); spin_lock_irqsave(&ptr_virt_m_cfg->lock, flags); /* check errors */ - __ib_virt_m_dbg(&(ptr_ds_priv->ib_vsid_m_stats[virt_vsid]), - vsid_m_stats); - - - if (vsid_m_stats & IB_VIRT_M_STAT_FETCH_ERR) { - /* - ** If transaction pending bit is not set an timeout - ** is also not set, - ** that means that PDU was successfully written - ** into AXI memory - ** and nothing needs to be done. - ** If transaction pending bit is set or timeout is set, - ** engine needs - ** to be reset. After disabling engine, when - ** transaction pending - ** gets reset, engine is ready to be enabled again. - */ - - /* check if there is a corresponding DSE - ** that handles this vsid */ - for (dse_id = 0; - dse_id < RIO_MAX_NUM_IBDS_DSE; - dse_id++) { - __rio_local_read_config_32(mport, - RAB_IBDSE_STAT(dse_id), - &dse_stat); - - if (((dse_stat & IB_DSE_STAT_TRANS_PENDING) || - (dse_stat & IB_DSE_STAT_TIMEOUT)) && - ((dse_stat & IB_DSE_VSID_IN_USED) == virt_vsid)) { - /* - ** BZ43821 - SW workaround for the IBDS - ** descriptor fetch error - ** When S/W sees the descriptor fetch error - ** being indicated in - ** status bits, introduce a delay and then - ** disable the engine - ** and enable the engine again. - ** With this the next incoming packet for that - ** engine would - ** not get corrupted. - */ - ndelay(5); + __ib_virt_m_dbg( + &(ptr_ds_priv->ib_vsid_m_stats[virt_vsid]), + vsid_m_stats); - /* disable the engine */ - __rio_local_write_config_32(mport, + if (vsid_m_stats & IB_VIRT_M_STAT_FETCH_ERR) { + /* + ** If transaction pending bit is not + ** set and timeout is also not set, + ** that means that PDU was successfully + ** written into AXI memory and nothing + ** needs to be done. + ** If transaction pending bit is set + ** or timeout is set, engine needs to + ** be reset. After disabling engine, + ** when transaction pending gets reset, + ** engine is ready to be enabled again. + */ + + /* Check if there is a corresponding + ** DSE that handles this vsid */ + for (dse_id = 0; + dse_id < RIO_MAX_NUM_IBDS_DSE; + dse_id++) { + __rio_local_read_config_32( + mport, + RAB_IBDSE_STAT(dse_id), + &dse_stat); + + if (((dse_stat & IB_DSE_STAT_TRANS_PENDING) || + (dse_stat & IB_DSE_STAT_TIMEOUT)) && + ((dse_stat & IB_DSE_VSID_IN_USED) == virt_vsid)) { + /* + ** BZ43821 - SW workaround for + ** the IBDS descriptor fetch + ** error + ** When S/W sees the descriptor + ** fetch error being indicated + ** in status bits, introduce a + ** delay and then disable the + ** engine and enable the engine + ** again. + ** With this the next incoming + ** packet for that engine would + ** not get corrupted. + */ + ndelay(5); + + /* Disable the engine */ + __rio_local_write_config_32( + mport, RAB_IBDSE_CTRL(dse_id), 0); - /*should wait till the pending bit is reset?*/ + /* Should wait till the pending + ** bit is reset?*/ - /* enable the engine again */ - __rio_local_write_config_32(mport, + /* Enable the engine again */ + __rio_local_write_config_32( + mport, RAB_IBDSE_CTRL(dse_id), 1); - - break; + break; + } + } } - } - } + /* In case of timeout error, if not alreaday + ** disabled, descriptor prefetch logic should + ** be disabled and associated descriptor start + ** address needs to be set for VSID PDUs to be + ** assembled again. Engine should be disabled, + ** once transaction pending gets reset, engine + ** can be enabled again. + ** TBD + */ - /* In case of timeout error, if not alreaday disabled, descriptor - ** prefetch logic should be disabled and associated descriptor - ** start address needs to be set for VSID PDUs to be - ** eassembled again. Engine should be disabled, once - ** transaction pending gets reset, engine can be enabled again. - ** TBD - */ + /* Process maximum number MAX_NUM_PROC_IBDS_DESC + ** transactions */ + data_write_ptr = ptr_virt_m_cfg->data_write_ptr; - /* process maximum number of MAX_NUM_PROC_IBDS_DESC transactions */ - data_write_ptr = ptr_virt_m_cfg->data_write_ptr; + ptr_data_desc = + &(ptr_virt_m_cfg->ptr_ibds_data_desc[data_write_ptr]); - ptr_data_desc = - &(ptr_virt_m_cfg->ptr_ibds_data_desc[data_write_ptr]); + /* Get the done bit of the data descriptor */ + is_desc_done = + (ptr_data_desc->dw0 & IB_DSE_DESC_DONE); - /* get the done bit of the data descriptor */ - is_desc_done = (ptr_data_desc->dw0 & IB_DSE_DESC_DONE); + while (is_desc_done) { + ptr_virt_m_cfg->num_hw_written_bufs++; + __ib_dse_dw_dbg( + &(ptr_ds_priv->ib_vsid_m_stats[virt_vsid]), + ptr_data_desc->dw0); - while (is_desc_done) { - ptr_virt_m_cfg->num_hw_written_bufs++; - __ib_dse_dw_dbg( - &(ptr_ds_priv->ib_vsid_m_stats[virt_vsid]), - ptr_data_desc->dw0); + if (data_write_ptr == + (ptr_virt_m_cfg->max_num_data_desc-1)) + data_write_ptr = 0; + else + data_write_ptr++; - if (data_write_ptr == - (ptr_virt_m_cfg->max_num_data_desc-1)) - data_write_ptr = 0; - else - data_write_ptr++; - - /* set the valid bit to be invalid */ - ptr_data_desc->dw0 &= 0xFFFFFFFE; + /* set the valid bit to be invalid */ + ptr_data_desc->dw0 &= 0xFFFFFFFE; - ptr_data_desc = - &(ptr_virt_m_cfg->ptr_ibds_data_desc[data_write_ptr]); + ptr_data_desc = + &(ptr_virt_m_cfg->ptr_ibds_data_desc[data_write_ptr]); - is_desc_done = (ptr_data_desc->dw0 & IB_DSE_DESC_DONE); - } + is_desc_done = (ptr_data_desc->dw0 & IB_DSE_DESC_DONE); + } - ptr_virt_m_cfg->data_write_ptr = data_write_ptr; + ptr_virt_m_cfg->data_write_ptr = data_write_ptr; - /* call back - TBD */ + /* Call back - TBD */ - /* clear the interrupt bit? - TBD */ - /* clear the virt_m stats bit */ - if (vsid_m_stats & 0x2) { - __rio_local_write_config_32(mport, - RAB_IBVIRT_M_STAT(virt_vsid), - vsid_m_stats); - } - __rio_local_read_config_32(mport, - RAB_IBVIRT_M_STAT(virt_vsid), - &vsid_m_stats); + /* Clear the interrupt bit? - TBD */ + /* Clear the virt_m stats bit */ + if (vsid_m_stats & 0x2) { + __rio_local_write_config_32(mport, + RAB_IBVIRT_M_STAT(virt_vsid), + vsid_m_stats); + } + __rio_local_read_config_32(mport, + RAB_IBVIRT_M_STAT(virt_vsid), + &vsid_m_stats); - spin_unlock_irqrestore(&ptr_virt_m_cfg->lock, flags); - } + spin_unlock_irqrestore(&ptr_virt_m_cfg->lock, + flags); + } } } @@ -1442,19 +1454,18 @@ void *axxia_get_ibds_data( int *ptr_pdu_length, int *ptr_stream_id) { - struct rio_priv *priv = mport->priv; - struct rio_ds_priv *ptr_ds_priv = &(priv->ds_priv_data); - struct ibds_virt_m_cfg *ptr_virt_m_cfg; - struct rio_ids_data_desc *ptr_data_desc; - u32 m_id, data_read_ptr; - u8 found_one = RIO_DS_FALSE; - void *user_buf; - u32 pdu_length; + struct rio_priv *priv = mport->priv; + struct axxia_rio_ds_cfg *ptr_ds_cfg = &(priv->ds_cfg_data); + struct axxia_ibds_virt_m_cfg *ptr_virt_m_cfg; + struct axxia_rio_ids_data_desc *ptr_data_desc; + u32 m_id, data_read_ptr; + u8 found_one = RIO_DS_FALSE; + void *user_buf; + u32 pdu_length; unsigned long iflags; - u32 vsid; - u16 virt_vsid; - u32 alias_reg; - + u32 vsid; + u16 virt_vsid; + u32 alias_reg; /* find the mapping between incoming VSID and internal VSID */ __rio_local_read_config_32(mport, RAB_IBDS_VSID_ALIAS, &alias_reg); @@ -1465,11 +1476,10 @@ void *axxia_get_ibds_data( /* calculate the virtual M index */ (void)axxio_virt_vsid_convert(vsid, alias_reg, &virt_vsid); - /* search through the virtual M table to find the one that ** has the same source_id and cos */ for (m_id = 0; m_id < RIO_MAX_NUM_IBDS_VSID_M; m_id++) { - ptr_virt_m_cfg = &(ptr_ds_priv->ibds_vsid_m_cfg[m_id]); + ptr_virt_m_cfg = &(ptr_ds_cfg->ibds_vsid_m_cfg[m_id]); if ((ptr_virt_m_cfg->virt_vsid == virt_vsid) && (ptr_virt_m_cfg->in_use == RIO_DS_TRUE)) { @@ -1481,7 +1491,7 @@ void *axxia_get_ibds_data( if (found_one == RIO_DS_FALSE) return NULL; - /* check if the there are buffers that are written - semaphore ?*/ + /* Check if the there are buffers that are written - semaphore ?*/ if (ptr_virt_m_cfg->num_hw_written_bufs < 1) return NULL; @@ -1489,11 +1499,11 @@ void *axxia_get_ibds_data( data_read_ptr = ptr_virt_m_cfg->data_read_ptr; - /* get the data descriptor */ + /* Get the data descriptor */ ptr_data_desc = &(ptr_virt_m_cfg->ptr_ibds_data_desc[data_read_ptr]); - /* check if the source_id and cos matches */ + /* Check if the source_id and cos matches */ if ((((ptr_data_desc->dw0 >> 16) & 0xFFFF) != source_id) || ((ptr_data_desc->dw2 & 0xFF0000) >> 16) != cos) { spin_unlock_irqrestore(&ptr_virt_m_cfg->lock, iflags); @@ -1532,7 +1542,6 @@ void *axxia_get_ibds_data( return user_buf; } - } EXPORT_SYMBOL(axxia_get_ibds_data); @@ -1552,18 +1561,19 @@ int axxia_close_ib_data_stream( int source_id, int cos) { - struct rio_priv *priv = mport->priv; - struct rio_ds_priv *ptr_ds_priv = &(priv->ds_priv_data); - struct ibds_virt_m_cfg *ptr_virt_m_cfg; - u8 find_ava_virt_m = RIO_DS_FALSE; + struct rio_priv *priv = mport->priv; + struct axxia_rio_ds_priv *ptr_ds_priv = &(priv->ds_priv_data); + struct axxia_rio_ds_cfg *ptr_ds_cfg = &(priv->ds_cfg_data); + struct axxia_ibds_virt_m_cfg *ptr_virt_m_cfg; + struct axxia_rio_ids_data_desc *ptr_data_desc; + u8 find_ava_virt_m = RIO_DS_FALSE; u8 i; - struct rio_ids_data_desc *ptr_data_desc; u8 virt_vsid; axxia_api_lock(priv); - for (i = 0; i < (ptr_ds_priv->num_ibds_virtual_m); i++) { - ptr_virt_m_cfg = &(ptr_ds_priv->ibds_vsid_m_cfg[i]); + for (i = 0; i < (ptr_ds_cfg->num_ibds_virtual_m); i++) { + ptr_virt_m_cfg = &(ptr_ds_cfg->ibds_vsid_m_cfg[i]); if ((ptr_virt_m_cfg->in_use == RIO_DS_TRUE) && (ptr_virt_m_cfg->source_id == source_id) && @@ -1594,7 +1604,7 @@ int axxia_close_ib_data_stream( for (i = 0; i < ptr_virt_m_cfg->max_num_data_desc; i++) { ptr_data_desc = &(ptr_virt_m_cfg->ptr_ibds_data_desc[i]); - /* if an application has not yet retrieve the data */ + /* if an application has not yet retrieved the data */ if (((ptr_data_desc->buf_status == DS_DBUF_ALLOC)) && (ptr_data_desc->virt_data_buf)) { kfree((void *)ptr_data_desc->virt_data_buf); @@ -1714,11 +1724,11 @@ void release_ib_ds(struct rio_irq_handler *h) ****************************************************************************/ int axxia_parse_dtb_ds( struct platform_device *dev, - struct rio_ds_dtb_info *ptr_ds_dtb_info) + struct axxia_rio_ds_dtb_info *ptr_ds_dtb_info) { u32 pval; - memset(ptr_ds_dtb_info, 0, sizeof(struct rio_ds_dtb_info)); + memset(ptr_ds_dtb_info, 0, sizeof(struct axxia_rio_ds_dtb_info)); /* set the default of ds_enable to be 1 if it is on 55XX */ ptr_ds_dtb_info->ds_enabled = 1; @@ -1744,13 +1754,14 @@ int axxia_parse_dtb_ds( ****************************************************************************/ int axxia_cfg_ds( struct rio_mport *mport, - struct rio_ds_dtb_info *ptr_ds_dtb_info) + struct axxia_rio_ds_dtb_info *ptr_ds_dtb_info) { - struct rio_priv *priv = mport->priv; - struct rio_ds_priv *ptr_ds_priv = &(priv->ds_priv_data); - u8 dse_id; - u32 reg_val; - u8 ds_capable; + struct rio_priv *priv = mport->priv; + struct axxia_rio_ds_priv *ptr_ds_priv = &(priv->ds_priv_data); + struct axxia_rio_ds_cfg *ptr_ds_cfg = &(priv->ds_cfg_data); + u8 dse_id; + u32 reg_val; + u8 ds_capable; /* ** Check if the ASIC supports data streaming feature. @@ -1773,12 +1784,12 @@ int axxia_cfg_ds( ptr_ds_priv->is_use_ds_feature = 0; } - ptr_ds_priv->num_obds_dses = RIO_MAX_NUM_OBDS_DSE; - ptr_ds_priv->num_ibds_virtual_m = RIO_MAX_NUM_IBDS_VSID_M; - ptr_ds_priv->num_ibds_dses = RIO_MAX_NUM_IBDS_DSE; + ptr_ds_cfg->num_obds_dses = RIO_MAX_NUM_OBDS_DSE; + ptr_ds_cfg->num_ibds_virtual_m = RIO_MAX_NUM_IBDS_VSID_M; + ptr_ds_cfg->num_ibds_dses = RIO_MAX_NUM_IBDS_DSE; /* Enable all VIRTM */ - for (dse_id = 0; dse_id < ptr_ds_priv->num_ibds_dses; dse_id++) { + for (dse_id = 0; dse_id < ptr_ds_cfg->num_ibds_dses; dse_id++) { __rio_local_write_config_32(mport, RAB_IBDSE_CTRL(dse_id), 1); @@ -1806,7 +1817,7 @@ void axxia_rio_ds_port_irq_init( struct rio_mport *mport) { struct rio_priv *priv = mport->priv; - struct rio_ds_priv *ptr_ds_priv; + struct axxia_rio_ds_priv *ptr_ds_priv; int i; ptr_ds_priv = &(priv->ds_priv_data); @@ -1846,3 +1857,27 @@ void axxia_rio_ds_port_irq_init( ptr_ds_priv->ob_dse_irq[i].release_fn = release_ib_ds; } } + +/***************************************************************************** + * axxia_mport_to_ds_cfg - + * + * @mport: the master port + * + * Returns %<ptr> of type 'struct axxia_rio_ds_cfg' on success + * NULL on failure + ****************************************************************************/ +struct axxia_rio_ds_cfg* +axxia_mport_to_ds_cfg( + struct rio_mport *mport) +{ + if (mport) { + struct rio_priv *priv = mport->priv; + if (priv) + return &priv->ds_cfg_data; + else + return NULL; + } else { + return NULL; + } +} +EXPORT_SYMBOL(axxia_mport_to_ds_cfg); diff --git a/drivers/rapidio/devices/lsi/axxia-rio-ds.h b/drivers/rapidio/devices/lsi/axxia-rio-ds.h index 25633c0..139037e 100755 --- a/drivers/rapidio/devices/lsi/axxia-rio-ds.h +++ b/drivers/rapidio/devices/lsi/axxia-rio-ds.h @@ -24,233 +24,27 @@ #include <linux/interrupt.h> #include <linux/kfifo.h> +#include <linux/rio-axxia.h> + /* #define DS_DEBUG 1 */ #define USE_IOCTRL 1 /****************************************************************************** #defines ******************************************************************************/ -#define RIO_IBDS_DATA_BUF_1K (1<<10) -#define RIO_IBDS_DATA_BUF_2K (1<<11) -#define RIO_IBDS_DATA_BUF_4K (1<<12) -#define RIO_IBDS_DATA_BUF_8K (1<<13) -#define RIO_IBDS_DATA_BUF_16K (1<<14) -#define RIO_IBDS_DATA_BUF_32K (1<<15) -#define RIO_IBDS_DATA_BUF_64K (1<<16) - - -#define RIO_DS_DATA_BUF_64K (0) /* HW uses 0 for 64K */ - -#define RIO_MAX_NUM_OBDS_DSE (16) -#define RIO_MAX_NUM_IBDS_DSE (16) -#define RIO_MAX_NUM_IBDS_VSID_M (32) - -#define RC_TBD (-1) - -#define RIO_DS_TRUE (1) -#define RIO_DS_FALSE (0) - -#define IOCTL_BUF_SIZE (4096) -#define MAX_NUM_PROC_IBDS_DESC (10) - -#define DS_DBUF_FREED (0) -#define DS_DBUF_ALLOC (1) -#define DS_DBUF_RETRIEVED (2) - #define AXXIA_SRIO_RAB_VER_VAL_55xx (0x00211021) #define AXXIA_SRIO_RAB_VER_VAL_55xx_X7v1P1 (0x00221013) +/****************************************************************************** + #Type definitions +******************************************************************************/ -/* -** Data Streaming registers -*/ -#define IB_DS_INT_EN (1<<7) -#define OB_DS_INT_EN (1<<8) -#define OB_DSE_WAKEUP (2) -#define OB_DSE_ENABLE (1) -#define OB_DSE_PREFETCH (4) - -#define IB_VSID_M_PREFETCH_ENABLE (2) -#define IB_VSID_M_PREFETCH_WAKEUP (4) - -#define RAB_OBDSE_CTRL(n) (RAB_REG_BASE + (0x2d28 + (0xC*(n)))) -#define RAB_OBDSE_STAT(n) (RAB_REG_BASE + (0x2d28 + (0xC*(n)))+0x4) -#define RAB_OBDSE_DESC_ADDR(n) (RAB_REG_BASE + (0x2d28 + (0xC*(n)))+0x8) - -#define RAB_IBVIRT_M_STAT(n) (RAB_REG_BASE + (0x2ef0 + (0x4*(n)))) - -#define RAB_IBDSE_CTRL(n) \ - (RAB_REG_BASE + (0x2a20 + (0x8 * (n)))) -#define RAB_IBDSE_STAT(n) \ - (RAB_REG_BASE + (0x2a20 + (0x8 * (n))) + 0x4) - -#define RAB_IBDS_VSID_ADDR_LOW(n) (RAB_REG_BASE + (0x2b28 + (0x8*(n)))) -#define RAB_IBDS_VSID_ADDR_HI(n) (RAB_REG_BASE + (0x2b28 + (0x8*(n)))+0x4) - -#define RAB_IBDS_VSID_ALIAS (RAB_REG_BASE + 0x2a1c) -#define GRIO_DSI_CAR (0x3c) -#define GRIO_DSLL_CCSR (0x48) - -#define RIO_DS_DESC_ALIGNMENT (1 << 5) - -/* stats */ -#define IB_VIRT_M_STAT_ERROR_MASK 0x3FC -#define IB_VIRT_M_STAT_SLEEPING (1<<11) -#define IB_VIRT_M_STAT_TRAN_PENDING (1<<10) -#define IB_VIRT_M_STAT_PDU_DROPPED (1 << 9) -#define IB_VIRT_M_STAT_SEG_LOSS (1 << 8) -#define IB_VIRT_M_STAT_MTU_LEN_MIS_ERR (1 << 7) -#define IB_VIRT_M_STAT_PDU_LEN_MIS_ERR (1 << 6) -#define IB_VIRT_M_STAT_TRANS_ERR (1 << 5) -#define IB_VIRT_M_STAT_UPDATE_ERR (1 << 4) -#define IB_VIRT_M_STAT_TIMEOUT_ERR (1 << 3) -#define IB_VIRT_M_STAT_FETCH_ERR (1 << 2) - -#define IB_DSE_DESC_ERROR_MASK 0xC00 -#define IB_DSE_DESC_AXI_ERR (1 << 11) -#define IB_DSE_DESC_DS_ERR (1 << 10) -#define IB_DSE_DESC_DONE (1 << 9) - -#define IB_DSE_VSID_IN_USED 0x3F -#define IB_DSE_STAT_TRANS_PENDING (1 << 6) -#define IB_DSE_STAT_TIMEOUT (1 << 7) - -#define OB_DSE_STAT_ERROR_MASK 0x3C -#define OB_DSE_STAT_TRANS_ERR (1 << 5) -#define OB_DSE_STAT_UPDATE_ERR (1 << 4) -#define OB_DSE_STAT_DESC_ERR (1 << 3) -#define OB_DSE_STAT_FETCH_ERR (1 << 2) -#define OB_DSE_STAT_SLEEPING (1<<8) - -#define OB_DSE_DESC_ERROR_MASK 0x400 -#define OB_HDR_DESC_AXI_ERR (1 << 10) -#define OB_HDR_DESC_DONE (1 << 8) - - -/* data streaming dtb related information */ -struct rio_ds_dtb_info { +struct axxia_rio_ds_dtb_info { int ds_enabled; - #if 0 - int num_inb_virtaul_m; /* number of inbound virtual M */ - int num_outb_dses; /* number of outbound DSEs */ - int inb_num_data_descs; /* number of inbound data descriptors */ - int outb_num_hdr_descs; /* number of outbound header descriptors */ - int outb_num_data_descs; /* number of outbound data descriptors */ - #endif -}; - -/* -** The following data structure defines data streaming descriptors -** -** The HW requires that the desc_addr has to be 8 words alignment, thus -** additional words are added for SW usage -*/ -/* outbound data descriptor */ -struct rio_ods_data_desc { - u32 dw0; - u32 dw1; - u32 dw2; - u32 dw3; - - /* SW usage */ - u32 virt_data_buf; - u32 sw1; - u32 sw2; - u32 sw3; -}; - -/* inbound data descriptor */ -struct rio_ids_data_desc { - u32 dw0; - u32 dw1; - u32 dw2; - u32 dw3; - u32 dw4; - - /* SW usage */ - u32 virt_data_buf; - u32 buf_status; - u32 sw2; -}; - -/* -** The following data structure defines data streaming header descriptors -** only used in outbound -*/ -struct rio_ds_hdr_desc { - u32 dw0; - u32 dw1; - u32 dw2; - u32 dw3; - u32 dw4; - - /* SW usage */ - u32 virt_data_buf; - u32 buf_status; - u32 sw2; -}; - -/* -** OBDS DSE configuration -*/ -struct rio_obds_dse_cfg { - u8 in_use; /* if the DSE is in_use */ - u8 cos; - u16 dest_id; - u16 stream_id; - spinlock_t lock; - u8 irqEnabled; - char name[16]; - - /* header descriptor */ - u16 num_hdr_desc_free; - u16 max_num_hdr_desc; - - /* data descriptor */ - u16 num_data_desc_free; - u16 max_num_data_desc; - u16 hdr_read_ptr; - u16 hdr_write_ptr; - u8 first_hdr_desc; - - u16 data_read_ptr; - u16 data_write_ptr; - u8 first_data_desc; - - struct rio_ds_hdr_desc *ptr_obds_hdr_desc; - struct rio_ods_data_desc *ptr_obds_data_desc; -}; - -/* -** IBDS configuration -*/ -struct ibds_virt_m_cfg { - spinlock_t lock; - u32 in_use; /* if the DSE is in_use */ - u8 cos; - u16 dest_id; - u16 stream_id; - u16 source_id; - char name[16]; - - u16 num_desc_free; - u16 max_num_data_desc; - u16 data_read_ptr; - u16 data_write_ptr; - - struct rio_ids_data_desc *ptr_ibds_data_desc; - u32 desc_dbuf_size; - u32 buf_add_ptr; - u32 num_hw_written_bufs; - - u32 alias_reg_value; - u16 virt_vsid; - u16 num_data_streams; - }; /* Outbound data stream stats */ -struct rio_ds_obds_dse_stats { +struct axxia_rio_ds_obds_dse_stats { u32 num_desc_chain_transferred; u32 num_desc_transferred; u32 num_desc_err; @@ -261,7 +55,7 @@ struct rio_ds_obds_dse_stats { }; /* Inbound data stream stats */ -struct rio_ds_ibds_vsid_m_stats { +struct axxia_rio_ds_ibds_vsid_m_stats { u32 num_desc_chain_transferred; u32 num_desc_transferred; u32 num_desc_fetch_err; @@ -281,128 +75,38 @@ struct rio_ds_ibds_vsid_m_stats { ** The following data structure defines private data used by data streaming ** feature */ -struct rio_ds_priv { - /* IBDS */ - u16 mtu; - u32 ibds_avsid_mapping; - u16 num_ibds_dses;/* TBR */ - u16 num_ibds_virtual_m;/* TBR */ - struct ibds_virt_m_cfg ibds_vsid_m_cfg[RIO_MAX_NUM_IBDS_VSID_M]; - - /* OBDS */ - u16 num_obds_dses; /* TBR */ - struct rio_obds_dse_cfg obds_dse_cfg[RIO_MAX_NUM_OBDS_DSE]; - +struct axxia_rio_ds_priv { struct rio_irq_handler ob_dse_irq[RIO_MAX_NUM_OBDS_DSE]; struct rio_irq_handler ib_dse_vsid_irq[RIO_MAX_NUM_IBDS_VSID_M]; - struct rio_ds_ibds_vsid_m_stats - ib_vsid_m_stats[RIO_MAX_NUM_IBDS_VSID_M]; - struct rio_ds_obds_dse_stats ob_dse_stats[RIO_MAX_NUM_OBDS_DSE]; + struct axxia_rio_ds_ibds_vsid_m_stats ib_vsid_m_stats[RIO_MAX_NUM_IBDS_VSID_M]; + struct axxia_rio_ds_obds_dse_stats ob_dse_stats[RIO_MAX_NUM_OBDS_DSE]; u8 is_use_ds_feature; }; +/****************************************************************************** + Platform Driver APIs +******************************************************************************/ + /* Platform driver initialization */ extern int axxia_parse_dtb_ds( struct platform_device *dev, - struct rio_ds_dtb_info *ptr_ds_dtb_info); + struct axxia_rio_ds_dtb_info *ptr_ds_dtb_info); extern int axxia_cfg_ds( struct rio_mport *mport, - struct rio_ds_dtb_info *ptr_ds_dtb_info); + struct axxia_rio_ds_dtb_info *ptr_ds_dtb_info); extern void axxia_rio_ds_port_irq_init( struct rio_mport *mport); -/* open an OBDS data stream */ -extern int axxia_open_ob_data_stream( - struct rio_mport *mport, - void *dev_id, - int dse_id, - int num_header_entries, - int num_data_entries); - -extern int open_ob_data_stream( - struct rio_mport *mport, - void *dev_id, - int dse_id, - int num_header_entries, - int num_data_entries); - -/* add user's data */ -extern int axxia_add_ob_data_stream( - struct rio_mport *mport, - int dest_id, - int stream_id, - int cos, - int priority, - int is_hdr_desc, - void *buffer, - int data_len); - /* handle outbound data streaming DSE interrupt */ void ob_dse_irq_handler(struct rio_irq_handler *h, u32 state); /* handle inbound VSID interrupt */ void ib_dse_vsid_m_irq_handler(struct rio_irq_handler *h, u32 state); -/* data streaming global configuration */ -extern int axxia_data_stream_global_cfg( - struct rio_mport *mport, - int mtu, - int ibds_avsid_mapping); - -/* open IBDS data stream */ -extern int axxia_open_ib_data_stream( - struct rio_mport *mport, - void *dev_id, - int source_id, - int cos, - int desc_dbuf_size, - int num_entries); - -int open_ib_data_stream( - struct rio_mport *mport, - void *dev_id, - int source_id, - int cos, - int desc_dbuf_size, - int num_entries); - -/* add IBDS data buffer */ -extern int axxia_add_ibds_buffer( - struct rio_mport *mport, - int source_id, - int cos, - void *buf, - int buf_size); - -/* get IBDS data */ -extern void *axxia_get_ibds_data( - struct rio_mport *mport, - int source_id, - int cos, - int *ptr_pdu_length, - int *ptr_stream_id); - -/* convert VSID to internal VSID */ -int axxio_virt_vsid_convert( - u32 vsid, - u32 alias_reg, - u16 *ptr_virt_vsid); - -/* close IBDS data streaming */ -extern int axxia_close_ib_data_stream( - struct rio_mport *mport, - int source_id, - int cos); - -/* close OBDS data streaming */ -extern int axxia_close_ob_data_stream( - struct rio_mport *mport, - int dse_id); - void release_ob_ds(struct rio_irq_handler *h); void release_ib_ds(struct rio_irq_handler *h); diff --git a/drivers/rapidio/devices/lsi/axxia-rio-irq.c b/drivers/rapidio/devices/lsi/axxia-rio-irq.c index 3c88941..5922ee1 100644 --- a/drivers/rapidio/devices/lsi/axxia-rio-irq.c +++ b/drivers/rapidio/devices/lsi/axxia-rio-irq.c @@ -953,13 +953,13 @@ static void release_dme(struct kref *kref) if (me->desc) { for (i = 0, desc = me->desc; i < me->entries; i++, desc++) { - if (desc->msg_virt != NULL) + if (desc->msg_virt) kfree(desc->msg_virt); } kfree(me->desc); } - if (me->descriptors != NULL) + if (me->descriptors) kfree(me->descriptors); if (!priv->internalDesc) { @@ -1083,7 +1083,7 @@ static void release_mbox(struct kref *kref) priv->ib_dme_irq[mb->mbox_no].irq_state_mask = 0; - if (mb->virt_buffer != NULL) + if (mb->virt_buffer) kfree(mb->virt_buffer); kfree(mb); diff --git a/drivers/rapidio/devices/lsi/axxia-rio.c b/drivers/rapidio/devices/lsi/axxia-rio.c index 48d36a3..26c9fd9 100644 --- a/drivers/rapidio/devices/lsi/axxia-rio.c +++ b/drivers/rapidio/devices/lsi/axxia-rio.c @@ -793,7 +793,7 @@ void axxia_rio_set_mport_disc_mode(struct rio_mport *mport) __rio_local_write_config_32(mport, EPC_PNADIDCSR(priv->portNdx), result); - dev_dbg(priv->dev, "Port%dAltDevIdmCSR set to 0x%X for main port\n", + dev_dbg(priv->dev, "Port%dAltDevIdmCSR set to 0x%X\n", priv->portNdx, CONFIG_RAPIDIO_SECOND_DEST_ID); } #else @@ -811,7 +811,7 @@ void axxia_rio_set_mport_disc_mode(struct rio_mport *mport) __rio_local_write_config_32(mport, EPC_PNADIDCSR(priv->portNdx), result); - dev_dbg(priv->dev, "Port%dAltDevIdmCSR set to 0x%X for main port\n", + dev_dbg(priv->dev, "Port%dAltDevIdmCSR set to 0x%X\n", priv->portNdx, result); } #endif @@ -1615,7 +1615,7 @@ static int axxia_rio_setup(struct platform_device *dev) int numObDmes[2] = { 0, }, outbDmes[2] = { 0, }; int numIbDmes[2] = { 0, }, inbDmes[2] = { 0, }; struct event_regs linkdown_reset = { 0, }; - struct rio_ds_dtb_info ds_dtb_info; /* data_streaming */ + struct axxia_rio_ds_dtb_info ds_dtb_info; /* data_streaming */ /* Get address boundaries, etc. from DTB */ if (rio_parse_dtb(dev, &ndx, &law_start, &law_size, ®s, diff --git a/drivers/rapidio/devices/lsi/axxia-rio.h b/drivers/rapidio/devices/lsi/axxia-rio.h index 4d751d5..4dc62dc 100644 --- a/drivers/rapidio/devices/lsi/axxia-rio.h +++ b/drivers/rapidio/devices/lsi/axxia-rio.h @@ -544,7 +544,8 @@ struct rio_priv { void (*port_notify_cb)(struct rio_mport *mport); /* data_streaming */ - struct rio_ds_priv ds_priv_data; + struct axxia_rio_ds_priv ds_priv_data; + struct axxia_rio_ds_cfg ds_cfg_data; }; diff --git a/include/linux/rio-axxia.h b/include/linux/rio-axxia.h new file mode 100644 index 0000000..60c0edb --- /dev/null +++ b/include/linux/rio-axxia.h @@ -0,0 +1,322 @@ +#ifndef __RIO_AXXIA_H__ +#define __RIO_AXXIA_H__ + +#include <linux/device.h> +#include <linux/of_platform.h> +#include <linux/rio.h> +#include <linux/rio_drv.h> +#include <linux/rio_dio.h> +#include <linux/interrupt.h> +#include <linux/kfifo.h> + +/****************************************************************************** +** Buffer sizes, Device limits, and other limits +******************************************************************************/ + +#define RIO_IBDS_DATA_BUF_1K (1<<10) +#define RIO_IBDS_DATA_BUF_2K (1<<11) +#define RIO_IBDS_DATA_BUF_4K (1<<12) +#define RIO_IBDS_DATA_BUF_8K (1<<13) +#define RIO_IBDS_DATA_BUF_16K (1<<14) +#define RIO_IBDS_DATA_BUF_32K (1<<15) +#define RIO_IBDS_DATA_BUF_64K (1<<16) + +#define RIO_DS_DATA_BUF_64K (0) /* HW uses 0 for 64K */ + +#define RIO_MAX_NUM_OBDS_DSE (16) +#define RIO_MAX_NUM_IBDS_DSE (16) +#define RIO_MAX_NUM_IBDS_VSID_M (32) + +#define RC_TBD (-1) + +#define RIO_DS_TRUE (1) +#define RIO_DS_FALSE (0) + +#define IOCTL_BUF_SIZE (4096) +#define MAX_NUM_PROC_IBDS_DESC (10) + +#define DS_DBUF_FREED (0) +#define DS_DBUF_ALLOC (1) +#define DS_DBUF_RETRIEVED (2) + +/****************************************************************************** +** Data Streaming registers +******************************************************************************/ + +#define IB_DS_INT_EN (1<<7) +#define OB_DS_INT_EN (1<<8) +#define OB_DSE_WAKEUP (2) +#define OB_DSE_ENABLE (1) +#define OB_DSE_PREFETCH (4) + +#define IB_VSID_M_PREFETCH_ENABLE (2) +#define IB_VSID_M_PREFETCH_WAKEUP (4) + +#define RAB_OBDSE_CTRL(n) (RAB_REG_BASE + (0x2d28 + (0xC*(n)))) +#define RAB_OBDSE_STAT(n) (RAB_REG_BASE + (0x2d28 + (0xC*(n)))+0x4) +#define RAB_OBDSE_DESC_ADDR(n) (RAB_REG_BASE + (0x2d28 + (0xC*(n)))+0x8) + +#define RAB_IBVIRT_M_STAT(n) (RAB_REG_BASE + (0x2ef0 + (0x4*(n)))) + +#define RAB_IBDSE_CTRL(n) \ + (RAB_REG_BASE + (0x2a20 + (0x8 * (n)))) +#define RAB_IBDSE_STAT(n) \ + (RAB_REG_BASE + (0x2a20 + (0x8 * (n))) + 0x4) + +#define RAB_IBDS_VSID_ADDR_LOW(n) (RAB_REG_BASE + (0x2b28 + (0x8*(n)))) +#define RAB_IBDS_VSID_ADDR_HI(n) (RAB_REG_BASE + (0x2b28 + (0x8*(n)))+0x4) + +#define RAB_IBDS_VSID_ALIAS (RAB_REG_BASE + 0x2a1c) +#define GRIO_DSI_CAR (0x3c) +#define GRIO_DSLL_CCSR (0x48) + +#define RIO_DS_DESC_ALIGNMENT (1 << 5) + +/* stats */ +#define IB_VIRT_M_STAT_ERROR_MASK 0x3FC +#define IB_VIRT_M_STAT_SLEEPING (1<<11) +#define IB_VIRT_M_STAT_TRAN_PENDING (1<<10) +#define IB_VIRT_M_STAT_PDU_DROPPED (1 << 9) +#define IB_VIRT_M_STAT_SEG_LOSS (1 << 8) +#define IB_VIRT_M_STAT_MTU_LEN_MIS_ERR (1 << 7) +#define IB_VIRT_M_STAT_PDU_LEN_MIS_ERR (1 << 6) +#define IB_VIRT_M_STAT_TRANS_ERR (1 << 5) +#define IB_VIRT_M_STAT_UPDATE_ERR (1 << 4) +#define IB_VIRT_M_STAT_TIMEOUT_ERR (1 << 3) +#define IB_VIRT_M_STAT_FETCH_ERR (1 << 2) + +#define IB_DSE_DESC_ERROR_MASK 0xC00 +#define IB_DSE_DESC_AXI_ERR (1 << 11) +#define IB_DSE_DESC_DS_ERR (1 << 10) +#define IB_DSE_DESC_DONE (1 << 9) + +#define IB_DSE_VSID_IN_USED 0x3F +#define IB_DSE_STAT_TRANS_PENDING (1 << 6) +#define IB_DSE_STAT_TIMEOUT (1 << 7) + +#define OB_DSE_STAT_ERROR_MASK 0x3C +#define OB_DSE_STAT_TRANS_ERR (1 << 5) +#define OB_DSE_STAT_UPDATE_ERR (1 << 4) +#define OB_DSE_STAT_DESC_ERR (1 << 3) +#define OB_DSE_STAT_FETCH_ERR (1 << 2) +#define OB_DSE_STAT_SLEEPING (1<<8) + +#define OB_DSE_DESC_ERROR_MASK 0x400 +#define OB_HDR_DESC_AXI_ERR (1 << 10) +#define OB_HDR_DESC_DONE (1 << 8) + +/****************************************************************************** +** Type Definitions for registers & APIs +******************************************************************************/ + +/* outbound data descriptor */ +struct axxia_rio_ods_data_desc { + u32 dw0; + u32 dw1; + u32 dw2; + u32 dw3; + + /* SW usage */ + u32 virt_data_buf; + u32 sw1; + u32 sw2; + u32 sw3; +}; + +/* inbound data descriptor */ +struct axxia_rio_ids_data_desc { + u32 dw0; + u32 dw1; + u32 dw2; + u32 dw3; + u32 dw4; + + /* SW usage */ + u32 virt_data_buf; + u32 buf_status; + u32 sw2; +}; + +/* +** The following data structure defines data streaming header descriptors +** only used in outbound +*/ +struct axxia_rio_ds_hdr_desc { + u32 dw0; + u32 dw1; + u32 dw2; + u32 dw3; + u32 dw4; + + /* SW usage */ + u32 virt_data_buf; + u32 buf_status; + u32 sw2; +}; + +/* +** OBDS DSE configuration +*/ +struct axxia_rio_obds_dse_cfg { + u8 in_use; /* if the DSE is in_use */ + u8 cos; + u16 dest_id; + u16 stream_id; + spinlock_t lock; + u8 irqEnabled; + char name[16]; + + /* header descriptor */ + u16 num_hdr_desc_free; + u16 max_num_hdr_desc; + + /* data descriptor */ + u16 num_data_desc_free; + u16 max_num_data_desc; + u16 hdr_read_ptr; + u16 hdr_write_ptr; + u8 first_hdr_desc; + + u16 data_read_ptr; + u16 data_write_ptr; + u8 first_data_desc; + + struct axxia_rio_ds_hdr_desc *ptr_obds_hdr_desc; + struct axxia_rio_ods_data_desc *ptr_obds_data_desc; +}; + +/* +** IBDS configuration +*/ +struct axxia_ibds_virt_m_cfg { + spinlock_t lock; + u32 in_use; /* if the DSE is in_use */ + u8 cos; + u16 dest_id; + u16 stream_id; + u16 source_id; + char name[16]; + + u16 num_desc_free; + u16 max_num_data_desc; + u16 data_read_ptr; + u16 data_write_ptr; + + struct axxia_rio_ids_data_desc *ptr_ibds_data_desc; + u32 desc_dbuf_size; + u32 buf_add_ptr; + u32 num_hw_written_bufs; + + u32 alias_reg_value; + u16 virt_vsid; + u16 num_data_streams; +}; + +/* +** The following data structure defines the configuration of the AXXIA +** data streaming feature used by the device-specific code of the +** current mport. +*/ +struct axxia_rio_ds_cfg { + /* IBDS */ + u16 mtu; + u32 ibds_avsid_mapping; + u16 num_ibds_dses;/* TBR */ + u16 num_ibds_virtual_m;/* TBR */ + struct axxia_ibds_virt_m_cfg ibds_vsid_m_cfg[RIO_MAX_NUM_IBDS_VSID_M]; + + /* OBDS */ + u16 num_obds_dses; /* TBR */ + struct axxia_rio_obds_dse_cfg obds_dse_cfg[RIO_MAX_NUM_OBDS_DSE]; +}; + +/****************************************************************************** +** APIs exported to other kernel modules +******************************************************************************/ + +extern struct axxia_rio_ds_cfg* + axxia_mport_to_ds_cfg(struct rio_mport *mport); + +/* open an OBDS data stream */ +extern int axxia_open_ob_data_stream( + struct rio_mport *mport, + void *dev_id, + int dse_id, + int num_header_entries, + int num_data_entries); + +extern int open_ob_data_stream( + struct rio_mport *mport, + void *dev_id, + int dse_id, + int num_header_entries, + int num_data_entries); + +/* add user's data */ +extern int axxia_add_ob_data_stream( + struct rio_mport *mport, + int dest_id, + int stream_id, + int cos, + int priority, + int is_hdr_desc, + void *buffer, + int data_len); + +/* data streaming global configuration */ +extern int axxia_data_stream_global_cfg( + struct rio_mport *mport, + int mtu, + int ibds_avsid_mapping); + +/* open IBDS data stream */ +extern int axxia_open_ib_data_stream( + struct rio_mport *mport, + void *dev_id, + int source_id, + int cos, + int desc_dbuf_size, + int num_entries); + +int open_ib_data_stream( + struct rio_mport *mport, + void *dev_id, + int source_id, + int cos, + int desc_dbuf_size, + int num_entries); + +/* add IBDS data buffer */ +extern int axxia_add_ibds_buffer( + struct rio_mport *mport, + int source_id, + int cos, + void *buf, + int buf_size); + +/* get IBDS data */ +extern void *axxia_get_ibds_data( + struct rio_mport *mport, + int source_id, + int cos, + int *ptr_pdu_length, + int *ptr_stream_id); + +/* convert VSID to internal VSID */ +int axxio_virt_vsid_convert( + u32 vsid, + u32 alias_reg, + u16 *ptr_virt_vsid); + +/* close IBDS data streaming */ +extern int axxia_close_ib_data_stream( + struct rio_mport *mport, + int source_id, + int cos); + +/* close OBDS data streaming */ +extern int axxia_close_ob_data_stream( + struct rio_mport *mport, + int dse_id); + +#endif /* __RIO_AXXIA_H__ */ -- 1.7.9.5 -- _______________________________________________ linux-yocto mailing list linux-yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/linux-yocto