Note : depuis mon patch à été ajouté directement dans les drivers natif …
Le drivers rt2570, correspondant aux chip USB ralink souffre d’un petit bug, à moins qu’il ne s’agisse d’une fonctionnalité, je ne sais pas ! il n’est pas possible de changer leur adresse MAC.
Après analyse du problème, il s’avère que lorsque l’on remonte le driver par un ifconfig rausb0 up celui-ci effectue une réinitialisation complète du périphérique incluant donc le rechargement de l’adresse MAC d’origine et venant donc écraser celle configurée précédemment par le ifconfig rausb0 hw ether ….
La solution a ce problème est assez simple, lors de l’init que l’on trouve dans rtusb_main.c il suffit de tester si l’adresse MAC du net_dev vaut 00, auquel cas on charge celle de la carte (premier appel) sinon, on conserve la valeur du net_dev qui correspond à celle forcée.
Ce qui se traduit par :
Dans la fonction usb_rtusb_open, ligne 1231 environ
RTUSBCmd_kill =0;
CreateThreads(net_dev);
memcpy(pAdapter->net->dev_addr, pAdapter->CurrentAddress, pAdapter->net->addr_len);
// Clear Reset Flag before starting receiving/transmitting
RTMP_CLEAR_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS);Va devenir:
RTUSBCmd_kill =0;
CreateThreads(net_dev);
// at every open handler, copy mac address.
// PATCH >>>>>>>>>>>>>>>>>>
if ( net_dev->dev_addr[0] == 0 && net_dev->dev_addr[1] == 0 && net_dev->dev_addr[2] == 0 &&
net_dev->dev_addr[3] == 0 && net_dev->dev_addr[4] == 0 && net_dev->dev_addr[5] == 0 ) {
// First time initialization
memcpy(pAdapter->net->dev_addr, pAdapter->CurrentAddress, pAdapter->net->addr_len);
} else {
// Next time “la vérité est ailleurs!”
memcpy(pAdapter->CurrentAddress, pAdapter->net->dev_addr, pAdapter->net->addr_len);
}
// <<<<<<<<<<<<<<<<< PATCH// Clear Reset Flag before starting receiving/transmitting
RTMP_CLEAR_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS);
Après on recompile, et la solution a l’air de fonctionner …. ??? et bien en fait non elle ne fonctionne pas !! oups.. j’aurais dû un peu plus tester … j’avais un petit oubli … voila qui est corrigé ! merci à larbig d’avoir complété le boulo.
Il semble en effet que l’adresse MAC doit être la même entre le pAdapter et le net_dev sans quoi les trames ne sont pas emises dans l’air … ennuyeux. voici donc le patch complet et cette fois testé !! sisi !! Les modifications sont cette fois dans rtusb_init.c où il faut modifier la fonction NICReadEEPROMParameters de la façon suivante :
VOID NICReadEEPROMParameters( IN PRT2570ADAPTER pAdapter) { USHORT i; int value; UCHAR TmpPhy; EEPROM_TX_PWR_STRUC Power; EEPROM_ANTENNA_STRUC Antenna;//blue // EEPROM_VERSION_STRUC Version; DBGPRINT(RT_DEBUG_TRACE,"--> NICReadEEPROMParameters "); //Read MAC address. RTUSBReadEEPROM(pAdapter, EEPROM_MAC_ADDRESS_BASE_OFFSET, pAdapter->PermanentAddress, ETH_LENGTH_OF_ADDRESS); DBGPRINT_RAW(RT_DEBUG_TRACE,"MAC address ReadEEPROM : "); for (i = 0; i < ETH_LENGTH_OF_ADDRESS; i++) DBGPRINT_RAW(RT_DEBUG_TRACE,"%02x ", pAdapter->PermanentAddress[i]); DBGPRINT_RAW(RT_DEBUG_TRACE," "); if (pAdapter->PortCfg.bLocalAdminMAC != TRUE) { pAdapter->CurrentAddress[0] = pAdapter->PermanentAddress[0]; pAdapter->CurrentAddress[1] = pAdapter->PermanentAddress[1]; pAdapter->CurrentAddress[2] = pAdapter->PermanentAddress[2]; pAdapter->CurrentAddress[3] = pAdapter->PermanentAddress[3]; pAdapter->CurrentAddress[4] = pAdapter->PermanentAddress[4]; pAdapter->CurrentAddress[5] = pAdapter->PermanentAddress[5]; }
devient
VOID NICReadEEPROMParameters( IN PRT2570ADAPTER pAdapter, struct net_device *net_dev) { USHORT i; int value; UCHAR TmpPhy; EEPROM_TX_PWR_STRUC Power; EEPROM_ANTENNA_STRUC Antenna;//blue // EEPROM_VERSION_STRUC Version; DBGPRINT(RT_DEBUG_TRACE,"--> NICReadEEPROMParameters "); //Read MAC address. RTUSBReadEEPROM(pAdapter, EEPROM_MAC_ADDRESS_BASE_OFFSET, pAdapter->PermanentAddress, ETH_LENGTH_OF_ADDRESS); DBGPRINT_RAW(RT_DEBUG_TRACE,"MAC address ReadEEPROM :"); for (i = 0; i < ETH_LENGTH_OF_ADDRESS; i++) DBGPRINT_RAW(RT_DEBUG_TRACE,"%02x ", pAdapter->PermanentAddress[i]); DBGPRINT_RAW(RT_DEBUG_TRACE,""); if (pAdapter->PortCfg.bLocalAdminMAC != TRUE) { if ( net_dev->dev_addr[0] == 0 && net_dev->dev_addr[1] == 0 && net_dev->dev_addr[2] == 0 && net_dev->dev_addr[3] == 0 && net_dev->dev_addr[4] == 0 && net_dev->dev_addr[5] == 0 ) { // Startup time ... read the original MAC pAdapter->CurrentAddress[0] = pAdapter->PermanentAddress[0]; pAdapter->CurrentAddress[1] = pAdapter->PermanentAddress[1]; pAdapter->CurrentAddress[2] = pAdapter->PermanentAddress[2]; pAdapter->CurrentAddress[3] = pAdapter->PermanentAddress[3]; pAdapter->CurrentAddress[4] = pAdapter->PermanentAddress[4]; pAdapter->CurrentAddress[5] = pAdapter->PermanentAddress[5]; } else { // Next time, get the MAC from net_dev->dev_addr printk(KERN_INFO "net_dev supplies MAC, activating this one :%02x:%02x:%02x:%02x:%02x:%02x.", net_dev->dev_addr[0], net_dev->dev_addr[1], net_dev->dev_addr[2], net_dev->dev_addr[3], net_dev->dev_addr[4], net_dev->dev_addr[5]); memcpy(pAdapter->CurrentAddress, pAdapter->net->dev_addr, pAdapter->net->addr_len); } }
La mécanique est axactement la même que celle faite précédemment : lors du premier appel on fait comme si de rien n’etait et on recupère l’adresse en EEPROM, pour les appels suivant on choisit la MAC du net_dev à la place.
Pour que ca fonctionne il reste deux petites modifications, modifier le header de cette fonction : dans rt2570sw.h
VOID NICReadEEPROMParameters( IN PRT2570ADAPTER pAdapter);
devient :
VOID NICReadEEPROMParameters( IN PRT2570ADAPTER pAdapter, struct net_device *net_dev);
enfin il reste l’appel de la fonction de lecture à modifier, dans rtusb_main.c:
NICReadEEPROMParameters(pAdapter, net_dev);
Ca y est !!