Hello Jan.

In attach follows a patch for the link beat functionality for the rt_8139too 
driver and SOCK_RAW.

For more drivers to support this it must be implemented in the driver (like 
rt_8139too) but it think is easy.

For the other sockets the only thing to do is add two or three code lines in 
the ioctl function.


To get the link bit of one board use something like this:

bool CRtEthernetComm::CheckLinkBeat( int n_if_index )
{
    int nReturn = -1;
    struct rtnet_device_monitoring sMonitoring;
    sMonitoring.ifindex = n_if_index;

    nReturn = rt_dev_ioctl(m_nFileDescriptor, 
RTNET_RTIOC_MONITORING_LINK_BEAT, &sMonitoring);
    if(nReturn < 0)
    {
        CPrint::Instance()->Print( "Error retrieving link beat information. 
Error = %d\n",nReturn);
        return false;
    }
    if(sMonitoring.link_beat == 1)
        return true;

    return false;
}


I've already test it adn it works fine.
Plese test it in one of your boards, or anyone that reads this e-mail.

Greetings

Em Quinta, 23 de Novembro de 2006 18:32, escreveu:
> Jorge Almeida wrote:
> > Em Quinta, 23 de Novembro de 2006 17:27, o Jan Kiszka escreveu:
> >> Jorge Almeida wrote:
> >>> Em Quinta, 23 de Novembro de 2006 16:46, escreveu:
> >>>> Jorge Almeida wrote:
> >>>>> Em Quinta, 23 de Novembro de 2006 16:02, escreveu:
> >>>>>> Jorge Almeida wrote:
> >>>>>>> Hello Jan,
> >>>>>>>
> >>>>>>> I'm trying to implement an easy way of monitoring the link beat of 
one 
> >>>>> board.
> >>>>>>> What i want is to pass the index of the board, and internaly call 
the 
> >>>>>>> "do_ioctl" function that should be initialialized in the 
rtnet_device 
> >>>>> struct 
> >>>>>>> for each device.
> >>>>>>>
> >>>>>>> My question is, How do i call the do_ioctl function using the file 
> >>>>> descriptor 
> >>>>>>> of one socket that is open passing the number of the if_index (or 
the 
> >>>>>>> interface name)? And how rtnet knows wath device to call?
> >>>>>> IOCTLs on RTDM sockets come in over the related protocol handler, see
> >>>>>> e.g. this one for packet sockets:
> >>>>>>
> >>>>>>
> > 
http://www.rts.uni-hannover.de/rtnet/lxr/source/stack/packet/af_packet.c#L240
> >>>>>> From there on you can easily go down the chain.
> >>>>>>
> >>>>>> As the IOCTLs are per-socket and not per-device, you have to provide 
> > the
> >>>>>> information about the address device within the request packet. Do 
you
> >>>>>> have some Linux data structure you can reuse for it? Something like 
for
> >>>>>> SIOCGIFINDEX?
> >>>>> Yes, i have the struct ifreq used for the SIOCGIFINDEX ioctl.
> >>>>>
> >>>>> I was checking the code and the path is something like this:
> >>>>>
> >>>>> 1       Start at "rt_packet_ioctl" (af_packet.c) checking for  a new 
> >>>>> type of 
> >>> ioctl 
> >>>>> "RTIOC_TYPE_MONITORING"
> >>>> So you are about to define a new IOCTL? Is there no comparable 
interface
> >>>> existing in Linux? Will this interface be about polling for the current
> >>>> link status? I'm not aware of an official Linux API for this, but this
> >>>> doesn't mean there isn't any.
> >>> I don't know either if anything similar exists.
> >>> I used to use the mii-diag tool to check if the has link bit or not.
> >>>
> >>> The IOCTL is only made when the user asks for it. Theres no polling 
> > mechanism 
> >> Which is already what I meant with polling.
> >>
> >>> working here. Thats another question that can be implemented in the 
> > future.
> >>>> Anyway, do this multiplexing here:
> >>>>
> >>>> http://www.rts.uni-hannover.de/rtnet/lxr/source/stack/socket.c#L225
> >>>>
> >>>> i.e. in rt_socket_if_ioctl(). That way it will automatically work for
> >>>> all kind of RTnet sockets.
> >>> But it is driver dependent, and not a configuration stuff.
> >> The driver dependent stuff comes with calling rtdev->do_ioctl. Here it
> >> is about finding out which driver to to call.
> >>
> >>> Isn't better to define already a new type of IOCTL??
> >>> For future drivers and sockets it will be already available and the 
> > developers 
> >>> are free to implement it.
> >> If there is no IOCTL for Linux that tells you "link on device X is
> >> up/down", then define one for RTnet.
> >>
> >>>>> 2       send it to a new function in socket.c 
> >>>>> "rt_socket_monitoring_ioctl"
> >>>>>
> >>>>> 3       check the device that we are trying to check the link beat
> >>>>>
> >>>>> 4       send it to the driver (rt_8139too.c) with the do_ioctl pointer.
> >>>>>
> >>>>> In this i only have one doubt:
> >>>>>         Where do i return the result?
> >>>> In the same data structure you used for the request? What does it look
> >>>> like so far?
> >>>>
> >>>>> Maybe the solution:
> >>>>>         Build a new struct in RTnet has support of the monitoring IOCTLS
> >>>>>         (just for now ) something like
> >>>>>
> >>>>> struct SDeviceMonit
> >>>>> {
> >>>>>         int nDeviceIndex;
> >>>>>         int nLinkBeat;
> >>>>> }
> >>>>>
> >>>>> This way i can identify the device (nDeviceIndex;) and get the result 
> >>>>> (nLinkBeat;).
> >>>>>
> >>>>> Any sugestion??!!
> >>>> In any case, try to do it within struct ifreq. There is e.g. 
ifru_ivalue
> >>>> used by multiple requests to pass an integer up and down.
> >>> The ifreq structure is very limited:
> >>> struct ifreq 
> >>> {
> >>> #define IFHWADDRLEN       6
> >>>   union
> >>>   {
> >>>           char    ifrn_name[IFNAMSIZ];            /* if name, e.g. "en0" 
> >>> */
> >>>   } ifr_ifrn;
> >>>   
> >>>   union {
> >>>           struct  sockaddr ifru_addr;
> >>>           struct  sockaddr ifru_dstaddr;
> >>>           struct  sockaddr ifru_broadaddr;
> >>>           struct  sockaddr ifru_netmask;
> >>>           struct  sockaddr ifru_hwaddr;
> >>>           short   ifru_flags;
> >>>           int     ifru_ivalue;
> >>>           int     ifru_mtu;
> >>>           struct  ifmap ifru_map;
> >>>           char    ifru_slave[IFNAMSIZ];   /* Just fits the size */
> >>>           char    ifru_newname[IFNAMSIZ];
> >>>           void __user *   ifru_data;
> >>>           struct  if_settings ifru_settings;
> >>>   } ifr_ifru;
> >>> };
> >>>
> >>> only has two fileds, i think the hardware monitoring need much more in 
the 
> >>> future. If a new structure is already available the next developers only 
> > has 
> >>> to fill it with the new parameters that they need, or even make a union 
> >>> similar to the struct ifreq.
> >> OK, if you see the need for further fields that don't fit here, we can
> >> extend the structure. But I would at least like to keep its head to
> >> unify its usage - both in user-space and in the kernel.
> >>
> >> What further information would you like to bundle one day
> >> _with_this_particular_ service call?
> > 
> > For example:
> > 
> > check if Auto-negotiation is enabled or not.
> > check the link speed.
> > check if is Half or Full duplex.
> 
> The above information make sense. I agree that at least the link speed
> should come not as some bits in a single integer but as a real value to
> remain independent of the medium.
> 
> > change the speed manualy.
> 
> That's stuff for another service call.
> 
> > 
> > And some more that i dont remember now.
> 
> There more we know, the better we can design the interface on first attempt.
> 
> > 
> > I will send you a patch todoy or tomorow morning with something 
implemented.
> 
> OK, looking forward.
> 
> Jan
> 
> 

-- 
Jorge Almeida
[EMAIL PROTECTED]

DISCLAIMER: This message may contain confidential information or privileged 
material and is intended only for the individual(s) named. If you are not a 
named addressee and mistakenly received this message you should not copy or 
otherwise disseminate it: please delete this e-mail from your system and notify 
the sender immediately. E-mail transmissions are not guaranteed to be secure or 
without errors as information could be intercepted, corrupted, lost, destroyed, 
arrive late or incomplete or contain viruses. Therefore, the sender does not 
accept liability for any errors or omissions in the contents of this message 
that arise as a result of e-mail transmissions. Please request a hard copy 
version if verification is required. Critical Software, SA.
Index: stack/include/rtnet.h
===================================================================
--- stack/include/rtnet.h	(revision 1087)
+++ stack/include/rtnet.h	(working copy)
@@ -52,6 +52,14 @@
     void    *arg;
 };
 
+/*
+ * Monitoring Device structure
+ */
+struct rtnet_device_monitoring 
+{
+    int ifindex;
+    int link_beat;
+};
 
 /* sub-classes: RTDM_CLASS_NETWORK */
 #define RTDM_SUBCLASS_RTNET     0
@@ -70,6 +78,13 @@
 #define RTNET_RTIOC_EXTPOOL     _IOW(RTIOC_TYPE_NETWORK, 0x14, unsigned int)
 #define RTNET_RTIOC_SHRPOOL     _IOW(RTIOC_TYPE_NETWORK, 0x15, unsigned int)
 
+
+/* RTnet Monitoring Ioctls */
+// this must be different from RTIOC_TYPE_NETWORK
+#define RTIOC_TYPE_NETWORK_MONITORING 152
+
+#define RTNET_RTIOC_MONITORING_LINK_BEAT _IOW(RTIOC_TYPE_NETWORK_MONITORING, 0x01, struct rtnet_device_monitoring )
+
 /* socket transmission priorities */
 #define SOCK_MAX_PRIO           0
 #define SOCK_DEF_PRIO           SOCK_MAX_PRIO + \
Index: stack/include/rtnet_socket.h
===================================================================
--- stack/include/rtnet_socket.h	(revision 1087)
+++ stack/include/rtnet_socket.h	(working copy)
@@ -103,5 +103,7 @@
 extern int rt_socket_if_ioctl(struct rtdm_dev_context *context,
                               rtdm_user_info_t *user_info,
                               int request, void *arg);
-
+extern int rt_socket_monitoring_ioctl(struct rtdm_dev_context *context,
+                                  rtdm_user_info_t *user_info,
+                                  int request, void *arg);
 #endif  /* __RTNET_SOCKET_H_ */
Index: stack/packet/af_packet.c
===================================================================
--- stack/packet/af_packet.c	(revision 1087)
+++ stack/packet/af_packet.c	(working copy)
@@ -243,12 +243,16 @@
     struct rtsocket *sock = (struct rtsocket *)&sockctx->dev_private;
     struct _rtdm_setsockaddr_args *setaddr = arg;
     struct _rtdm_getsockaddr_args *getaddr = arg;
+    struct rtnet_device_monitoring* test = (struct rtnet_device_monitoring*)arg;
 
-
     /* fast path for common socket IOCTLs */
     if (_IOC_TYPE(request) == RTIOC_TYPE_NETWORK)
         return rt_socket_common_ioctl(sockctx, user_info, request, arg);
 
+        /* fast path for monitoring socket IOCTLs */
+    if ( _IOC_TYPE(request) == RTIOC_TYPE_NETWORK_MONITORING)
+        return rt_socket_monitoring_ioctl(sockctx, user_info, request, arg);
+
     switch (request) {
         case _RTIOC_BIND:
             return rt_packet_bind(sock, setaddr->addr, setaddr->addrlen);
Index: stack/socket.c
===================================================================
--- stack/socket.c	(revision 1087)
+++ stack/socket.c	(working copy)
@@ -229,7 +229,6 @@
     struct ifreq        *ifr = arg;
     int                 ret = 0;
 
-
     if (request == SIOCGIFCONF) {
         struct ifconf       *ifc = arg;
         struct ifreq        *cur_ifr = ifc->ifc_req;
@@ -289,8 +288,30 @@
     return ret;
 }
 
+/***
+ *  rt_socket_monitoring_ioctl
+ */
+int rt_socket_monitoring_ioctl(struct rtdm_dev_context *sockctx,
+                           rtdm_user_info_t *user_info,
+                           int request, void *arg)
+{
+    struct rtnet_device *rtdev = NULL;
+    struct rtnet_device_monitoring* psDevMonit = arg;
+    
+    rtdev = rtdev_get_by_index(psDevMonit->ifindex);
+    if(rtdev == NULL)
+        return -ENODEV;
+    if(rtdev->do_ioctl != NULL)    
+        return rtdev->do_ioctl( rtdev, request, arg);
+    else
+    {
+        rtdev_dereference(rtdev);
+        return -ENOSYS;        
+    }
+}
 
 EXPORT_SYMBOL(rt_socket_init);
 EXPORT_SYMBOL(rt_socket_cleanup);
 EXPORT_SYMBOL(rt_socket_common_ioctl);
 EXPORT_SYMBOL(rt_socket_if_ioctl);
+EXPORT_SYMBOL(rt_socket_monitoring_ioctl);
Index: drivers/rt_8139too.c
===================================================================
--- drivers/rt_8139too.c	(revision 1087)
+++ drivers/rt_8139too.c	(working copy)
@@ -525,6 +525,7 @@
 static int rtl8139_interrupt (rtdm_irq_t *irq_handle);
 static int rtl8139_start_xmit (struct rtskb *skb, struct rtnet_device *rtdev);
 
+static int rtl8139_ioctl(struct rtnet_device *rtdev, unsigned int request, void * cmd);
 
 static void rtl8139_init_ring (struct rtnet_device *rtdev);
 static void rtl8139_set_rx_mode (struct rtnet_device *rtdev);
@@ -834,6 +835,7 @@
         rtdev->stop = rtl8139_close;
         rtdev->hard_header = &rt_eth_header;
         rtdev->hard_start_xmit = rtl8139_start_xmit;
+        rtdev->do_ioctl = rtl8139_ioctl;
 
         /*rtdev->set_multicast_list = rtl8139_set_rx_mode; */
         rtdev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
@@ -1341,6 +1343,32 @@
         return 0;
 }
 
+static int rtl8139_ioctl(struct rtnet_device *rtdev, unsigned int request, void * cmd)
+{
+    struct rtl8139_private *tp = rtdev->priv;
+    void *ioaddr = tp->mmio_addr;
+    int nReturn = 0;
+    struct rtnet_device_monitoring*  psDeviceMonit = cmd;
+    switch( request )
+    {
+        case RTNET_RTIOC_MONITORING_LINK_BEAT :
+        {
+            if(RTL_R16 (CSCR) & CSCR_LinkOKBit)
+                psDeviceMonit->link_beat = 1;
+            else
+                psDeviceMonit->link_beat = 0;
+            break;
+        }
+        default :
+        {
+            rtdm_printk("rtl8139_ioctl: IOCTL not implemented.\n");
+            nReturn = -ENOIOCTLCMD;
+            break;
+        }
+    }
+    rtdev_dereference(rtdev);
+    return nReturn;
+}
 
 static void rtl8139_tx_interrupt (struct rtnet_device *rtdev,
                                   struct rtl8139_private *tp,
@@ -1661,7 +1689,7 @@
                    an first get an additional status bit from CSCR. */
                 if (status & RxUnderrun)
                         link_changed = RTL_R16 (CSCR) & CSCR_LinkChangeBit;
-
+ 
                 /* The chip takes special action when we clear RxAckBits,
                  * so we clear them later in rtl8139_rx_interrupt
                  */
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
RTnet-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/rtnet-developers

Reply via email to