Explanation of struct ieee80211_local in Linux kernel - linux-kernel

Can anybody explain me the ieee80211_local structure and its members?
The structure is defined in /net/mac80211/ieee80211_i.h of the Linux source code, somewhere near line no. 930, it may vary with different kernel versions.

According to a presentation by Daniel Camps Mur struct ieee80211_local "…contains information about the real hardware, and is created when the interface is first added."
In another set of slides by Johannes Berg it is stated that the struct "represents a wireless device." On the same slide, you can find a statement about the element ieee80211_hw "…is the part of ieee80211_local that is visible to drivers."
Interestingly, the struct is not mentioned in the 802.11 subsystems documentation by Johannes Berg.
Looking at a source code cross reference of the Linux kernel, you can see that the
ieee80211_local struct is never used outside of the mac80211 part. Therefore, I think that it is indeed an internally used representation of a wireless device from mac80211's point of view.
In contrast, you can see that the ieee80211_hw element is used in both mac80211 and various wireless device drivers which underlines that it is used to communicate between mac80211 and drivers.
BTW, the struct was introduced with the very first commit of ieee80211_i.h by Jiri Benc in 2007.
If you need to know more details about the struct and its members, it looks like you want to do some development at the mac80211 code. I would suggest to get in touch with the active developers. The Linux wireless mailing list may be a good starting point for that.

Related

What is the purpose of class and class device?

I followed some tutorials that explained how to write Linux kernel modules and I am a bit confused. Even after reading the official "documentation", I have poor understanding of the concepts.
After creating a character device (register_chrdev), I see it is common to use a combination of the following functions:
class_create
class_device_create
device_create
I was not able to understand, what is a class, device and, class device and driver?
Which one of these actually responsible to create an entry under /proc/?
Rather than going into what's a class, or what's a device (I'm no expert in Linux kernel), I will address the question as follows.
After creating the character device, you want to be able to access it from the user space. To do this, you need to add a device node under /dev. You can do this in two ways.
Use mknod to manually add a device node (old)
mknod /dev/<name> c <major> <minor>
OR
Use udev
This is where the class_create and device_create or class_device_create (old) come in.
To notify udev from your kernel module, you first create a virtual device class using
struct class * class_create(owner, name)
Now, the name will appear in /sys/class/<name>.
Then, create a device and register it with sysfs.
struct device *device_create(struct class *class, struct device *parent,
dev_t devt, void *drvdata, const char *fmt, ...)
Now, device name will appear in /sys/devices/virtual/<class name>/<device name> and /dev/<device name>
It's not clear what you are asking about the /proc entry.
After your module is loaded, it will appear in /proc/modules (do a cat /proc/modules to see it). And, after you allocate the device numbers, say with
int register_chrdev_region(dev_t first, unsigned int count, char *name)
, the name will appear in /proc/devices (do a cat /proc/devices to see it).
And, please check the kernel sources for these functions as well, as they provide a good description of what they do in their comments.
The good old LDD3 does not provide these mechanisms, but it's a very good source.

Where to find device-tree?

Coming form this question yesterday, I decided to port this library to my board. I was aware that I needed to change something, so I compiled the library, call it on a small program and see what happens. The 1st problem is here:
// Check for GPIO and peripheral addresses from device tree.
// Adapted from code in the RPi.GPIO library at:
// http://sourceforge.net/p/raspberry-gpio-python/
FILE *fp = fopen("/proc/device-tree/soc/ranges", "rb");
if (fp == NULL) {
return MMIO_ERROR_OFFSET;
}
This lib is aimed for Rpi, os the structure of the system on my board is not the same. So I was wondering if somebody could tell me where I could find this file or how it looks like so I can find it by my self in order to proceed the job.
Thanks.
You don't necessarily want that "file" (or more precisely /proc node).
The code this is found in is setting up to do direct memory mapped I/O using what appears to be a pi-specific gpio-flavored version of the /dev/mem type of device driver for exposing hardware special function registers to userspace.
To port this to your board, you would need to first determine if there is a /dev/mem or similar capability in your kernel which you can activate. Then you would need to determine the appropriate I/O registers for GPIO pins. The pi-specific code is reading the Device Tree to figure this out, but there are other ways, for example you can manually read the programmer's manual of the SoC on which you are running.
Another approach you can consider is adding some small microcontroller (or yes, barebones ***duino) to the system, and using that to collect information from various sensors and peripherals. This can then be forwarded to the SoC over a UART link, or queried out via I2C or similar - add a small amount of cost and some degree of bottleneck, but also means that the software on the SoC then becomes very portable - to a different comparable chip, or perhaps even to run on a desktop PC during development.

My attributes are way too racy, what should I do?

In a linux device driver, creating sysfs attributes in probe is way too racy--specifically, it experiences a race condition with userspace. The recommended workaround is to add your attributes to various default attribute groups so they can be automatically created before probe. For a device driver, struct device_driver contains const struct attribute_group **groups for this purpose.
However, struct attribute_group only got a field for binary attributes in Linux 3.11. With older kernels (specifically, 3.4), how should a device driver create sysfs binary attributes before probe?
Quoting (emphasis mine) Greg Kroah-Hartman from his comment to a merge request (that was merged by Linus as a part of 3.11 development cycle):
Here are some driver core patches for 3.11-rc2. They aren't really
bugfixes, but a bunch of new helper macros for drivers to properly
create attribute groups, which drivers and subsystems need to fix up a
ton of race issues with incorrectly creating sysfs files (binary and
normal) after userspace has been told that the device is present.
Also here is the ability to create binary files as attribute groups, to solve that race condition, which was impossible to do before this, so that's my fault the drivers were broken.
So it looks like there really is no way to solve this problem on old kernels.

Documentation for regulator framework with device tree

I would like to know if there is any documentation for the linux kernel regulator framework with device tree. I am totally lost with consumer name and lists. I need to add consumers from device tree but I cant see consumer list at all in the device tree files.
I am using AM335x based custom board based on TI sitara.
By reading both documentation (DeviceTree and Regulator) you should be able to find what you want. But as usual the best documentation is the code itself. The driver ti-abb-regulator is using the DeviceTree and the Regulator framework.
In addition, Federico has already said, there are so-called MFD(MultiFunction) devices. These are often referred PMIC(Power Management IC) that are used in conjunction with a SOC from TI. For AM335x it maybe TPS65217, TPS65910A, TPS65910x, TPS650250, etc. If so, that means some of them you can find follow this link: MFD.
I was just looking into this myself, and my conclusion is that the setup in device tree is pretty different from the way it's done in the board file.
What you'll need to do is to add your drivers to the device tree as well, and then use the "[name]-supply" notation, e.g.:
cpus {
cpu0 {
cpu0-supply = <&omap_tps65912_dcdc1>;
};
};
If you look for this in other board files, you'll see how it works.

How do I port a serial port device driver from Linux 2.6.21 to 2.6.36?

It appears that some time between these two kernels a lot of data structures were changed, and it breaks my driver in several places.
First, in 2.6.21 the struct uart_port had a field "struct uart_info *info" which I relied on in several places. I test several places to make sure it is non-null, and if non-null I additionally test if it's sub-field (struct tty_struct *tty) is non-null, and I uses these to check if flow control is enabled and if we are stopped transmitting.
In 2.6.36 the info back pointer has been removed and I'm not sure how to get at it, or if the semantics of what I am trying to do are even valid any more, as the only serial driver that even uses this appears to have ifdef'ed out the code dealing with it, and additionally holds all this data in its own structures (how does that work to even correctly maintain state with the kernel)???
Additionally, save_and_cli() and restore_flags() are missing. I see new functions local_irq_save() and local_irq_restore(), can I just switch to using those, or are there any gotchas?
Finally, __ioremap is missing. Looks like maybe ioremap_noncache is the replacement, but again I'm not sure if there are any semantic differences or gotchas. I would assume I don't want ioremap() since I am talking directly to hardware, but some other drivers appear to do so and I don't know why that would work.
Looking at how an in-tree driver that uses the same functionality has changed between the two versions is usually the best way to go. For example, the ioc4_serial driver uses the info member of struct uart_port in kernel 2.6.21, but has switched to using the struct uart_state *state member by kernel 2.6.36.
That driver obtains the tty_struct with:
state = the_port->state;
tty = state->port.tty;

Resources