On 24/01/2024 15:26, Herve Codina wrote:
Hi Vadim,

On Wed, 24 Jan 2024 10:10:46 +0000
Vadim Fedorenko <vadim.fedore...@linux.dev> wrote:

[...]
+static int qmc_hdlc_xlate_slot_map(struct qmc_hdlc *qmc_hdlc,
+                                  u32 slot_map, struct qmc_chan_ts_info 
*ts_info)
+{
+       u64 ts_mask_avail;
+       unsigned int bit;
+       unsigned int i;
+       u64 ts_mask;
+       u64 map;
+
+       /* Tx and Rx masks must be identical */
+       if (ts_info->rx_ts_mask_avail != ts_info->tx_ts_mask_avail) {
+               dev_err(qmc_hdlc->dev, "tx and rx available timeslots mismatch 
(0x%llx, 0x%llx)\n",
+                       ts_info->rx_ts_mask_avail, ts_info->tx_ts_mask_avail);
+               return -EINVAL;
+       }
+
+       ts_mask_avail = ts_info->rx_ts_mask_avail;
+       ts_mask = 0;
+       map = slot_map;
+       bit = 0;
+       for (i = 0; i < 64; i++) {
+               if (ts_mask_avail & BIT_ULL(i)) {
+                       if (map & BIT_ULL(bit))
+                               ts_mask |= BIT_ULL(i);
+                       bit++;
+               }
+       }
+
+       if (hweight64(ts_mask) != hweight64(map)) {
+               dev_err(qmc_hdlc->dev, "Cannot translate timeslots 0x%llx -> 
(0x%llx,0x%llx)\n",
+                       map, ts_mask_avail, ts_mask);
+               return -EINVAL;
+       }
+
+       ts_info->tx_ts_mask = ts_mask;
+       ts_info->rx_ts_mask = ts_mask;
+       return 0;
+}
+
+static int qmc_hdlc_xlate_ts_info(struct qmc_hdlc *qmc_hdlc,
+                                 const struct qmc_chan_ts_info *ts_info, u32 
*slot_map)
+{
+       u64 ts_mask_avail;
+       unsigned int bit;
+       unsigned int i;
+       u64 ts_mask;
+       u64 map;
+

Starting from here ...

+       /* Tx and Rx masks must be identical */
+       if (ts_info->rx_ts_mask_avail != ts_info->tx_ts_mask_avail) {
+               dev_err(qmc_hdlc->dev, "tx and rx available timeslots mismatch 
(0x%llx, 0x%llx)\n",
+                       ts_info->rx_ts_mask_avail, ts_info->tx_ts_mask_avail);
+               return -EINVAL;
+       }
+       if (ts_info->rx_ts_mask != ts_info->tx_ts_mask) {
+               dev_err(qmc_hdlc->dev, "tx and rx timeslots mismatch (0x%llx, 
0x%llx)\n",
+                       ts_info->rx_ts_mask, ts_info->tx_ts_mask);
+               return -EINVAL;
+       }
+
+       ts_mask_avail = ts_info->rx_ts_mask_avail;
+       ts_mask = ts_info->rx_ts_mask;
+       map = 0;
+       bit = 0;
+       for (i = 0; i < 64; i++) {
+               if (ts_mask_avail & BIT_ULL(i)) {
+                       if (ts_mask & BIT_ULL(i))
+                               map |= BIT_ULL(bit);
+                       bit++;
+               }
+       }
+
+       if (hweight64(ts_mask) != hweight64(map)) {
+               dev_err(qmc_hdlc->dev, "Cannot translate timeslots (0x%llx,0x%llx) 
-> 0x%llx\n",
+                       ts_mask_avail, ts_mask, map);
+               return -EINVAL;
+       }
+

till here the block looks like copy of the block from previous function.
It worth to make a separate function for it, I think.

+       if (map >= BIT_ULL(32)) {
+               dev_err(qmc_hdlc->dev, "Slot map out of 32bit (0x%llx,0x%llx) -> 
0x%llx\n",
+                       ts_mask_avail, ts_mask, map);
+               return -EINVAL;
+       }
+
+       *slot_map = map;
+       return 0;
+}
+
[...]

I am not so sure. There are slighty differences between the two functions.
The error messages and, in particular, the loop in qmc_hdlc_xlate_slot_map() is:
        --- 8< ---
        ts_mask_avail = ts_info->rx_ts_mask_avail;
        ts_mask = 0;
        map = slot_map;
        bit = 0;
        for (i = 0; i < 64; i++) {
                if (ts_mask_avail & BIT_ULL(i)) {
                        if (map & BIT_ULL(bit))
                                ts_mask |= BIT_ULL(i);
                        bit++;
                }
        }
        --- 8< ---

whereas it is the following in qmc_hdlc_xlate_ts_info():
        --- 8< ---
        ts_mask_avail = ts_info->rx_ts_mask_avail;
        ts_mask = ts_info->rx_ts_mask;
        map = 0;
        bit = 0;
        for (i = 0; i < 64; i++) {
                if (ts_mask_avail & BIT_ULL(i)) {
                        if (ts_mask & BIT_ULL(i))
                                map |= BIT_ULL(bit);
                        bit++;
                }
        }
        --- 8< ---

ts_map and map initializations are not the same, i and bit are not used for
the same purpose and the computed value is not computed based on the same
information.

With that pointed, I am not sure that having some common code for both
function will be relevant. Your opinion ?

I see. I'm just thinking if it's possible to use helpers from bitops.h
and bitmap.h here to avoid open-coding common parts of the code.

Best regards,
Hervé

Reply via email to