mac位址在一般情況下是從網絡卡的eeprom中讀取的,一般廠商會在出廠的時候固化在eeprom中,在有些時候,廠商為了省錢不會去買乙個固定的唯一的mac,而是始終用乙個固定的mac位址,這樣就會在後續使用者使用的時候造成mac位址衝突。
#define qf9700_automac
#ifdef qf9700_automac
/* global variables for file-based mac address machenism */
int mac_used[129] = ;
int dev_addr[129] = ;
define_spinlock(qf9700_lock);
#endif
定義乙個核心自旋鎖qf9700_lock。
mac位址的讀寫主要在驅動的bind函式中
static const struct driver_info qf9700_info = ;
以下是bind函式,巨集qf9700_automac定義包含的就是需要新增的功能
static int qf9700_bind(struct usbnet *dev, struct usb_inte***ce *intf)
; struct file *fp;
mm_segment_t fs;
loff_t pos;
#endif
ret = usbnet_get_endpoints(dev, intf);
if (ret)
goto out;
dev->net->netdev_ops = &qf9700_netdev_ops;
dev->net->ethtool_ops = &qf9700_ethtool_ops;
dev->net->hard_header_len += qf_tx_overhead;
dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
dev->rx_urb_size = dev->net->mtu + eth_hlen + qf_rx_overhead;
dev->mii.dev = dev->net;
dev->mii.mdio_read = qf9700_mdio_read;
dev->mii.mdio_write = qf9700_mdio_write;
dev->mii.phy_id_mask = 0x1f;
dev->mii.reg_num_mask = 0x1f;
/* reset the qf9700 */
qf_write_reg(dev, ncr, 1);
udelay(20);
/* read mac */
if (qf_read(dev, par, eth_alen, dev->net->dev_addr) < 0)
#ifdef qf9700_automac
/* compare with the file-based mac address * this is for dongle or product without eeprom condition */
if (memcmp( dev->net->dev_addr, defaultaddress, eth_alen ) == 0)
fs = get_fs();
set_fs(kernel_ds);
random_ether_addr(dev->net->dev_addr);
*(u8 *)(dev->net->dev_addr + 0) = 0;
pos = 0;
vfs_write(fp, dev->net->dev_addr, eth_alen, &pos);
}
else
pos = 0;
vfs_read(fp, dev->net->dev_addr, eth_alen, &pos);
filp_close(fp, null);
set_fs(fs);
dev_addr[i] = dev->udev->devnum;
mac_used[i] = 1;
/* *(u8*)(dev->net->dev_addr + 0) += i;
*(u8*)(dev->net->dev_addr + 1) += i;
*(u8*)(dev->net->dev_addr + 2) += i;
*(u8*)(dev->net->dev_addr + 3) += i;
*(u8*)(dev->net->dev_addr + 4) += i;*/
*(u8*)(dev->net->dev_addr + 5) += i;
break;
}
} spin_unlock(&qf9700_lock);
/* set the mac address */
if ((ret = qf_write (dev, par, eth_alen, dev->net->dev_addr)) < 0)
} netif_carrier_off(dev->net);
#endif
/* power up and reset phy */
qf_write_reg(dev, prr, 1);
mdelay(20); // at least 10ms, here 20ms for safe
qf_write_reg(dev, prr, 0);
mdelay(2); // at least 1ms, here 2ms for reading right register
/* receive broadcast packets */
qf9700_set_multicast(dev->net);
qf9700_mdio_write(dev->net, dev->mii.phy_id, mii_bmcr, bmcr_reset);
qf9700_mdio_write(dev->net, dev->mii.phy_id, mii_advertise, advertise_all | advertise_csma | advertise_pause_cap);
mii_nway_restart(&dev->mii);
out:
return ret;
}
Linux網絡卡驅動中對於組播MAC位址的獲取
對於2.6的核心,net device內部存在乙個結構體指標,struct dev mc list dev mc list通過對它的訪問,可以迴圈獲取所有的組播mac位址。但是,在新的核心中 至少在3.10中 發生了變化,取而代之的是 struct netdev hw addr list mc 我們...
繫結mac位址與網絡卡驅動wlan
按照之前部落格的配置,我們可以在樹莓派上實現雙網絡卡,但是再多次試驗中發現,每次重啟後,網絡卡的順序都可能發生變化,也就是mac位址與wlan的關係不確定。網上很多資料說是修改 etc network inte ces檔案,但這是沒有用的,它只會修改網絡卡的mac位址,而不改變實際的繫結。正確的繫結...
獲取網絡卡MAC位址
做網路程式設計的程式設計師免不了要與mac位址打交道,這個128bit的數字串在某種程度上就代表了機器的唯一性,因此在做統計工作時一般都以mac位址作為標準。下面介紹兩種獲取本機mac位址的方式。1.通過請求netbios服務獲取mac位址 2.通過iphelpapi獲取。第一種方法要求本機開啟了n...