@@ -2602,44 +2602,58 @@ static int airoha_qdma_set_tx_rate_limit(struct net_device *netdev,
26022602 return 0 ;
26032603}
26042604
2605- static int airoha_tc_htb_alloc_leaf_queue (struct net_device * netdev ,
2606- struct tc_htb_qopt_offload * opt )
2605+ static int airoha_tc_htb_modify_queue (struct net_device * dev ,
2606+ struct tc_htb_qopt_offload * opt )
26072607{
26082608 u32 channel = TC_H_MIN (opt -> classid ) % AIROHA_NUM_QOS_CHANNELS ;
26092609 u32 rate = div_u64 (opt -> rate , 1000 ) << 3 ; /* kbps */
2610- int err , num_tx_queues = netdev -> real_num_tx_queues ;
2611- struct airoha_gdm_dev * dev = netdev_priv (netdev );
2612- struct airoha_gdm_port * port = dev -> port ;
26132610
26142611 if (opt -> parent_classid != TC_HTB_CLASSID_ROOT ) {
26152612 NL_SET_ERR_MSG_MOD (opt -> extack , "invalid parent classid" );
26162613 return - EINVAL ;
26172614 }
26182615
2619- err = airoha_qdma_set_tx_rate_limit (netdev , channel , rate ,
2620- opt -> quantum );
2621- if (err ) {
2616+ return airoha_qdma_set_tx_rate_limit (dev , channel , rate , opt -> quantum );
2617+ }
2618+
2619+ static int airoha_tc_htb_alloc_leaf_queue (struct net_device * netdev ,
2620+ struct tc_htb_qopt_offload * opt )
2621+ {
2622+ u32 channel = TC_H_MIN (opt -> classid ) % AIROHA_NUM_QOS_CHANNELS ;
2623+ int err , num_tx_queues = netdev -> real_num_tx_queues ;
2624+ struct airoha_gdm_dev * dev = netdev_priv (netdev );
2625+ struct airoha_qdma * qdma = dev -> qdma ;
2626+
2627+ /* Here we need to check the requested QDMA channel is not already
2628+ * in use by another net_device running on the same QDMA block.
2629+ */
2630+ if (test_and_set_bit (channel , qdma -> qos_channel_map )) {
26222631 NL_SET_ERR_MSG_MOD (opt -> extack ,
2623- "failed configuring htb offload " );
2624- return err ;
2632+ "qdma qos channel already in use " );
2633+ return - EBUSY ;
26252634 }
26262635
2627- if (opt -> command == TC_HTB_NODE_MODIFY )
2628- return 0 ;
2636+ err = airoha_tc_htb_modify_queue (netdev , opt );
2637+ if (err )
2638+ goto error ;
26292639
26302640 err = netif_set_real_num_tx_queues (netdev , num_tx_queues + 1 );
26312641 if (err ) {
26322642 airoha_qdma_set_tx_rate_limit (netdev , channel , 0 ,
26332643 opt -> quantum );
26342644 NL_SET_ERR_MSG_MOD (opt -> extack ,
26352645 "failed setting real_num_tx_queues" );
2636- return err ;
2646+ goto error ;
26372647 }
26382648
2639- set_bit (channel , port -> qos_sq_bmap );
2649+ set_bit (channel , dev -> qos_sq_bmap );
26402650 opt -> qid = AIROHA_NUM_TX_RING + channel ;
26412651
26422652 return 0 ;
2653+ error :
2654+ clear_bit (channel , qdma -> qos_channel_map );
2655+
2656+ return err ;
26432657}
26442658
26452659static int airoha_qdma_set_rx_meter (struct airoha_gdm_dev * dev ,
@@ -2820,21 +2834,22 @@ static int airoha_dev_setup_tc_block(struct net_device *dev,
28202834static void airoha_tc_remove_htb_queue (struct net_device * netdev , int queue )
28212835{
28222836 struct airoha_gdm_dev * dev = netdev_priv (netdev );
2823- struct airoha_gdm_port * port = dev -> port ;
2837+ struct airoha_qdma * qdma = dev -> qdma ;
28242838
28252839 netif_set_real_num_tx_queues (netdev , netdev -> real_num_tx_queues - 1 );
28262840 airoha_qdma_set_tx_rate_limit (netdev , queue + 1 , 0 , 0 );
2827- clear_bit (queue , port -> qos_sq_bmap );
2841+
2842+ clear_bit (queue , qdma -> qos_channel_map );
2843+ clear_bit (queue , dev -> qos_sq_bmap );
28282844}
28292845
28302846static int airoha_tc_htb_delete_leaf_queue (struct net_device * netdev ,
28312847 struct tc_htb_qopt_offload * opt )
28322848{
28332849 u32 channel = TC_H_MIN (opt -> classid ) % AIROHA_NUM_QOS_CHANNELS ;
28342850 struct airoha_gdm_dev * dev = netdev_priv (netdev );
2835- struct airoha_gdm_port * port = dev -> port ;
28362851
2837- if (!test_bit (channel , port -> qos_sq_bmap )) {
2852+ if (!test_bit (channel , dev -> qos_sq_bmap )) {
28382853 NL_SET_ERR_MSG_MOD (opt -> extack , "invalid queue id" );
28392854 return - EINVAL ;
28402855 }
@@ -2847,10 +2862,9 @@ static int airoha_tc_htb_delete_leaf_queue(struct net_device *netdev,
28472862static int airoha_tc_htb_destroy (struct net_device * netdev )
28482863{
28492864 struct airoha_gdm_dev * dev = netdev_priv (netdev );
2850- struct airoha_gdm_port * port = dev -> port ;
28512865 int q ;
28522866
2853- for_each_set_bit (q , port -> qos_sq_bmap , AIROHA_NUM_QOS_CHANNELS )
2867+ for_each_set_bit (q , dev -> qos_sq_bmap , AIROHA_NUM_QOS_CHANNELS )
28542868 airoha_tc_remove_htb_queue (netdev , q );
28552869
28562870 return 0 ;
@@ -2861,9 +2875,8 @@ static int airoha_tc_get_htb_get_leaf_queue(struct net_device *netdev,
28612875{
28622876 u32 channel = TC_H_MIN (opt -> classid ) % AIROHA_NUM_QOS_CHANNELS ;
28632877 struct airoha_gdm_dev * dev = netdev_priv (netdev );
2864- struct airoha_gdm_port * port = dev -> port ;
28652878
2866- if (!test_bit (channel , port -> qos_sq_bmap )) {
2879+ if (!test_bit (channel , dev -> qos_sq_bmap )) {
28672880 NL_SET_ERR_MSG_MOD (opt -> extack , "invalid queue id" );
28682881 return - EINVAL ;
28692882 }
@@ -2882,6 +2895,7 @@ static int airoha_tc_setup_qdisc_htb(struct net_device *dev,
28822895 case TC_HTB_DESTROY :
28832896 return airoha_tc_htb_destroy (dev );
28842897 case TC_HTB_NODE_MODIFY :
2898+ return airoha_tc_htb_modify_queue (dev , opt );
28852899 case TC_HTB_LEAF_ALLOC_QUEUE :
28862900 return airoha_tc_htb_alloc_leaf_queue (dev , opt );
28872901 case TC_HTB_LEAF_DEL :
0 commit comments