5151#define QM_MB_CMD_DATA_ADDR_L 0x304
5252#define QM_MB_CMD_DATA_ADDR_H 0x308
5353#define QM_MB_PING_ALL_VFS 0xffff
54+ #define QM_MB_CMD_DATA_SHIFT 32
5455#define QM_MB_CMD_DATA_MASK GENMASK(31, 0)
5556
5657/* sqc shift */
185186
186187/* interfunction communication */
187188#define QM_IFC_READY_STATUS 0x100128
189+ #define QM_IFC_C_STS_M 0x10012C
188190#define QM_IFC_INT_SET_P 0x100130
189191#define QM_IFC_INT_CFG 0x100134
190192#define QM_IFC_INT_SOURCE_P 0x100138
256258#define QM_SHAPER_CBS_B 1
257259#define QM_SHAPER_CBS_S 16
258260#define QM_SHAPER_VFT_OFFSET 6
261+ #define WAIT_FOR_QOS_VF 100
259262#define QM_QOS_MIN_ERROR_RATE 5
260263#define QM_QOS_TYPICAL_NUM 8
261264#define QM_SHAPER_MIN_CBS_S 8
@@ -328,6 +331,8 @@ enum qm_mb_cmd {
328331 QM_VF_PREPARE_FAIL ,
329332 QM_VF_START_DONE ,
330333 QM_VF_START_FAIL ,
334+ QM_PF_SET_QOS ,
335+ QM_VF_GET_QOS ,
331336};
332337
333338struct qm_cqe {
@@ -2124,7 +2129,7 @@ static void qm_trigger_vf_interrupt(struct hisi_qm *qm, u32 fun_num)
21242129 u32 val ;
21252130
21262131 val = readl (qm -> io_base + QM_IFC_INT_CFG );
2127- val | = ~QM_IFC_SEND_ALL_VFS ;
2132+ val & = ~QM_IFC_SEND_ALL_VFS ;
21282133 val |= fun_num ;
21292134 writel (val , qm -> io_base + QM_IFC_INT_CFG );
21302135
@@ -3926,6 +3931,139 @@ static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos)
39263931 return 0 ;
39273932}
39283933
3934+ static u32 qm_get_shaper_vft_qos (struct hisi_qm * qm , u32 fun_index )
3935+ {
3936+ u64 cir_u = 0 , cir_b = 0 , cir_s = 0 ;
3937+ u64 shaper_vft , ir_calc , ir ;
3938+ unsigned int val ;
3939+ u32 error_rate ;
3940+ int ret ;
3941+
3942+ ret = readl_relaxed_poll_timeout (qm -> io_base + QM_VFT_CFG_RDY , val ,
3943+ val & BIT (0 ), POLL_PERIOD ,
3944+ POLL_TIMEOUT );
3945+ if (ret )
3946+ return 0 ;
3947+
3948+ writel (0x1 , qm -> io_base + QM_VFT_CFG_OP_WR );
3949+ writel (SHAPER_VFT , qm -> io_base + QM_VFT_CFG_TYPE );
3950+ writel (fun_index , qm -> io_base + QM_VFT_CFG );
3951+
3952+ writel (0x0 , qm -> io_base + QM_VFT_CFG_RDY );
3953+ writel (0x1 , qm -> io_base + QM_VFT_CFG_OP_ENABLE );
3954+
3955+ ret = readl_relaxed_poll_timeout (qm -> io_base + QM_VFT_CFG_RDY , val ,
3956+ val & BIT (0 ), POLL_PERIOD ,
3957+ POLL_TIMEOUT );
3958+ if (ret )
3959+ return 0 ;
3960+
3961+ shaper_vft = readl (qm -> io_base + QM_VFT_CFG_DATA_L ) |
3962+ ((u64 )readl (qm -> io_base + QM_VFT_CFG_DATA_H ) << 32 );
3963+
3964+ cir_b = shaper_vft & QM_SHAPER_CIR_B_MASK ;
3965+ cir_u = shaper_vft & QM_SHAPER_CIR_U_MASK ;
3966+ cir_u = cir_u >> QM_SHAPER_FACTOR_CIR_U_SHIFT ;
3967+
3968+ cir_s = shaper_vft & QM_SHAPER_CIR_S_MASK ;
3969+ cir_s = cir_s >> QM_SHAPER_FACTOR_CIR_S_SHIFT ;
3970+
3971+ ir_calc = acc_shaper_para_calc (cir_b , cir_u , cir_s );
3972+
3973+ ir = qm -> factor [fun_index ].func_qos * QM_QOS_RATE ;
3974+
3975+ error_rate = QM_QOS_EXPAND_RATE * (u32 )abs (ir_calc - ir ) / ir ;
3976+ if (error_rate > QM_QOS_MIN_ERROR_RATE ) {
3977+ pci_err (qm -> pdev , "error_rate: %u, get function qos is error!\n" , error_rate );
3978+ return 0 ;
3979+ }
3980+
3981+ return ir ;
3982+ }
3983+
3984+ static void qm_vf_get_qos (struct hisi_qm * qm , u32 fun_num )
3985+ {
3986+ struct device * dev = & qm -> pdev -> dev ;
3987+ u64 mb_cmd ;
3988+ u32 qos ;
3989+ int ret ;
3990+
3991+ qos = qm_get_shaper_vft_qos (qm , fun_num );
3992+ if (!qos ) {
3993+ dev_err (dev , "function(%u) failed to get qos by PF!\n" , fun_num );
3994+ return ;
3995+ }
3996+
3997+ mb_cmd = QM_PF_SET_QOS | (u64 )qos << QM_MB_CMD_DATA_SHIFT ;
3998+ ret = qm_ping_single_vf (qm , mb_cmd , fun_num );
3999+ if (ret )
4000+ dev_err (dev , "failed to send cmd to VF(%u)!\n" , fun_num );
4001+ }
4002+
4003+ static int qm_vf_read_qos (struct hisi_qm * qm )
4004+ {
4005+ int cnt = 0 ;
4006+ int ret ;
4007+
4008+ /* reset mailbox qos val */
4009+ qm -> mb_qos = 0 ;
4010+
4011+ /* vf ping pf to get function qos */
4012+ if (qm -> ops -> ping_pf ) {
4013+ ret = qm -> ops -> ping_pf (qm , QM_VF_GET_QOS );
4014+ if (ret ) {
4015+ pci_err (qm -> pdev , "failed to send cmd to PF to get qos!\n" );
4016+ return ret ;
4017+ }
4018+ }
4019+
4020+ while (true) {
4021+ msleep (QM_WAIT_DST_ACK );
4022+ if (qm -> mb_qos )
4023+ break ;
4024+
4025+ if (++ cnt > QM_MAX_VF_WAIT_COUNT ) {
4026+ pci_err (qm -> pdev , "PF ping VF timeout!\n" );
4027+ return - ETIMEDOUT ;
4028+ }
4029+ }
4030+
4031+ return ret ;
4032+ }
4033+
4034+ static ssize_t qm_algqos_read (struct file * filp , char __user * buf ,
4035+ size_t count , loff_t * pos )
4036+ {
4037+ struct hisi_qm * qm = filp -> private_data ;
4038+ char tbuf [QM_DBG_READ_LEN ];
4039+ u32 qos_val , ir ;
4040+ int ret ;
4041+
4042+ /* Mailbox and reset cannot be operated at the same time */
4043+ if (test_and_set_bit (QM_RESETTING , & qm -> misc_ctl )) {
4044+ pci_err (qm -> pdev , "dev resetting, read alg qos failed!\n" );
4045+ return - EAGAIN ;
4046+ }
4047+
4048+ if (qm -> fun_type == QM_HW_PF ) {
4049+ ir = qm_get_shaper_vft_qos (qm , 0 );
4050+ } else {
4051+ ret = qm_vf_read_qos (qm );
4052+ if (ret )
4053+ goto err_get_status ;
4054+ ir = qm -> mb_qos ;
4055+ }
4056+
4057+ qos_val = ir / QM_QOS_RATE ;
4058+ ret = scnprintf (tbuf , QM_DBG_READ_LEN , "%u\n" , qos_val );
4059+
4060+ ret = simple_read_from_buffer (buf , count , pos , tbuf , ret );
4061+
4062+ err_get_status :
4063+ clear_bit (QM_RESETTING , & qm -> misc_ctl );
4064+ return ret ;
4065+ }
4066+
39294067static ssize_t qm_qos_value_init (const char * buf , unsigned long * val )
39304068{
39314069 int buflen = strlen (buf );
@@ -4020,6 +4158,7 @@ static ssize_t qm_algqos_write(struct file *filp, const char __user *buf,
40204158static const struct file_operations qm_algqos_fops = {
40214159 .owner = THIS_MODULE ,
40224160 .open = simple_open ,
4161+ .read = qm_algqos_read ,
40234162 .write = qm_algqos_write ,
40244163};
40254164
@@ -5129,10 +5268,8 @@ static void qm_pf_reset_vf_process(struct hisi_qm *qm,
51295268 qm_reset_bit_clear (qm );
51305269}
51315270
5132- static void qm_cmd_process (struct work_struct * cmd_process )
5271+ static void qm_handle_cmd_msg (struct hisi_qm * qm , u32 fun_num )
51335272{
5134- struct hisi_qm * qm = container_of (cmd_process ,
5135- struct hisi_qm , cmd_process );
51365273 struct device * dev = & qm -> pdev -> dev ;
51375274 u64 msg ;
51385275 u32 cmd ;
@@ -5142,8 +5279,8 @@ static void qm_cmd_process(struct work_struct *cmd_process)
51425279 * Get the msg from source by sending mailbox. Whether message is got
51435280 * successfully, destination needs to ack source by clearing the interrupt.
51445281 */
5145- ret = qm_get_mb_cmd (qm , & msg , 0 );
5146- qm_clear_cmd_interrupt (qm , 0 );
5282+ ret = qm_get_mb_cmd (qm , & msg , fun_num );
5283+ qm_clear_cmd_interrupt (qm , BIT ( fun_num ) );
51475284 if (ret ) {
51485285 dev_err (dev , "failed to get msg from source!\n" );
51495286 return ;
@@ -5157,12 +5294,42 @@ static void qm_cmd_process(struct work_struct *cmd_process)
51575294 case QM_PF_SRST_PREPARE :
51585295 qm_pf_reset_vf_process (qm , QM_SOFT_RESET );
51595296 break ;
5297+ case QM_VF_GET_QOS :
5298+ qm_vf_get_qos (qm , fun_num );
5299+ break ;
5300+ case QM_PF_SET_QOS :
5301+ qm -> mb_qos = msg >> QM_MB_CMD_DATA_SHIFT ;
5302+ break ;
51605303 default :
5161- dev_err (dev , "unsupported cmd %u sent by PF !\n" , cmd );
5304+ dev_err (dev , "unsupported cmd %u sent by function(%u) !\n" , cmd , fun_num );
51625305 break ;
51635306 }
51645307}
51655308
5309+ static void qm_cmd_process (struct work_struct * cmd_process )
5310+ {
5311+ struct hisi_qm * qm = container_of (cmd_process ,
5312+ struct hisi_qm , cmd_process );
5313+ u32 vfs_num = qm -> vfs_num ;
5314+ u64 val ;
5315+ u32 i ;
5316+
5317+ if (qm -> fun_type == QM_HW_PF ) {
5318+ val = readq (qm -> io_base + QM_IFC_INT_SOURCE_P );
5319+ if (!val )
5320+ return ;
5321+
5322+ for (i = 1 ; i <= vfs_num ; i ++ ) {
5323+ if (val & BIT (i ))
5324+ qm_handle_cmd_msg (qm , i );
5325+ }
5326+
5327+ return ;
5328+ }
5329+
5330+ qm_handle_cmd_msg (qm , 0 );
5331+ }
5332+
51665333/**
51675334 * hisi_qm_alg_register() - Register alg to crypto and add qm to qm_list.
51685335 * @qm: The qm needs add.
0 commit comments