This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Adding Promiscous Mode Support to NIMU

Other Parts Discussed in Thread: OMAPL138

Reference SPRU523G,  see page 10.  There it says that the older LL Packet Driver archtecture provided an interface for a single device driver, while the newer NIMU architecture overcomes that "limitation", and is suited to ethernet devices where it is common to have multiple instances running concurrently.  It concludes that the LL Packet driver architecture is no longer supported.  Presumanly, that means we now have a single API layer that implements a full network stack that can run multiple services.

Here is an example where things are perhaps a little bit broken or incomplete.

For several weeks now i have been asking the simple question, how do you do raw i/o in such a way that you receive all packets regarldess of mac header.

Putting it another way, how do you put the interface in promiscous mode, and how do you turn off the ether type  filter in the NIMU?

The answer seems to be: you don't.    That is, unless you are willing to do some hacking.

Here is what i have worked out so far.  Please feel free to tell me if there is an easier way to do this.

For reference, we are working with the C6748,  and so far it seems the network code drives from the omapl138 stuff in the ndk and nsp.

Take a look at nimu_eth.c and in EmacStart() you find a single call to HwPktSetRx()  to set the receive filter to multicast. It is not set anywhere else in this source file.  There is an Emacioctl(),  But it only adds and remove mulitcast addresses. Emacioctl() is called from NIMUIoctl(), from the default case in the cmd switch.   So perhaps all we need for promiscous mode is one patch in nimu_eth.c and then an NIMUIoctl()  in our application.

Now to understand what the fucntion HwPktSetRx() is about, take a look at ethdriver.c. First it sets up a multicast list, and then it sets the filter.  Filter constants are defined in etherif.h.    The multicast list is a bit confusing, but lets work our way up and see how, or if, it ever gets set.

The bottom of the call tree is  EmacStart -> HwPktSetRx(), but where is EmacStart called?   In EmacInit(), we find NETIF_DEVICE *ptr_device->start = EmacStart.;, and then NIMURegister(ptr_device);.  In nimu.c we see that the start function is called in NIMURegister, and the init fucntion is called from NIMUInit().    So where is NMUInit called?    Once again, grep comes to the rescue, and there it is in netctrl.c, in NC_NetStart().  Wonderful.  What about that multicast?  Well again, grep -i mcast, and we find nobody sets it. 

So presumably, that means we're home free.  We can add an ioctl to set promiscous mode in the Emacicotl, give it a unique cmd value, and NIMUIoctly will pass it thru and take care of the llenter, llexit, etc. for us.   Voila.

Now, how about turning off that filtering on ether type that happens int the NIMU? We find the offending code in nimu.c in NIMUPacketServiceCheck().  The least intrusive way to kluge a true "pass everything" raw receive into this, might be to set an external from another ioctl that we add, or perhaps add a field to the interface structure, and either way, check it at the top of NIMURecieve and then pass the packet straight up if its supposed to be a raw receive, essentially short circuiting the rest of the nimu service gizmo.  The pros and cons are the extra ops it takes to get it from the multiple indirect references versus a single extern that does it to everything.  and there you have it.

I hope that someone will please let me if the above plan seems correct.

Thank you