#include <linux/netdevice.h>
#include <linux/tcp.h>
#include <linux/ipv6.h>
+#include <linux/slab.h>
#include <net/checksum.h>
#include <net/ip6_checksum.h>
#include <linux/mii.h>
length = le16_to_cpu(rx_desc->length);
- /* !EOP means multiple descriptors were used to store a single
- * packet, also make sure the frame isn't just CRC only */
- if (!(status & E1000_RXD_STAT_EOP) || (length <= 4)) {
+ /*
+ * !EOP means multiple descriptors were used to store a single
+ * packet, if that's the case we need to toss it. In fact, we
+ * need to toss every packet with the EOP bit clear and the
+ * next frame that _does_ have the EOP bit set, as it is by
+ * definition only a frame fragment
+ */
+ if (unlikely(!(status & E1000_RXD_STAT_EOP)))
+ adapter->flags2 |= FLAG2_IS_DISCARDING;
+
+ if (adapter->flags2 & FLAG2_IS_DISCARDING) {
/* All receives must fit into a single buffer */
e_dbg("Receive packet consumed multiple buffers\n");
/* recycle */
buffer_info->skb = skb;
+ if (status & E1000_RXD_STAT_EOP)
+ adapter->flags2 &= ~FLAG2_IS_DISCARDING;
goto next_desc;
}
static void e1000_put_txbuf(struct e1000_adapter *adapter,
struct e1000_buffer *buffer_info)
{
- buffer_info->dma = 0;
+ if (buffer_info->dma) {
+ if (buffer_info->mapped_as_page)
+ pci_unmap_page(adapter->pdev, buffer_info->dma,
+ buffer_info->length, PCI_DMA_TODEVICE);
+ else
+ pci_unmap_single(adapter->pdev, buffer_info->dma,
+ buffer_info->length,
+ PCI_DMA_TODEVICE);
+ buffer_info->dma = 0;
+ }
if (buffer_info->skb) {
- skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
- DMA_TO_DEVICE);
dev_kfree_skb_any(buffer_info->skb);
buffer_info->skb = NULL;
}
i = 0;
}
+ if (i == tx_ring->next_to_use)
+ break;
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop);
}
adapter->detect_tx_hung = 0;
if (tx_ring->buffer_info[i].time_stamp &&
time_after(jiffies, tx_ring->buffer_info[i].time_stamp
- + (adapter->tx_timeout_factor * HZ))
- && !(er32(STATUS) & E1000_STATUS_TXOFF)) {
+ + (adapter->tx_timeout_factor * HZ)) &&
+ !(er32(STATUS) & E1000_STATUS_TXOFF)) {
schedule_work(&adapter->print_hang_task);
netif_stop_queue(netdev);
}
PCI_DMA_FROMDEVICE);
buffer_info->dma = 0;
- if (!(staterr & E1000_RXD_STAT_EOP)) {
+ /* see !EOP comment in other rx routine */
+ if (!(staterr & E1000_RXD_STAT_EOP))
+ adapter->flags2 |= FLAG2_IS_DISCARDING;
+
+ if (adapter->flags2 & FLAG2_IS_DISCARDING) {
e_dbg("Packet Split buffers didn't pick up the full "
"packet\n");
dev_kfree_skb_irq(skb);
+ if (staterr & E1000_RXD_STAT_EOP)
+ adapter->flags2 &= ~FLAG2_IS_DISCARDING;
goto next_desc;
}
rx_ring->next_to_clean = 0;
rx_ring->next_to_use = 0;
+ adapter->flags2 &= ~FLAG2_IS_DISCARDING;
writel(0, adapter->hw.hw_addr + rx_ring->head);
writel(0, adapter->hw.hw_addr + rx_ring->tail);
ew32(TCTL, tctl);
e1000e_config_collision_dist(hw);
-
- adapter->tx_queue_len = adapter->netdev->tx_queue_len;
}
/**
rctl &= ~E1000_RCTL_SZ_4096;
rctl |= E1000_RCTL_BSEX;
switch (adapter->rx_buffer_len) {
- case 256:
- rctl |= E1000_RCTL_SZ_256;
- rctl &= ~E1000_RCTL_BSEX;
- break;
- case 512:
- rctl |= E1000_RCTL_SZ_512;
- rctl &= ~E1000_RCTL_BSEX;
- break;
- case 1024:
- rctl |= E1000_RCTL_SZ_1024;
- rctl &= ~E1000_RCTL_BSEX;
- break;
case 2048:
default:
rctl |= E1000_RCTL_SZ_2048;
* @hw: pointer to the HW structure
* @mc_addr_list: array of multicast addresses to program
* @mc_addr_count: number of multicast addresses to program
- * @rar_used_count: the first RAR register free to program
- * @rar_count: total number of supported Receive Address Registers
*
- * Updates the Receive Address Registers and Multicast Table Array.
+ * Updates the Multicast Table Array.
* The caller must have a packed mc_addr_list of multicast addresses.
- * The parameter rar_count will usually be hw->mac.rar_entry_count
- * unless there are workarounds that change this. Currently no func pointer
- * exists and all implementations are handled in the generic version of this
- * function.
**/
static void e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list,
- u32 mc_addr_count, u32 rar_used_count,
- u32 rar_count)
+ u32 mc_addr_count)
{
- hw->mac.ops.update_mc_addr_list(hw, mc_addr_list, mc_addr_count,
- rar_used_count, rar_count);
+ hw->mac.ops.update_mc_addr_list(hw, mc_addr_list, mc_addr_count);
}
/**
{
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
- struct e1000_mac_info *mac = &hw->mac;
struct dev_mc_list *mc_ptr;
u8 *mta_list;
u32 rctl;
ew32(RCTL, rctl);
- if (netdev->mc_count) {
- mta_list = kmalloc(netdev->mc_count * 6, GFP_ATOMIC);
+ if (!netdev_mc_empty(netdev)) {
+ mta_list = kmalloc(netdev_mc_count(netdev) * 6, GFP_ATOMIC);
if (!mta_list)
return;
/* prepare a packed array of only addresses. */
- mc_ptr = netdev->mc_list;
-
- for (i = 0; i < netdev->mc_count; i++) {
- if (!mc_ptr)
- break;
- memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr,
- ETH_ALEN);
- mc_ptr = mc_ptr->next;
- }
+ i = 0;
+ netdev_for_each_mc_addr(mc_ptr, netdev)
+ memcpy(mta_list + (i++ * ETH_ALEN),
+ mc_ptr->dmi_addr, ETH_ALEN);
- e1000_update_mc_addr_list(hw, mta_list, i, 1,
- mac->rar_entry_count);
+ e1000_update_mc_addr_list(hw, mta_list, i);
kfree(mta_list);
} else {
/*
* if we're called from probe, we might not have
* anything to do here, so clear out the list
*/
- e1000_update_mc_addr_list(hw, NULL, 0, 1, mac->rar_entry_count);
+ e1000_update_mc_addr_list(hw, NULL, 0);
}
}
**/
void e1000e_power_up_phy(struct e1000_adapter *adapter)
{
- u16 mii_reg = 0;
-
- /* Just clear the power down bit to wake the phy back up */
- if (adapter->hw.phy.media_type == e1000_media_type_copper) {
- /*
- * According to the manual, the phy will retain its
- * settings across a power-down/up cycle
- */
- e1e_rphy(&adapter->hw, PHY_CONTROL, &mii_reg);
- mii_reg &= ~MII_CR_POWER_DOWN;
- e1e_wphy(&adapter->hw, PHY_CONTROL, mii_reg);
- }
+ if (adapter->hw.phy.ops.power_up)
+ adapter->hw.phy.ops.power_up(&adapter->hw);
adapter->hw.mac.ops.setup_link(&adapter->hw);
}
/**
* e1000_power_down_phy - Power down the PHY
*
- * Power down the PHY so no link is implied when interface is down
- * The PHY cannot be powered down is management or WoL is active
+ * Power down the PHY so no link is implied when interface is down.
+ * The PHY cannot be powered down if management or WoL is active.
*/
static void e1000_power_down_phy(struct e1000_adapter *adapter)
{
- struct e1000_hw *hw = &adapter->hw;
- u16 mii_reg;
-
/* WoL is enabled */
if (adapter->wol)
return;
- /* non-copper PHY? */
- if (adapter->hw.phy.media_type != e1000_media_type_copper)
- return;
-
- /* reset is blocked because of a SoL/IDER session */
- if (e1000e_check_mng_mode(hw) || e1000_check_reset_block(hw))
- return;
-
- /* manageability (AMT) is enabled */
- if (er32(MANC) & E1000_MANC_SMBUS_EN)
- return;
-
- /* power down the PHY */
- e1e_rphy(hw, PHY_CONTROL, &mii_reg);
- mii_reg |= MII_CR_POWER_DOWN;
- e1e_wphy(hw, PHY_CONTROL, mii_reg);
- mdelay(1);
+ if (adapter->hw.phy.ops.power_down)
+ adapter->hw.phy.ops.power_down(&adapter->hw);
}
/**
del_timer_sync(&adapter->watchdog_timer);
del_timer_sync(&adapter->phy_info_timer);
- netdev->tx_queue_len = adapter->tx_queue_len;
netif_carrier_off(netdev);
adapter->link_speed = 0;
adapter->link_duplex = 0;
if ((hw->phy.type == e1000_phy_82578) ||
(hw->phy.type == e1000_phy_82577)) {
e1e_rphy(hw, HV_SCC_UPPER, &phy_data);
- e1e_rphy(hw, HV_SCC_LOWER, &phy_data);
- adapter->stats.scc += phy_data;
+ if (!e1e_rphy(hw, HV_SCC_LOWER, &phy_data))
+ adapter->stats.scc += phy_data;
e1e_rphy(hw, HV_ECOL_UPPER, &phy_data);
- e1e_rphy(hw, HV_ECOL_LOWER, &phy_data);
- adapter->stats.ecol += phy_data;
+ if (!e1e_rphy(hw, HV_ECOL_LOWER, &phy_data))
+ adapter->stats.ecol += phy_data;
e1e_rphy(hw, HV_MCC_UPPER, &phy_data);
- e1e_rphy(hw, HV_MCC_LOWER, &phy_data);
- adapter->stats.mcc += phy_data;
+ if (!e1e_rphy(hw, HV_MCC_LOWER, &phy_data))
+ adapter->stats.mcc += phy_data;
e1e_rphy(hw, HV_LATECOL_UPPER, &phy_data);
- e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data);
- adapter->stats.latecol += phy_data;
+ if (!e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data))
+ adapter->stats.latecol += phy_data;
e1e_rphy(hw, HV_DC_UPPER, &phy_data);
- e1e_rphy(hw, HV_DC_LOWER, &phy_data);
- adapter->stats.dc += phy_data;
+ if (!e1e_rphy(hw, HV_DC_LOWER, &phy_data))
+ adapter->stats.dc += phy_data;
} else {
adapter->stats.scc += er32(SCC);
adapter->stats.ecol += er32(ECOL);
if ((hw->phy.type == e1000_phy_82578) ||
(hw->phy.type == e1000_phy_82577)) {
e1e_rphy(hw, HV_COLC_UPPER, &phy_data);
- e1e_rphy(hw, HV_COLC_LOWER, &phy_data);
- hw->mac.collision_delta = phy_data;
+ if (!e1e_rphy(hw, HV_COLC_LOWER, &phy_data))
+ hw->mac.collision_delta = phy_data;
} else {
hw->mac.collision_delta = er32(COLC);
}
if ((hw->phy.type == e1000_phy_82578) ||
(hw->phy.type == e1000_phy_82577)) {
e1e_rphy(hw, HV_TNCRS_UPPER, &phy_data);
- e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data);
- adapter->stats.tncrs += phy_data;
+ if (!e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data))
+ adapter->stats.tncrs += phy_data;
} else {
if ((hw->mac.type != e1000_82574) &&
(hw->mac.type != e1000_82583))
((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" )));
}
-bool e1000_has_link(struct e1000_adapter *adapter)
+bool e1000e_has_link(struct e1000_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
bool link_active = 0;
u32 link, tctl;
int tx_pending = 0;
- link = e1000_has_link(adapter);
+ link = e1000e_has_link(adapter);
if ((netif_carrier_ok(netdev)) && link) {
e1000e_enable_receives(adapter);
goto link_up;
"link gets many collisions.\n");
}
- /*
- * tweak tx_queue_len according to speed/duplex
- * and adjust the timeout factor
- */
- netdev->tx_queue_len = adapter->tx_queue_len;
+ /* adjust timeout factor according to speed/duplex */
adapter->tx_timeout_factor = 1;
switch (adapter->link_speed) {
case SPEED_10:
txb2b = 0;
- netdev->tx_queue_len = 10;
adapter->tx_timeout_factor = 16;
break;
case SPEED_100:
txb2b = 0;
- netdev->tx_queue_len = 100;
adapter->tx_timeout_factor = 10;
break;
}
0, IPPROTO_TCP, 0);
cmd_length = E1000_TXD_CMD_IP;
ipcse = skb_transport_offset(skb) - 1;
- } else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) {
+ } else if (skb_is_gso_v6(skb)) {
ipv6_hdr(skb)->payload_len = 0;
tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
&ipv6_hdr(skb)->daddr,
unsigned int mss)
{
struct e1000_ring *tx_ring = adapter->tx_ring;
+ struct pci_dev *pdev = adapter->pdev;
struct e1000_buffer *buffer_info;
unsigned int len = skb_headlen(skb);
- unsigned int offset, size, count = 0, i;
+ unsigned int offset = 0, size, count = 0, i;
unsigned int f;
- dma_addr_t *map;
i = tx_ring->next_to_use;
- if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
- dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
- adapter->tx_dma_failed++;
- return 0;
- }
-
- map = skb_shinfo(skb)->dma_maps;
- offset = 0;
-
while (len) {
buffer_info = &tx_ring->buffer_info[i];
size = min(len, max_per_txd);
buffer_info->length = size;
buffer_info->time_stamp = jiffies;
buffer_info->next_to_watch = i;
- buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
- count++;
+ buffer_info->dma = pci_map_single(pdev, skb->data + offset,
+ size, PCI_DMA_TODEVICE);
+ buffer_info->mapped_as_page = false;
+ if (pci_dma_mapping_error(pdev, buffer_info->dma))
+ goto dma_error;
len -= size;
offset += size;
+ count++;
if (len) {
i++;
frag = &skb_shinfo(skb)->frags[f];
len = frag->size;
- offset = 0;
+ offset = frag->page_offset;
while (len) {
i++;
buffer_info->length = size;
buffer_info->time_stamp = jiffies;
buffer_info->next_to_watch = i;
- buffer_info->dma = map[f] + offset;
+ buffer_info->dma = pci_map_page(pdev, frag->page,
+ offset, size,
+ PCI_DMA_TODEVICE);
+ buffer_info->mapped_as_page = true;
+ if (pci_dma_mapping_error(pdev, buffer_info->dma))
+ goto dma_error;
len -= size;
offset += size;
tx_ring->buffer_info[first].next_to_watch = i;
return count;
+
+dma_error:
+ dev_err(&pdev->dev, "TX DMA map failed\n");
+ buffer_info->dma = 0;
+ if (count)
+ count--;
+
+ while (count--) {
+ if (i==0)
+ i += tx_ring->count;
+ i--;
+ buffer_info = &tx_ring->buffer_info[i];
+ e1000_put_txbuf(adapter, buffer_info);;
+ }
+
+ return 0;
}
static void e1000_tx_queue(struct e1000_adapter *adapter,
u16 length, offset;
if (vlan_tx_tag_present(skb)) {
- if (!((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id)
- && (adapter->hw.mng_cookie.status &
+ if (!((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id) &&
+ (adapter->hw.mng_cookie.status &
E1000_MNG_DHCP_COOKIE_STATUS_VLAN)))
return 0;
}
return -EINVAL;
}
+ /* 82573 Errata 17 */
+ if (((adapter->hw.mac.type == e1000_82573) ||
+ (adapter->hw.mac.type == e1000_82574)) &&
+ (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN)) {
+ adapter->flags2 |= FLAG2_DISABLE_ASPM_L1;
+ e1000e_disable_aspm(adapter->pdev, PCIE_LINK_STATE_L1);
+ }
+
while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
msleep(1);
/* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */
* fragmented skbs
*/
- if (max_frame <= 256)
- adapter->rx_buffer_len = 256;
- else if (max_frame <= 512)
- adapter->rx_buffer_len = 512;
- else if (max_frame <= 1024)
- adapter->rx_buffer_len = 1024;
- else if (max_frame <= 2048)
+ if (max_frame <= 2048)
adapter->rx_buffer_len = 2048;
else
adapter->rx_buffer_len = 4096;
e1000_media_type_internal_serdes) {
/* keep the laser running in D3 */
ctrl_ext = er32(CTRL_EXT);
- ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
+ ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA;
ew32(CTRL_EXT, ctrl_ext);
}
}
}
-static void e1000e_disable_l1aspm(struct pci_dev *pdev)
+#ifdef CONFIG_PCIEASPM
+static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
+{
+ pci_disable_link_state(pdev, state);
+}
+#else
+static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
{
int pos;
- u16 val;
+ u16 reg16;
/*
- * 82573 workaround - disable L1 ASPM on mobile chipsets
- *
- * L1 ASPM on various mobile (ich7) chipsets do not behave properly
- * resulting in lost data or garbage information on the pci-e link
- * level. This could result in (false) bad EEPROM checksum errors,
- * long ping times (up to 2s) or even a system freeze/hang.
- *
- * Unfortunately this feature saves about 1W power consumption when
- * active.
+ * Both device and parent should have the same ASPM setting.
+ * Disable ASPM in downstream component first and then upstream.
*/
- pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
- pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &val);
- if (val & 0x2) {
- dev_warn(&pdev->dev, "Disabling L1 ASPM\n");
- val &= ~0x2;
- pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, val);
- }
+ pos = pci_pcie_cap(pdev);
+ pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, ®16);
+ reg16 &= ~state;
+ pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
+
+ if (!pdev->bus->self)
+ return;
+
+ pos = pci_pcie_cap(pdev->bus->self);
+ pci_read_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, ®16);
+ reg16 &= ~state;
+ pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16);
+}
+#endif
+void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
+{
+ dev_info(&pdev->dev, "Disabling ASPM %s %s\n",
+ (state & PCIE_LINK_STATE_L0S) ? "L0s" : "",
+ (state & PCIE_LINK_STATE_L1) ? "L1" : "");
+
+ __e1000e_disable_aspm(pdev, state);
}
#ifdef CONFIG_PM
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
- e1000e_disable_l1aspm(pdev);
+ pci_save_state(pdev);
+ if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
+ e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
err = pci_enable_device_mem(pdev);
if (err) {
int err;
pci_ers_result_t result;
- e1000e_disable_l1aspm(pdev);
+ if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
+ e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
err = pci_enable_device_mem(pdev);
if (err) {
dev_err(&pdev->dev,
} else {
pci_set_master(pdev);
pci_restore_state(pdev);
+ pci_save_state(pdev);
pci_enable_wake(pdev, PCI_D3hot, 0);
pci_enable_wake(pdev, PCI_D3cold, 0);
dev_warn(&adapter->pdev->dev,
"Warning: detected DSPD enabled in EEPROM\n");
}
-
- ret_val = e1000_read_nvm(hw, NVM_INIT_3GIO_3, 1, &buf);
- if (!ret_val && (le16_to_cpu(buf) & (3 << 2))) {
- /* ASPM enable */
- dev_warn(&adapter->pdev->dev,
- "Warning: detected ASPM enabled in EEPROM\n");
- }
}
static const struct net_device_ops e1000e_netdev_ops = {
u16 eeprom_data = 0;
u16 eeprom_apme_mask = E1000_EEPROM_APME;
- e1000e_disable_l1aspm(pdev);
+ if (ei->flags2 & FLAG2_DISABLE_ASPM_L1)
+ e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
err = pci_enable_device_mem(pdev);
if (err)
e1000_eeprom_checks(adapter);
- /* copy the MAC address out of the NVM */
+ /* copy the MAC address */
if (e1000e_read_mac_addr(&adapter->hw))
e_err("NVM Read Error while reading MAC address\n");
cancel_work_sync(&adapter->print_hang_task);
flush_scheduled_work();
+ if (!(netdev->flags & IFF_UP))
+ e1000_power_down_phy(adapter);
+
+ unregister_netdev(netdev);
+
/*
* Release control of h/w to f/w. If f/w is AMT enabled, this
* would have already happened in close and is redundant.
*/
e1000_release_hw_control(adapter);
- unregister_netdev(netdev);
-
- if (!e1000_check_reset_block(&adapter->hw))
- e1000_phy_hw_reset(&adapter->hw);
-
e1000e_reset_interrupt_capability(adapter);
kfree(adapter->tx_ring);
kfree(adapter->rx_ring);
.resume = e1000_io_resume,
};
-static struct pci_device_id e1000_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_COPPER), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_FIBER), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_C), board_ich8lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M), board_ich8lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M_AMT), board_ich8lan },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_82567V_3), board_ich8lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE), board_ich9lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_G), board_ich9lan },