0

Hy i wanted to toggle a GPIO pin always when i send a package. But I have a weird behafure sometimes my pin gets toggled and sometimes not. I checked my Kernel logs and there is no Information that the pin could not be toggled. My Ops look like this:

static const struct net_device_ops stmuart_netdev_ops = {
    .ndo_init = stmuart_netdev_init,
    .ndo_uninit = stmuart_netdev_uninit,
    .ndo_open = stmuart_netdev_open,
    .ndo_stop = stmuart_netdev_close,
    .ndo_start_xmit = stmuart_netdev_xmit,
    .ndo_set_mac_address = eth_mac_addr,
    .ndo_tx_timeout = stmuart_netdev_tx_timeout,
    .ndo_validate_addr = eth_validate_addr,
};

So as far as i know the ndo_start_xmit method is called as soon as i want to send a package. so i only toggle my pin when this method is called. But when i look on my Oscilloscope i can see that the pin is only sometimes toggled.

My method for sending looks like this:

static netdev_tx_t
stmuart_netdev_xmit(struct sk_buff *skb, struct net_device *dev)
{
    struct net_device_stats *n_stats = &dev->stats;
    struct stmuart *stm = netdev_priv(dev);
    u8 pad_len = 0;
    int written;
    u8 *pos;
    
    spin_lock(&stm->lock);
    gpiod_set_value(stm->rts_gpio, 1);

    WARN_ON(stm->tx_left);

    if (!netif_running(dev))  {
        spin_unlock(&stm->lock);
        netdev_warn(stm->net_dev, "xmit: iface is down\n");
        goto out;
    }

    pos = stm->tx_buffer;

    if (skb->len < STMFRM_MIN_LEN)
        pad_len = STMFRM_MIN_LEN - skb->len;

    pos += stmfrm_create_header(pos, skb->len + pad_len);

    memcpy(pos, skb->data, skb->len);
    pos += skb->len;

    if (pad_len) {
        memset(pos, 0, pad_len);
        pos += pad_len;
    }

    pos += stmfrm_create_footer(pos);

    netif_stop_queue(stm->net_dev);
  

    written = serdev_device_write_buf(stm->serdev, stm->tx_buffer,
                      pos - stm->tx_buffer);
    
    if (written > 0) {
        stm->tx_left = (pos - stm->tx_buffer) - written;
        stm->tx_head = stm->tx_buffer + written;
        n_stats->tx_bytes += written;
    }
    spin_unlock(&stm->lock);

out:
    gpiod_set_value(stm->rts_gpio, 0);
    netif_trans_update(dev);
    dev_kfree_skb_any(skb);
    return NETDEV_TX_OK;
}

So i checked the netdevice.h but there i did not saw another method that gets called when the net device wants to send a package. It seems to me like always when the netdevice sends a ARP-Request the pin gets not toggled.

samann
  • 73
  • 5
  • Should your code be checking the return value of `spin_lock(&stm->lock);` before continuing on? – ryyker Jun 23 '21 at 12:44
  • No it is not neccesary in my opinion. Beside that i am able to send and recive my packages but the only thing thats not working correctly is to set the pin high before sending and low after sending. – samann Jun 23 '21 at 13:04
  • And what kind of GPIO controller is in use? (Btw, why you set pin under lock and clear without it? If you have an SMP system, it would be potential race condition.) – 0andriy Jun 23 '21 at 21:33
  • Hy thanks for the answer. I am using the #include to control my GPIOS. i also moved the spin_unlock(&stm->lock); afther my out: so it always gets unlocked. – samann Jun 24 '21 at 08:57
  • I was asking which hardware is used for that GPIOs. – 0andriy Jun 24 '21 at 09:14
  • Sorry i got it wrong i am using a stm32mp157-dk 1. – samann Jun 24 '21 at 09:29

0 Answers0