- Support to add/delete/store/restore 64 and 128 Ethernet addresses for Xframe I and Xframe II respectively.
Signed-off-by: Sreenivasa Honnur <[EMAIL PROTECTED]> Signed-off-by: Ramkrishna Vepa <[EMAIL PROTECTED]> --- diff -urpN patch1/drivers/net/s2io.c patch2/drivers/net/s2io.c --- patch1/drivers/net/s2io.c 2007-08-18 05:32:23.000000000 +0530 +++ patch2/drivers/net/s2io.c 2007-08-18 07:19:21.000000000 +0530 @@ -3589,6 +3589,9 @@ static void s2io_reset(struct s2io_nic * /* Set swapper to enable I/O register access */ s2io_set_swapper(sp); + /* restore mac_addr entries */ + restore_mac_and_mc_addr(sp); + /* Restore the MSIX table entries from local variables */ restore_xmsi_data(sp); @@ -3647,9 +3650,6 @@ static void s2io_reset(struct s2io_nic * writeq(val64, &bar0->pcc_err_reg); } - /* restore the previously assigned mac address */ - set_mac_addr(sp->dev, (u8 *)&sp->def_mac_addr[0].mac_addr); - sp->device_enabled_once = FALSE; } @@ -4118,8 +4118,19 @@ hw_init_failed: static int s2io_close(struct net_device *dev) { struct s2io_nic *sp = dev->priv; + struct config_param *config = &sp->config; + u64 tmp64; + int off; netif_stop_queue(dev); + + /* delete all populated mac entries */ + for(off =1; off < config->max_mc_addr; off++) { + tmp64 = read_mac_addr(sp,off); + if(tmp64 != 0xffffffffffffULL) + delete_mac_addr(sp, tmp64); + } + /* Reset card, kill tasklet and free Tx and Rx buffers. */ s2io_card_down(sp); @@ -5044,7 +5055,7 @@ static void s2io_set_multicast(struct ne &bar0->rmac_addr_data1_mem); val64 = RMAC_ADDR_CMD_MEM_WE | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | - RMAC_ADDR_CMD_MEM_OFFSET(MAC_MC_ALL_MC_ADDR_OFFSET); + RMAC_ADDR_CMD_MEM_OFFSET(config->max_mc_addr - 1); writeq(val64, &bar0->rmac_addr_cmd_mem); /* Wait till command completes */ wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, @@ -5052,7 +5063,7 @@ static void s2io_set_multicast(struct ne S2IO_BIT_RESET); sp->m_cast_flg = 1; - sp->all_multi_pos = MAC_MC_ALL_MC_ADDR_OFFSET; + sp->all_multi_pos = config->max_mc_addr - 1; } else if ((dev->flags & IFF_ALLMULTI) && (sp->m_cast_flg)) { /* Disable all Multicast addresses */ writeq(RMAC_ADDR_DATA0_MEM_ADDR(dis_addr), @@ -5121,7 +5132,8 @@ static void s2io_set_multicast(struct ne /* Update individual M_CAST address list */ if ((!sp->m_cast_flg) && dev->mc_count) { if (dev->mc_count > - (MAX_ADDRS_SUPPORTED - MAC_MC_ADDR_START_OFFSET - 1)) { + ((config->max_mc_addr - config->max_mac_addr) + - config->mc_start_offset - 1)) { DBG_PRINT(ERR_DBG, "%s: No more Rx filters ", dev->name); DBG_PRINT(ERR_DBG, "can be added, please enable "); @@ -5141,7 +5153,7 @@ static void s2io_set_multicast(struct ne val64 = RMAC_ADDR_CMD_MEM_WE | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | RMAC_ADDR_CMD_MEM_OFFSET - (MAC_MC_ADDR_START_OFFSET + i); + (config->mc_start_offset + i); writeq(val64, &bar0->rmac_addr_cmd_mem); /* Wait for command completes */ @@ -5173,7 +5185,7 @@ static void s2io_set_multicast(struct ne val64 = RMAC_ADDR_CMD_MEM_WE | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | RMAC_ADDR_CMD_MEM_OFFSET - (i + MAC_MC_ADDR_START_OFFSET); + (i + config->mc_start_offset); writeq(val64, &bar0->rmac_addr_cmd_mem); /* Wait for command completes */ @@ -5188,6 +5200,75 @@ static void s2io_set_multicast(struct ne } } } +/* read from CAM unicast & multicast addresses and store it in + * def_mac_addr structure. + **/ +void store_mac_and_mc_addr(struct s2io_nic *sp) +{ + int offset; + u64 mac_addr=0x0; + struct config_param *config = &sp->config; + + /* store unicast & multicast mac addresses */ + for(offset = 0; offset < config->max_mc_addr; offset++) { + mac_addr = read_mac_addr(sp,offset); + /* if read fails disable the entry */ + if(mac_addr == FAILURE) + mac_addr = 0xffffffffffffULL; + MAC_ADDR_SET(offset,mac_addr); + } +} + +/* restore unicast MAC addresses to CAM from def_mac_addr structure + **/ +static void restore_mac_and_mc_addr(struct s2io_nic *sp) +{ + int offset; + struct config_param *config = &sp->config; + /* restore unicast mac address */ + for(offset = 0; offset < config->max_mac_addr; offset++) + set_mac_addr(sp->dev,sp->def_mac_addr[offset].mac_addr); + + /* restore multicast mac address */ + for(offset = config->mc_start_offset; + offset < config->max_mc_addr; offset++) + add_mc_addr(sp, sp->def_mac_addr[offset].mac_addr); +} + +/* add a multicast MAC address to CAM. + **/ +static int add_mc_addr(struct s2io_nic *sp, u8* addr) +{ + int i; + u64 mac_addr=0; + struct config_param *config = &sp->config; + + for (i = 0; i < ETH_ALEN; i++) { + mac_addr <<= 8; + mac_addr |= addr[i]; + } + if((0ULL == mac_addr) || (mac_addr == 0xffffffffffffULL)) + return SUCCESS; + + /* check if the multicast mac already preset in CAM */ + for(i = config->mc_start_offset; i < config->max_mc_addr; i++) { + u64 tmp64; + tmp64 = read_mac_addr(sp,i); + if(tmp64 == 0xffffffffffffULL) /* CAM entry is empty */ + break; + + if(tmp64 == mac_addr) + return SUCCESS; + } + if(i == config->max_mc_addr) { + DBG_PRINT(ERR_DBG,"CAM full no space left for multicast MAC\n"); + return FAILURE; + } + /* Update the internal structure with this new mac address */ + MAC_ADDR_SET(i, mac_addr); + + return (add_mac_addr(sp,mac_addr,i)); +} /* add MAC address to CAM */ static int add_mac_addr(struct s2io_nic *sp, u64 addr, int off) @@ -5213,6 +5294,53 @@ static int add_mac_addr(struct s2io_nic return SUCCESS; } +/* deletes a specified unicast/multicast mac entry from CAM */ +static int delete_mac_addr(struct s2io_nic *sp,u64 addr) +{ + int off; + u64 dis_addr = 0xffffffffffffULL,tmp64; + struct config_param *config = &sp->config; + + for(off = 1; + off < config->max_mc_addr; off++) { + tmp64 = read_mac_addr(sp,off); + if(tmp64 == addr) { + /* disable the entry by writing 0xffffffffffffULL */ + if(add_mac_addr(sp,dis_addr,off) == FAILURE) + return FAILURE; + /* store the new mac list from CAM */ + store_mac_and_mc_addr(sp); + return SUCCESS; + } + } + DBG_PRINT(ERR_DBG,"MAC address 0x%llx not found in CAM\n", + (unsigned long long)addr); + return FAILURE; +} + +/* read mac entries from CAM */ +static u64 read_mac_addr(struct s2io_nic *sp, int offset) +{ + u64 tmp64=0xffffffffffff0000ULL, val64; + struct XENA_dev_config __iomem *bar0 = sp->bar0; + + /* read mac addr */ + val64 = + RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | + RMAC_ADDR_CMD_MEM_OFFSET(offset); + writeq(val64, &bar0->rmac_addr_cmd_mem); + + /* Wait till command completes */ + if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, + RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, + S2IO_BIT_RESET)) { + DBG_PRINT(INFO_DBG, "read_mac_addr failed\n"); + return FAILURE; + } + tmp64 = readq(&bar0->rmac_addr_data0_mem); + return (tmp64 >> 16); +} + /** * s2io_set_mac_addr driver entry point */ @@ -5243,6 +5371,8 @@ static int set_mac_addr(struct net_devic struct s2io_nic *sp = dev->priv; register u64 mac_addr = 0,perm_addr=0; int i; + u64 tmp64; + struct config_param *config = &sp->config; /* * Set the new MAC address as the new unicast filter and reflect this @@ -5260,9 +5390,28 @@ static int set_mac_addr(struct net_devic if(mac_addr == perm_addr) return SUCCESS; + /* check if the mac already preset in CAM */ + for(i = 1; i < config->max_mac_addr; i++) { + tmp64 = read_mac_addr(sp,i); + if(tmp64 == 0xffffffffffffULL) /* CAM entry is empty */ + break; + + if(tmp64 == mac_addr) { + DBG_PRINT(INFO_DBG, + "MAC addr:0x%llx already present in CAM\n", + (unsigned long long)mac_addr); + return SUCCESS; + } + } + + if(i == config->max_mac_addr) { + DBG_PRINT(ERR_DBG,"CAM full no space left for Unicast MAC\n"); + return FAILURE; + } + /* Update the internal structure with this new mac address */ - MAC_ADDR_SET(0, mac_addr); - return (add_mac_addr(sp,mac_addr,0)); + MAC_ADDR_SET(i, mac_addr); + return (add_mac_addr(sp,mac_addr,i)); } /** @@ -7991,7 +8140,7 @@ s2io_init_nic(struct pci_dev *pdev, cons */ bar0 = sp->bar0; val64 = RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | - RMAC_ADDR_CMD_MEM_OFFSET(0 + MAC_MAC_ADDR_START_OFFSET); + RMAC_ADDR_CMD_MEM_OFFSET(0 + S2IO_MAC_ADDR_START_OFFSET); writeq(val64, &bar0->rmac_addr_cmd_mem); wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, S2IO_BIT_RESET); @@ -8009,8 +8158,24 @@ s2io_init_nic(struct pci_dev *pdev, cons /* Set the factory defined MAC address initially */ dev->addr_len = ETH_ALEN; memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN); + memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN); + /* initialize number of multicast & unicast MAC entries variables */ + if (sp->device_type == XFRAME_I_DEVICE) { + config->max_mc_addr = S2IO_XENA_MAX_MC_ADDRESSES; + config->max_mac_addr = S2IO_XENA_MAX_MAC_ADDRESSES; + config->mc_start_offset = S2IO_XENA_MC_ADDR_START_OFFSET; + } + else if (sp->device_type == XFRAME_II_DEVICE) { + config->max_mc_addr = S2IO_HERC_MAX_MC_ADDRESSES; + config->max_mac_addr = S2IO_HERC_MAX_MAC_ADDRESSES; + config->mc_start_offset = S2IO_HERC_MC_ADDR_START_OFFSET; + } + + /* store mac addresses from CAM to s2io_nic structure */ + store_mac_and_mc_addr(sp); + /* Store the values of the MSIX table in the s2io_nic structure */ store_xmsi_data(sp); /* reset Nic and bring it to known state */ diff -urpN patch1/drivers/net/s2io.h patch2/drivers/net/s2io.h --- patch1/drivers/net/s2io.h 2007-08-18 04:52:10.000000000 +0530 +++ patch2/drivers/net/s2io.h 2007-08-18 07:21:10.000000000 +0530 @@ -459,6 +459,9 @@ struct config_param { #define MAX_MTU_JUMBO (MAX_PYLD_JUMBO+18) #define MAX_MTU_JUMBO_VLAN (MAX_PYLD_JUMBO+22) u16 bus_speed; + int max_mc_addr; /* xena=64 herc=256 */ + int max_mac_addr; /* xena=16 herc=64 */ + int mc_start_offset; /* xena=16 herc=64 */ }; /* Structure representing MAC Addrs */ @@ -817,9 +820,8 @@ struct s2io_nic { void __iomem *bar0; void __iomem *bar1; #define MAX_MAC_SUPPORTED 16 -#define MAX_SUPPORTED_MULTICASTS MAX_MAC_SUPPORTED - struct mac_addr def_mac_addr[MAX_MAC_SUPPORTED]; + struct mac_addr def_mac_addr[256]; struct net_device_stats stats; int high_dma_flag; @@ -843,10 +845,9 @@ struct s2io_nic { #define PROMISC 1 #define ALL_MULTI 2 -#define MAX_ADDRS_SUPPORTED 64 u16 usr_addr_count; u16 mc_addr_count; - struct usr_addr usr_addrs[MAX_ADDRS_SUPPORTED]; + struct usr_addr usr_addrs[256]; u16 m_cast_flg; u16 all_multi_pos; @@ -1063,6 +1064,12 @@ static int s2io_add_isr(struct s2io_nic static void s2io_rem_isr(struct s2io_nic * sp); static void restore_xmsi_data(struct s2io_nic *nic); +static void store_mac_and_mc_addr(struct s2io_nic *sp); +static void restore_mac_and_mc_addr(struct s2io_nic *sp); +static u64 read_mac_addr(struct s2io_nic *sp, int offset); +static int add_mc_addr(struct s2io_nic *sp, u8 * addr); +static int add_mac_addr(struct s2io_nic *sp, u64 addr, int off); +static int delete_mac_addr(struct s2io_nic *sp,u64 addr); static int s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, struct lro **lro, diff -urpN patch1/drivers/net/s2io-regs.h patch2/drivers/net/s2io-regs.h --- patch1/drivers/net/s2io-regs.h 2007-08-18 04:34:49.000000000 +0530 +++ patch2/drivers/net/s2io-regs.h 2007-08-18 05:18:17.000000000 +0530 @@ -721,12 +721,17 @@ struct XENA_dev_config { u64 rmac_cfg_key; #define RMAC_CFG_KEY(val) vBIT(val,0,16) +#define S2IO_MAC_ADDR_START_OFFSET 0 + +#define S2IO_XENA_MAX_MC_ADDRESSES 64 /* multicast addresses */ +#define S2IO_HERC_MAX_MC_ADDRESSES 256 + +#define S2IO_XENA_MAX_MAC_ADDRESSES 16 +#define S2IO_HERC_MAX_MAC_ADDRESSES 64 + +#define S2IO_XENA_MC_ADDR_START_OFFSET 16 +#define S2IO_HERC_MC_ADDR_START_OFFSET 64 -#define MAX_MAC_ADDRESSES 16 -#define MAX_MC_ADDRESSES 32 /* Multicast addresses */ -#define MAC_MAC_ADDR_START_OFFSET 0 -#define MAC_MC_ADDR_START_OFFSET 16 -#define MAC_MC_ALL_MC_ADDR_OFFSET 63 /* enables all multicast pkts */ u64 rmac_addr_cmd_mem; #define RMAC_ADDR_CMD_MEM_WE BIT(7) #define RMAC_ADDR_CMD_MEM_RD 0 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html