mirror of
				https://github.com/Ysurac/openmptcprouter.git
				synced 2025-03-09 15:40:20 +00:00 
			
		
		
		
	Update OpenWRT for 6.1 kernel
This commit is contained in:
		
							parent
							
								
									71b3b8aac9
								
							
						
					
					
						commit
						46d5683e1d
					
				
					 8 changed files with 3 additions and 1230 deletions
				
			
		| 
						 | 
				
			
			@ -1,15 +0,0 @@
 | 
			
		|||
--- a/src/linux/ifxos_linux_thread_drv.c	2023-05-22 08:50:14.087507831 +0200
 | 
			
		||||
+++ b/src/linux/ifxos_linux_thread_drv.c	2023-05-22 08:51:32.702129369 +0200
 | 
			
		||||
@@ -154,8 +154,11 @@
 | 
			
		||||
    retVal = pThrCntrl->pThrFct(&pThrCntrl->thrParams);
 | 
			
		||||
    pThrCntrl->thrParams.bRunning = IFX_FALSE;
 | 
			
		||||
 
 | 
			
		||||
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,17,0))
 | 
			
		||||
    complete_and_exit(&pThrCntrl->thrCompletion, (long)retVal);
 | 
			
		||||
-
 | 
			
		||||
+#else
 | 
			
		||||
+   kthread_complete_and_exit(&pThrCntrl->thrCompletion, (long)retVal);
 | 
			
		||||
+#endif
 | 
			
		||||
    IFXOS_PRN_USR_DBG_NL( IFXOS, IFXOS_PRN_LEVEL_NORMAL,
 | 
			
		||||
       ("EXIT - Kernel Thread Startup <%s>" IFXOS_CRLF,
 | 
			
		||||
         pThrCntrl->thrParams.pName));
 | 
			
		||||
| 
						 | 
				
			
			@ -1,22 +0,0 @@
 | 
			
		|||
--- a/src/drv_mei_cpe_linux.c	2023-05-22 14:07:34.356721319 +0200
 | 
			
		||||
+++ b/src/drv_mei_cpe_linux.c	2023-05-22 14:08:02.328250656 +0200
 | 
			
		||||
@@ -2062,7 +2062,7 @@
 | 
			
		||||
 
 | 
			
		||||
 static int mei_proc_single_open(struct inode *inode, struct file *file)
 | 
			
		||||
 {
 | 
			
		||||
-   return single_open(file, mei_seq_single_show, PDE_DATA(inode));
 | 
			
		||||
+   return single_open(file, mei_seq_single_show, pde_data(inode));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void mei_proc_entry_create(struct proc_dir_entry *parent_node,
 | 
			
		||||
--- a/src/drv_mei_cpe_linux_proc_config.c	2023-05-22 14:12:26.251818708 +0200
 | 
			
		||||
+++ b/src/drv_mei_cpe_linux_proc_config.c	2023-05-22 14:12:51.219401891 +0200
 | 
			
		||||
@@ -1274,7 +1274,7 @@
 | 
			
		||||
 
 | 
			
		||||
 static int mei_proc_single_open(struct inode *inode, struct file *file)
 | 
			
		||||
 {
 | 
			
		||||
-	return single_open(file, mei_seq_single_show, PDE_DATA(inode));
 | 
			
		||||
+	return single_open(file, mei_seq_single_show, pde_data(inode));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static struct proc_ops proc_ops = {
 | 
			
		||||
| 
						 | 
				
			
			@ -1,18 +0,0 @@
 | 
			
		|||
--- a/ep.c	2023-05-22 10:23:11.790142567 +0200
 | 
			
		||||
+++ b/ep.c	2023-05-22 10:27:23.029791914 +0200
 | 
			
		||||
@@ -589,13 +589,13 @@
 | 
			
		||||
 	/* Target structures have a limit of 32 bit DMA pointers.
 | 
			
		||||
 	 * DMA pointers can be wider than 32 bits by default on some systems.
 | 
			
		||||
 	 */
 | 
			
		||||
-	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 | 
			
		||||
+	ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
 | 
			
		||||
 	if (ret) {
 | 
			
		||||
 		dev_err(&pdev->dev, "32-bit DMA not available: %d\n", ret);
 | 
			
		||||
 		goto err_region;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 | 
			
		||||
+	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
 | 
			
		||||
 	if (ret) {
 | 
			
		||||
 		dev_err(&pdev->dev, "cannot enable 32-bit consistent DMA\n");
 | 
			
		||||
 		goto err_region;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,336 +0,0 @@
 | 
			
		|||
--- a/dcdp/ptm_tc.c	2023-05-22 11:06:09.177510131 +0200
 | 
			
		||||
+++ b/dcdp/ptm_tc.c	2023-05-22 11:37:23.765131033 +0200
 | 
			
		||||
@@ -659,7 +659,11 @@
 | 
			
		||||
 	memcpy(ptm_tc->outq_map, def_outq_map, sizeof(def_outq_map));
 | 
			
		||||
 	SET_NETDEV_DEV(ptm_tc->dev, tc_priv->ep_dev[id].dev);
 | 
			
		||||
 
 | 
			
		||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,0,0)
 | 
			
		||||
+	netif_napi_add(ptm_tc->dev, &ptm_tc->napi_rx, tc_priv->tc_ops.napi_rx);
 | 
			
		||||
+#else
 | 
			
		||||
 	netif_napi_add(ptm_tc->dev, &ptm_tc->napi_rx, tc_priv->tc_ops.napi_rx, NAPI_POLL_WEIGHT);
 | 
			
		||||
+#endif
 | 
			
		||||
 	netif_tx_napi_add(ptm_tc->dev, &ptm_tc->napi_tx, tc_priv->tc_ops.napi_tx, NAPI_POLL_WEIGHT);
 | 
			
		||||
 
 | 
			
		||||
 	err = register_netdev(ptm_tc->dev);
 | 
			
		||||
@@ -3125,7 +3129,7 @@
 | 
			
		||||
 	if (!capable(CAP_SYS_ADMIN))
 | 
			
		||||
 		return -EPERM;
 | 
			
		||||
 
 | 
			
		||||
-	priv = (struct ptm_ep_priv *)PDE_DATA(file_inode(file));
 | 
			
		||||
+	priv = (struct ptm_ep_priv *)pde_data(file_inode(file));
 | 
			
		||||
 
 | 
			
		||||
 	len = count < sizeof(str) ? count : sizeof(str) - 1;
 | 
			
		||||
 	rlen = len - copy_from_user(str, buf, len);
 | 
			
		||||
@@ -3335,7 +3339,7 @@
 | 
			
		||||
 	local_buf[len] = 0;
 | 
			
		||||
 
 | 
			
		||||
 	num = vrx_split_buffer(local_buf, param_list, ARRAY_SIZE(param_list));
 | 
			
		||||
-	priv = (struct ptm_ep_priv *)PDE_DATA(file_inode(file));
 | 
			
		||||
+	priv = (struct ptm_ep_priv *)pde_data(file_inode(file));
 | 
			
		||||
 	if (priv == NULL) {
 | 
			
		||||
 		pr_err("%s: Invalid private data\n", __func__);
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
--- a/dcdp/inc/ptm_tc.h	2023-05-22 11:24:47.982177396 +0200
 | 
			
		||||
+++ b/dcdp/inc/ptm_tc.h	2023-05-22 11:25:34.313376656 +0200
 | 
			
		||||
@@ -76,6 +76,9 @@
 | 
			
		||||
 #define SFSM_DBACE			0x6000
 | 
			
		||||
 #define SFSM_CBACE			0x7100
 | 
			
		||||
 
 | 
			
		||||
+
 | 
			
		||||
+#define netif_tx_napi_add netif_napi_add_tx_weight
 | 
			
		||||
+
 | 
			
		||||
 enum {
 | 
			
		||||
 	US_DMA_PRE_RXCH = 0,
 | 
			
		||||
 	US_DMA_PRE_TXCH,
 | 
			
		||||
--- a/dcdp/tc_proc.c	2023-05-22 11:58:32.715356238 +0200
 | 
			
		||||
+++ b/dcdp/tc_proc.c	2023-05-22 11:59:13.454660657 +0200
 | 
			
		||||
@@ -343,7 +343,7 @@
 | 
			
		||||
 	if (!capable(CAP_SYS_ADMIN))
 | 
			
		||||
 		return -EPERM;
 | 
			
		||||
 
 | 
			
		||||
-	priv = ((struct tc_comm *)PDE_DATA(file_inode(file)));
 | 
			
		||||
+	priv = ((struct tc_comm *)pde_data(file_inode(file)));
 | 
			
		||||
 	if (priv == NULL) {
 | 
			
		||||
 		pr_err("%s: Invalid priv data\n", __func__);
 | 
			
		||||
 		return -EFAULT;
 | 
			
		||||
@@ -476,7 +476,7 @@
 | 
			
		||||
 	if (!capable(CAP_SYS_ADMIN))
 | 
			
		||||
 		return -EPERM;
 | 
			
		||||
 
 | 
			
		||||
-	priv = ((struct tc_comm *)PDE_DATA(file_inode(file)));
 | 
			
		||||
+	priv = ((struct tc_comm *)pde_data(file_inode(file)));
 | 
			
		||||
 	if (priv == NULL) {
 | 
			
		||||
 		pr_err("%s: priv pointer is NULL!!!\n", __func__);
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
@@ -746,7 +746,7 @@
 | 
			
		||||
 
 | 
			
		||||
 static int proc_read_pp32_seq_open(struct inode *inode, struct file *file)
 | 
			
		||||
 {
 | 
			
		||||
-	return single_open(file, proc_read_pp32, PDE_DATA(inode));
 | 
			
		||||
+	return single_open(file, proc_read_pp32, pde_data(inode));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static const struct proc_ops pp32_proc_fops = {
 | 
			
		||||
@@ -822,7 +822,7 @@
 | 
			
		||||
 	len = count < sizeof(str) ? count : sizeof(str) - 1;
 | 
			
		||||
 	rlen = len - copy_from_user(str, buf, len);
 | 
			
		||||
 	str[rlen] = 0;
 | 
			
		||||
-	priv = (struct tc_priv *)PDE_DATA(file_inode(file));
 | 
			
		||||
+	priv = (struct tc_priv *)pde_data(file_inode(file));
 | 
			
		||||
 	if (priv == NULL)
 | 
			
		||||
 		return count;
 | 
			
		||||
 
 | 
			
		||||
@@ -862,7 +862,7 @@
 | 
			
		||||
 
 | 
			
		||||
 static int proc_read_tc_cfg_seq_open(struct inode *inode, struct file *file)
 | 
			
		||||
 {
 | 
			
		||||
-	return single_open(file, proc_read_tc_cfg, PDE_DATA(inode));
 | 
			
		||||
+	return single_open(file, proc_read_tc_cfg, pde_data(inode));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static const struct proc_ops tc_cfg_proc_fops = {
 | 
			
		||||
@@ -888,7 +888,7 @@
 | 
			
		||||
 	if (!capable(CAP_SYS_ADMIN))
 | 
			
		||||
 		return -EPERM;
 | 
			
		||||
 
 | 
			
		||||
-	priv = (struct tc_priv *)PDE_DATA(file_inode(file));
 | 
			
		||||
+	priv = (struct tc_priv *)pde_data(file_inode(file));
 | 
			
		||||
 	if (priv == NULL)
 | 
			
		||||
 		return count;
 | 
			
		||||
 
 | 
			
		||||
@@ -947,7 +947,7 @@
 | 
			
		||||
 
 | 
			
		||||
 static int proc_read_dbg_seq_open(struct inode *inode, struct file *file)
 | 
			
		||||
 {
 | 
			
		||||
-	return single_open(file, proc_read_dbg, PDE_DATA(inode));
 | 
			
		||||
+	return single_open(file, proc_read_dbg, pde_data(inode));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static const struct proc_ops tc_dbg_proc_fops = {
 | 
			
		||||
@@ -970,7 +970,7 @@
 | 
			
		||||
 	if (!capable(CAP_SYS_ADMIN))
 | 
			
		||||
 		return -EPERM;
 | 
			
		||||
 
 | 
			
		||||
-	priv = (struct tc_priv *)PDE_DATA(file_inode(file));
 | 
			
		||||
+	priv = (struct tc_priv *)pde_data(file_inode(file));
 | 
			
		||||
 
 | 
			
		||||
 	len = count < sizeof(str) ? count : sizeof(str) - 1;
 | 
			
		||||
 	rlen = len - copy_from_user(str, buf, len);
 | 
			
		||||
@@ -1033,7 +1033,7 @@
 | 
			
		||||
 	if (!capable(CAP_SYS_ADMIN))
 | 
			
		||||
 		return -EPERM;
 | 
			
		||||
 
 | 
			
		||||
-	priv = (struct tc_priv *)PDE_DATA(file_inode(file));
 | 
			
		||||
+	priv = (struct tc_priv *)pde_data(file_inode(file));
 | 
			
		||||
 
 | 
			
		||||
 	len = count < sizeof(str) ? count : sizeof(str) - 1;
 | 
			
		||||
 	rlen = len - copy_from_user(str, buf, len);
 | 
			
		||||
@@ -1125,7 +1125,7 @@
 | 
			
		||||
 
 | 
			
		||||
 static int proc_read_ver_seq_open(struct inode *inode, struct file *file)
 | 
			
		||||
 {
 | 
			
		||||
-	return single_open(file, proc_read_ver, PDE_DATA(inode));
 | 
			
		||||
+	return single_open(file, proc_read_ver, pde_data(inode));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static const struct proc_ops tc_ver_proc_fops = {
 | 
			
		||||
@@ -1159,7 +1159,7 @@
 | 
			
		||||
 
 | 
			
		||||
 static int proc_read_soc_seq_open(struct inode *inode, struct file *file)
 | 
			
		||||
 {
 | 
			
		||||
-	return single_open(file, proc_read_soc, PDE_DATA(inode));
 | 
			
		||||
+	return single_open(file, proc_read_soc, pde_data(inode));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static const struct proc_ops tc_soc_proc_fops = {
 | 
			
		||||
@@ -1185,7 +1185,7 @@
 | 
			
		||||
 	if (!capable(CAP_SYS_ADMIN))
 | 
			
		||||
 		return -EPERM;
 | 
			
		||||
 
 | 
			
		||||
-	priv = (struct tc_priv *)PDE_DATA(file_inode(file));
 | 
			
		||||
+	priv = (struct tc_priv *)pde_data(file_inode(file));
 | 
			
		||||
 	if (priv == NULL)
 | 
			
		||||
 		return count;
 | 
			
		||||
 
 | 
			
		||||
@@ -1264,7 +1264,7 @@
 | 
			
		||||
 
 | 
			
		||||
 static int proc_read_desc_conf_seq_open(struct inode *inode, struct file *file)
 | 
			
		||||
 {
 | 
			
		||||
-	return single_open(file, proc_read_desc_conf, PDE_DATA(inode));
 | 
			
		||||
+	return single_open(file, proc_read_desc_conf, pde_data(inode));
 | 
			
		||||
 }
 | 
			
		||||
 #endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1343,7 +1343,7 @@
 | 
			
		||||
 
 | 
			
		||||
 static int proc_read_ptm_wanmib_seq_open(struct inode *inode, struct file *file)
 | 
			
		||||
 {
 | 
			
		||||
-	return single_open(file, proc_read_ptm_wanmib, PDE_DATA(inode));
 | 
			
		||||
+	return single_open(file, proc_read_ptm_wanmib, pde_data(inode));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static const struct proc_ops ptm_wanmib_proc_fops = {
 | 
			
		||||
@@ -1382,7 +1382,7 @@
 | 
			
		||||
 
 | 
			
		||||
 static int proc_read_cfg_seq_open(struct inode *inode, struct file *file)
 | 
			
		||||
 {
 | 
			
		||||
-	return single_open(file, proc_ptm_read_cfg, PDE_DATA(inode));
 | 
			
		||||
+	return single_open(file, proc_ptm_read_cfg, pde_data(inode));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static ssize_t ptm_cfg_proc_write(struct file *file,
 | 
			
		||||
@@ -1398,7 +1398,7 @@
 | 
			
		||||
 	if (!capable(CAP_SYS_ADMIN))
 | 
			
		||||
 		return -EPERM;
 | 
			
		||||
 
 | 
			
		||||
-	priv = (struct ptm_ep_priv *)PDE_DATA(file_inode(file));
 | 
			
		||||
+	priv = (struct ptm_ep_priv *)pde_data(file_inode(file));
 | 
			
		||||
 	if (priv == NULL) {
 | 
			
		||||
 		pr_err("%s: Invalid private data\n", __func__);
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
@@ -1478,7 +1478,7 @@
 | 
			
		||||
 	p1 = local_buf;
 | 
			
		||||
 
 | 
			
		||||
 	num = vrx_split_buffer(local_buf, param_list, ARRAY_SIZE(param_list));
 | 
			
		||||
-	priv = (struct ptm_ep_priv *)PDE_DATA(file_inode(file));
 | 
			
		||||
+	priv = (struct ptm_ep_priv *)pde_data(file_inode(file));
 | 
			
		||||
 
 | 
			
		||||
 	if (priv == NULL) {
 | 
			
		||||
 		pr_err("%s: Invalid private data\n", __func__);
 | 
			
		||||
@@ -1554,7 +1554,7 @@
 | 
			
		||||
 
 | 
			
		||||
 static int proc_ptm_read_prio_seq_open(struct inode *inode, struct file *file)
 | 
			
		||||
 {
 | 
			
		||||
-	return single_open(file, proc_ptm_read_prio, PDE_DATA(inode));
 | 
			
		||||
+	return single_open(file, proc_ptm_read_prio, pde_data(inode));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static const struct proc_ops ptm_prio_proc_fops = {
 | 
			
		||||
@@ -1567,7 +1567,7 @@
 | 
			
		||||
 
 | 
			
		||||
 static int proc_ptm_read_bond_seq_open(struct inode *inode, struct file *file)
 | 
			
		||||
 {
 | 
			
		||||
-	return single_open(file, proc_ptm_read_bond, PDE_DATA(inode));
 | 
			
		||||
+	return single_open(file, proc_ptm_read_bond, pde_data(inode));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static const struct proc_ops ptm_bond_proc_fops = {
 | 
			
		||||
@@ -1580,7 +1580,7 @@
 | 
			
		||||
 static int proc_ptm_read_bondmib_seq_open(struct inode *inode,
 | 
			
		||||
 							struct file *file)
 | 
			
		||||
 {
 | 
			
		||||
-	return single_open(file, proc_ptm_read_bondmib, PDE_DATA(inode));
 | 
			
		||||
+	return single_open(file, proc_ptm_read_bondmib, pde_data(inode));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static const struct proc_ops ptm_bondmib_proc_fops = {
 | 
			
		||||
@@ -1983,7 +1983,7 @@
 | 
			
		||||
 
 | 
			
		||||
 	num = vrx_split_buffer(local_buf, param_list,
 | 
			
		||||
 		ARRAY_SIZE(param_list));
 | 
			
		||||
-	priv =  (struct tc_comm *)PDE_DATA(file_inode(file));
 | 
			
		||||
+	priv =  (struct tc_comm *)pde_data(file_inode(file));
 | 
			
		||||
 	if (priv == NULL) {
 | 
			
		||||
 		pr_err("<%s>: Invalid private data\n", __func__);
 | 
			
		||||
 		return count;
 | 
			
		||||
@@ -2158,7 +2158,7 @@
 | 
			
		||||
 
 | 
			
		||||
 static int proc_read_atm_cfg_seq_open(struct inode *inode, struct file *file)
 | 
			
		||||
 {
 | 
			
		||||
-	return single_open(file, proc_read_atm_cfg, PDE_DATA(inode));
 | 
			
		||||
+	return single_open(file, proc_read_atm_cfg, pde_data(inode));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static ssize_t atm_cfg_proc_write(struct file *file,
 | 
			
		||||
@@ -2174,7 +2174,7 @@
 | 
			
		||||
 	if (!capable(CAP_SYS_ADMIN))
 | 
			
		||||
 		return -EPERM;
 | 
			
		||||
 
 | 
			
		||||
-	priv = (struct atm_priv *)PDE_DATA(file_inode(file));
 | 
			
		||||
+	priv = (struct atm_priv *)pde_data(file_inode(file));
 | 
			
		||||
 
 | 
			
		||||
 	if (!access_ok(buf, count))
 | 
			
		||||
 		return -EFAULT;
 | 
			
		||||
@@ -2238,7 +2238,7 @@
 | 
			
		||||
 	if (!capable(CAP_SYS_ADMIN))
 | 
			
		||||
 		return -EPERM;
 | 
			
		||||
 
 | 
			
		||||
-	priv = (struct atm_priv *)PDE_DATA(file_inode(file));
 | 
			
		||||
+	priv = (struct atm_priv *)pde_data(file_inode(file));
 | 
			
		||||
 	if (priv == NULL) {
 | 
			
		||||
 		pr_err("%s: Invalid private data\n", __func__);
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
@@ -2266,7 +2266,7 @@
 | 
			
		||||
 static int proc_read_atm_wanmib_seq_open(struct inode *inode,
 | 
			
		||||
 	struct file *file)
 | 
			
		||||
 {
 | 
			
		||||
-	return single_open(file, proc_read_atm_wanmib, PDE_DATA(inode));
 | 
			
		||||
+	return single_open(file, proc_read_atm_wanmib, pde_data(inode));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
@@ -2281,7 +2281,7 @@
 | 
			
		||||
 
 | 
			
		||||
 static int proc_read_htu_seq_open(struct inode *inode, struct file *file)
 | 
			
		||||
 {
 | 
			
		||||
-	return single_open(file, proc_read_htu, PDE_DATA(inode));
 | 
			
		||||
+	return single_open(file, proc_read_htu, pde_data(inode));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static const struct proc_ops htu_proc_fops = {
 | 
			
		||||
@@ -2293,7 +2293,7 @@
 | 
			
		||||
 
 | 
			
		||||
 static int proc_read_queue_seq_open(struct inode *inode, struct file *file)
 | 
			
		||||
 {
 | 
			
		||||
-	return single_open(file, proc_read_queue, PDE_DATA(inode));
 | 
			
		||||
+	return single_open(file, proc_read_queue, pde_data(inode));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static const struct proc_ops queue_proc_fops = {
 | 
			
		||||
@@ -2350,7 +2350,7 @@
 | 
			
		||||
 	p1 = local_buf;
 | 
			
		||||
 
 | 
			
		||||
 	num = vrx_split_buffer(local_buf, param_list, ARRAY_SIZE(param_list));
 | 
			
		||||
-	priv =  (struct atm_priv *)PDE_DATA(file_inode(file));
 | 
			
		||||
+	priv =  (struct atm_priv *)pde_data(file_inode(file));
 | 
			
		||||
 	if (vrx_strcmpi(param_list[0], "help") == 0)
 | 
			
		||||
 		goto proc_atm_prio_help;
 | 
			
		||||
 	else if (vrx_strcmpi(param_list[0], "pvc") == 0) {
 | 
			
		||||
@@ -2513,7 +2513,7 @@
 | 
			
		||||
 
 | 
			
		||||
 static int proc_atm_read_prio_seq_open(struct inode *inode, struct file *file)
 | 
			
		||||
 {
 | 
			
		||||
-	return single_open(file, proc_atm_read_prio, PDE_DATA(inode));
 | 
			
		||||
+	return single_open(file, proc_atm_read_prio, pde_data(inode));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static const struct seq_operations pvc_mib_seq_ops = {
 | 
			
		||||
@@ -2536,7 +2536,7 @@
 | 
			
		||||
 	int ret = seq_open(file, &pvc_mib_seq_ops);
 | 
			
		||||
 	if (ret == 0) {
 | 
			
		||||
 		struct seq_file *m = file->private_data;
 | 
			
		||||
-		m->private = PDE_DATA(inode);
 | 
			
		||||
+		m->private = pde_data(inode);
 | 
			
		||||
 	}
 | 
			
		||||
 	return ret;
 | 
			
		||||
 }
 | 
			
		||||
@@ -2574,7 +2574,7 @@
 | 
			
		||||
 	local_buf[len] = 0;
 | 
			
		||||
 
 | 
			
		||||
 	num = vrx_split_buffer(local_buf, param_list, ARRAY_SIZE(param_list));
 | 
			
		||||
-	priv =  (struct atm_priv *)PDE_DATA(file_inode(file));
 | 
			
		||||
+	priv =  (struct atm_priv *)pde_data(file_inode(file));
 | 
			
		||||
 	if (priv == NULL) {
 | 
			
		||||
 		pr_err("<%s>: Invalid private data\n", __func__);
 | 
			
		||||
 		return count;
 | 
			
		||||
--- a/dcdp/ptm_tc.c	2023-06-29 11:30:37.060472655 +0200
 | 
			
		||||
+++ b/dcdp/ptm_tc.c	2023-06-29 11:31:01.376064210 +0200
 | 
			
		||||
@@ -88,7 +88,7 @@
 | 
			
		||||
 	unsigned int *data_addr, unsigned int *desc_addr);
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
-static inline void tc_ether_addr_copy(u8 *dst, const u8 *src)
 | 
			
		||||
+static inline void tc_ether_addr_copy(const u8 *dst, const u8 *src)
 | 
			
		||||
 {
 | 
			
		||||
 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
 | 
			
		||||
 	*(u32 *)dst = *(const u32 *)src;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,12 +0,0 @@
 | 
			
		|||
--- a/drivers/net/wireless/ath/carl9170/tx.c	2023-06-27 09:18:10.616850964 +0200
 | 
			
		||||
+++ b/drivers/net/wireless/ath/carl9170/tx.c	2023-06-27 09:18:39.260374789 +0200
 | 
			
		||||
@@ -280,7 +280,8 @@
 | 
			
		||||
 	 * carl9170_tx_fill_rateinfo() has filled the rate information
 | 
			
		||||
 	 * before we get to this point.
 | 
			
		||||
 	 */
 | 
			
		||||
-	memset_after(&txinfo->status, 0, rates);
 | 
			
		||||
+	memset(&txinfo->pad, 0, sizeof(txinfo->pad));
 | 
			
		||||
+	memset(&txinfo->rate_driver_data, 0, sizeof(txinfo->rate_driver_data));
 | 
			
		||||
 
 | 
			
		||||
 	if (atomic_read(&ar->tx_total_queued))
 | 
			
		||||
 		ar->tx_schedule = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,762 +0,0 @@
 | 
			
		|||
From 986e43b19ae9176093da35e0a844e65c8bf9ede7 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Felix Fietkau <nbd@nbd.name>
 | 
			
		||||
Date: Mon, 13 Feb 2023 11:08:54 +0100
 | 
			
		||||
Subject: [PATCH] wifi: mac80211: fix receiving A-MSDU frames on mesh
 | 
			
		||||
 interfaces
 | 
			
		||||
 | 
			
		||||
The current mac80211 mesh A-MSDU receive path fails to parse A-MSDU packets
 | 
			
		||||
on mesh interfaces, because it assumes that the Mesh Control field is always
 | 
			
		||||
directly after the 802.11 header.
 | 
			
		||||
802.11-2020 9.3.2.2.2 Figure 9-70 shows that the Mesh Control field is
 | 
			
		||||
actually part of the A-MSDU subframe header.
 | 
			
		||||
This makes more sense, since it allows packets for multiple different
 | 
			
		||||
destinations to be included in the same A-MSDU, as long as RA and TID are
 | 
			
		||||
still the same.
 | 
			
		||||
Another issue is the fact that the A-MSDU subframe length field was apparently
 | 
			
		||||
accidentally defined as little-endian in the standard.
 | 
			
		||||
 | 
			
		||||
In order to fix this, the mesh forwarding path needs happen at a different
 | 
			
		||||
point in the receive path.
 | 
			
		||||
 | 
			
		||||
ieee80211_data_to_8023_exthdr is changed to ignore the mesh control field
 | 
			
		||||
and leave it in after the ethernet header. This also affects the source/dest
 | 
			
		||||
MAC address fields, which now in the case of mesh point to the mesh SA/DA.
 | 
			
		||||
 | 
			
		||||
ieee80211_amsdu_to_8023s is changed to deal with the endian difference and
 | 
			
		||||
to add the Mesh Control length to the subframe length, since it's not covered
 | 
			
		||||
by the MSDU length field.
 | 
			
		||||
 | 
			
		||||
With these changes, the mac80211 will get the same packet structure for
 | 
			
		||||
converted regular data packets and unpacked A-MSDU subframes.
 | 
			
		||||
 | 
			
		||||
The mesh forwarding checks are now only performed after the A-MSDU decap.
 | 
			
		||||
For locally received packets, the Mesh Control header is stripped away.
 | 
			
		||||
For forwarded packets, a new 802.11 header gets added.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
			
		||||
Link: https://lore.kernel.org/r/20230213100855.34315-4-nbd@nbd.name
 | 
			
		||||
[fix fortify build error]
 | 
			
		||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
 | 
			
		||||
---
 | 
			
		||||
 .../wireless/marvell/mwifiex/11n_rxreorder.c  |   2 +-
 | 
			
		||||
 include/net/cfg80211.h                        |  27 +-
 | 
			
		||||
 net/mac80211/rx.c                             | 350 ++++++++++--------
 | 
			
		||||
 net/wireless/util.c                           | 120 +++---
 | 
			
		||||
 4 files changed, 297 insertions(+), 202 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
 | 
			
		||||
+++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
 | 
			
		||||
@@ -33,7 +33,7 @@ static int mwifiex_11n_dispatch_amsdu_pk
 | 
			
		||||
 		skb_trim(skb, le16_to_cpu(local_rx_pd->rx_pkt_length));
 | 
			
		||||
 
 | 
			
		||||
 		ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr,
 | 
			
		||||
-					 priv->wdev.iftype, 0, NULL, NULL);
 | 
			
		||||
+					 priv->wdev.iftype, 0, NULL, NULL, false);
 | 
			
		||||
 
 | 
			
		||||
 		while (!skb_queue_empty(&list)) {
 | 
			
		||||
 			struct rx_packet_hdr *rx_hdr;
 | 
			
		||||
--- a/include/net/cfg80211.h
 | 
			
		||||
+++ b/include/net/cfg80211.h
 | 
			
		||||
@@ -6208,11 +6208,36 @@ static inline int ieee80211_data_to_8023
 | 
			
		||||
  * @extra_headroom: The hardware extra headroom for SKBs in the @list.
 | 
			
		||||
  * @check_da: DA to check in the inner ethernet header, or NULL
 | 
			
		||||
  * @check_sa: SA to check in the inner ethernet header, or NULL
 | 
			
		||||
+ * @mesh_control: A-MSDU subframe header includes the mesh control field
 | 
			
		||||
  */
 | 
			
		||||
 void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
 | 
			
		||||
 			      const u8 *addr, enum nl80211_iftype iftype,
 | 
			
		||||
 			      const unsigned int extra_headroom,
 | 
			
		||||
-			      const u8 *check_da, const u8 *check_sa);
 | 
			
		||||
+			      const u8 *check_da, const u8 *check_sa,
 | 
			
		||||
+			      bool mesh_control);
 | 
			
		||||
+
 | 
			
		||||
+/**
 | 
			
		||||
+ * ieee80211_get_8023_tunnel_proto - get RFC1042 or bridge tunnel encap protocol
 | 
			
		||||
+ *
 | 
			
		||||
+ * Check for RFC1042 or bridge tunnel header and fetch the encapsulated
 | 
			
		||||
+ * protocol.
 | 
			
		||||
+ *
 | 
			
		||||
+ * @hdr: pointer to the MSDU payload
 | 
			
		||||
+ * @proto: destination pointer to store the protocol
 | 
			
		||||
+ * Return: true if encapsulation was found
 | 
			
		||||
+ */
 | 
			
		||||
+bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto);
 | 
			
		||||
+
 | 
			
		||||
+/**
 | 
			
		||||
+ * ieee80211_strip_8023_mesh_hdr - strip mesh header from converted 802.3 frames
 | 
			
		||||
+ *
 | 
			
		||||
+ * Strip the mesh header, which was left in by ieee80211_data_to_8023 as part
 | 
			
		||||
+ * of the MSDU data. Also move any source/destination addresses from the mesh
 | 
			
		||||
+ * header to the ethernet header (if present).
 | 
			
		||||
+ *
 | 
			
		||||
+ * @skb: The 802.3 frame with embedded mesh header
 | 
			
		||||
+ */
 | 
			
		||||
+int ieee80211_strip_8023_mesh_hdr(struct sk_buff *skb);
 | 
			
		||||
 
 | 
			
		||||
 /**
 | 
			
		||||
  * cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame
 | 
			
		||||
--- a/net/mac80211/rx.c
 | 
			
		||||
+++ b/net/mac80211/rx.c
 | 
			
		||||
@@ -2720,6 +2720,174 @@ ieee80211_deliver_skb(struct ieee80211_r
 | 
			
		||||
 	}
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static ieee80211_rx_result
 | 
			
		||||
+ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta,
 | 
			
		||||
+		       struct sk_buff *skb)
 | 
			
		||||
+{
 | 
			
		||||
+#ifdef CPTCFG_MAC80211_MESH
 | 
			
		||||
+	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
 | 
			
		||||
+	struct ieee80211_local *local = sdata->local;
 | 
			
		||||
+	uint16_t fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA;
 | 
			
		||||
+	struct ieee80211_hdr hdr = {
 | 
			
		||||
+		.frame_control = cpu_to_le16(fc)
 | 
			
		||||
+	};
 | 
			
		||||
+	struct ieee80211_hdr *fwd_hdr;
 | 
			
		||||
+	struct ieee80211s_hdr *mesh_hdr;
 | 
			
		||||
+	struct ieee80211_tx_info *info;
 | 
			
		||||
+	struct sk_buff *fwd_skb;
 | 
			
		||||
+	struct ethhdr *eth;
 | 
			
		||||
+	bool multicast;
 | 
			
		||||
+	int tailroom = 0;
 | 
			
		||||
+	int hdrlen, mesh_hdrlen;
 | 
			
		||||
+	u8 *qos;
 | 
			
		||||
+
 | 
			
		||||
+	if (!ieee80211_vif_is_mesh(&sdata->vif))
 | 
			
		||||
+		return RX_CONTINUE;
 | 
			
		||||
+
 | 
			
		||||
+	if (!pskb_may_pull(skb, sizeof(*eth) + 6))
 | 
			
		||||
+		return RX_DROP_MONITOR;
 | 
			
		||||
+
 | 
			
		||||
+	mesh_hdr = (struct ieee80211s_hdr *)(skb->data + sizeof(*eth));
 | 
			
		||||
+	mesh_hdrlen = ieee80211_get_mesh_hdrlen(mesh_hdr);
 | 
			
		||||
+
 | 
			
		||||
+	if (!pskb_may_pull(skb, sizeof(*eth) + mesh_hdrlen))
 | 
			
		||||
+		return RX_DROP_MONITOR;
 | 
			
		||||
+
 | 
			
		||||
+	eth = (struct ethhdr *)skb->data;
 | 
			
		||||
+	multicast = is_multicast_ether_addr(eth->h_dest);
 | 
			
		||||
+
 | 
			
		||||
+	mesh_hdr = (struct ieee80211s_hdr *)(eth + 1);
 | 
			
		||||
+	if (!mesh_hdr->ttl)
 | 
			
		||||
+		return RX_DROP_MONITOR;
 | 
			
		||||
+
 | 
			
		||||
+	/* frame is in RMC, don't forward */
 | 
			
		||||
+	if (is_multicast_ether_addr(eth->h_dest) &&
 | 
			
		||||
+	    mesh_rmc_check(sdata, eth->h_source, mesh_hdr))
 | 
			
		||||
+		return RX_DROP_MONITOR;
 | 
			
		||||
+
 | 
			
		||||
+	/* Frame has reached destination.  Don't forward */
 | 
			
		||||
+	if (ether_addr_equal(sdata->vif.addr, eth->h_dest))
 | 
			
		||||
+		goto rx_accept;
 | 
			
		||||
+
 | 
			
		||||
+	if (!ifmsh->mshcfg.dot11MeshForwarding) {
 | 
			
		||||
+		if (is_multicast_ether_addr(eth->h_dest))
 | 
			
		||||
+			goto rx_accept;
 | 
			
		||||
+
 | 
			
		||||
+		return RX_DROP_MONITOR;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	/* forward packet */
 | 
			
		||||
+	if (sdata->crypto_tx_tailroom_needed_cnt)
 | 
			
		||||
+		tailroom = IEEE80211_ENCRYPT_TAILROOM;
 | 
			
		||||
+
 | 
			
		||||
+	if (!--mesh_hdr->ttl) {
 | 
			
		||||
+		if (multicast)
 | 
			
		||||
+			goto rx_accept;
 | 
			
		||||
+
 | 
			
		||||
+		IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);
 | 
			
		||||
+		return RX_DROP_MONITOR;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	if (mesh_hdr->flags & MESH_FLAGS_AE) {
 | 
			
		||||
+		struct mesh_path *mppath;
 | 
			
		||||
+		char *proxied_addr;
 | 
			
		||||
+
 | 
			
		||||
+		if (multicast)
 | 
			
		||||
+			proxied_addr = mesh_hdr->eaddr1;
 | 
			
		||||
+		else if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6)
 | 
			
		||||
+			/* has_a4 already checked in ieee80211_rx_mesh_check */
 | 
			
		||||
+			proxied_addr = mesh_hdr->eaddr2;
 | 
			
		||||
+		else
 | 
			
		||||
+			return RX_DROP_MONITOR;
 | 
			
		||||
+
 | 
			
		||||
+		rcu_read_lock();
 | 
			
		||||
+		mppath = mpp_path_lookup(sdata, proxied_addr);
 | 
			
		||||
+		if (!mppath) {
 | 
			
		||||
+			mpp_path_add(sdata, proxied_addr, eth->h_source);
 | 
			
		||||
+		} else {
 | 
			
		||||
+			spin_lock_bh(&mppath->state_lock);
 | 
			
		||||
+			if (!ether_addr_equal(mppath->mpp, eth->h_source))
 | 
			
		||||
+				memcpy(mppath->mpp, eth->h_source, ETH_ALEN);
 | 
			
		||||
+			mppath->exp_time = jiffies;
 | 
			
		||||
+			spin_unlock_bh(&mppath->state_lock);
 | 
			
		||||
+		}
 | 
			
		||||
+		rcu_read_unlock();
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	skb_set_queue_mapping(skb, ieee802_1d_to_ac[skb->priority]);
 | 
			
		||||
+
 | 
			
		||||
+	ieee80211_fill_mesh_addresses(&hdr, &hdr.frame_control,
 | 
			
		||||
+				      eth->h_dest, eth->h_source);
 | 
			
		||||
+	hdrlen = ieee80211_hdrlen(hdr.frame_control);
 | 
			
		||||
+	if (multicast) {
 | 
			
		||||
+		int extra_head = sizeof(struct ieee80211_hdr) - sizeof(*eth);
 | 
			
		||||
+
 | 
			
		||||
+		fwd_skb = skb_copy_expand(skb, local->tx_headroom + extra_head +
 | 
			
		||||
+					       IEEE80211_ENCRYPT_HEADROOM,
 | 
			
		||||
+					  tailroom, GFP_ATOMIC);
 | 
			
		||||
+		if (!fwd_skb)
 | 
			
		||||
+			goto rx_accept;
 | 
			
		||||
+	} else {
 | 
			
		||||
+		fwd_skb = skb;
 | 
			
		||||
+		skb = NULL;
 | 
			
		||||
+
 | 
			
		||||
+		if (skb_cow_head(fwd_skb, hdrlen - sizeof(struct ethhdr)))
 | 
			
		||||
+			return RX_DROP_UNUSABLE;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	fwd_hdr = skb_push(fwd_skb, hdrlen - sizeof(struct ethhdr));
 | 
			
		||||
+	memcpy(fwd_hdr, &hdr, hdrlen - 2);
 | 
			
		||||
+	qos = ieee80211_get_qos_ctl(fwd_hdr);
 | 
			
		||||
+	qos[0] = qos[1] = 0;
 | 
			
		||||
+
 | 
			
		||||
+	skb_reset_mac_header(fwd_skb);
 | 
			
		||||
+	hdrlen += mesh_hdrlen;
 | 
			
		||||
+	if (ieee80211_get_8023_tunnel_proto(fwd_skb->data + hdrlen,
 | 
			
		||||
+					    &fwd_skb->protocol))
 | 
			
		||||
+		hdrlen += ETH_ALEN;
 | 
			
		||||
+	else
 | 
			
		||||
+		fwd_skb->protocol = htons(fwd_skb->len - hdrlen);
 | 
			
		||||
+	skb_set_network_header(fwd_skb, hdrlen);
 | 
			
		||||
+
 | 
			
		||||
+	info = IEEE80211_SKB_CB(fwd_skb);
 | 
			
		||||
+	memset(info, 0, sizeof(*info));
 | 
			
		||||
+	info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
 | 
			
		||||
+	info->control.vif = &sdata->vif;
 | 
			
		||||
+	info->control.jiffies = jiffies;
 | 
			
		||||
+	if (multicast) {
 | 
			
		||||
+		IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast);
 | 
			
		||||
+		memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
 | 
			
		||||
+		/* update power mode indication when forwarding */
 | 
			
		||||
+		ieee80211_mps_set_frame_flags(sdata, NULL, fwd_hdr);
 | 
			
		||||
+	} else if (!mesh_nexthop_lookup(sdata, fwd_skb)) {
 | 
			
		||||
+		/* mesh power mode flags updated in mesh_nexthop_lookup */
 | 
			
		||||
+		IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast);
 | 
			
		||||
+	} else {
 | 
			
		||||
+		/* unable to resolve next hop */
 | 
			
		||||
+		if (sta)
 | 
			
		||||
+			mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl,
 | 
			
		||||
+					   hdr.addr3, 0,
 | 
			
		||||
+					   WLAN_REASON_MESH_PATH_NOFORWARD,
 | 
			
		||||
+					   sta->sta.addr);
 | 
			
		||||
+		IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route);
 | 
			
		||||
+		kfree_skb(fwd_skb);
 | 
			
		||||
+		goto rx_accept;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames);
 | 
			
		||||
+	fwd_skb->dev = sdata->dev;
 | 
			
		||||
+	ieee80211_add_pending_skb(local, fwd_skb);
 | 
			
		||||
+
 | 
			
		||||
+rx_accept:
 | 
			
		||||
+	if (!skb)
 | 
			
		||||
+		return RX_QUEUED;
 | 
			
		||||
+
 | 
			
		||||
+	ieee80211_strip_8023_mesh_hdr(skb);
 | 
			
		||||
+#endif
 | 
			
		||||
+
 | 
			
		||||
+	return RX_CONTINUE;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static ieee80211_rx_result debug_noinline
 | 
			
		||||
 __ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset)
 | 
			
		||||
 {
 | 
			
		||||
@@ -2728,8 +2896,10 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
 | 
			
		||||
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 | 
			
		||||
 	__le16 fc = hdr->frame_control;
 | 
			
		||||
 	struct sk_buff_head frame_list;
 | 
			
		||||
+	static ieee80211_rx_result res;
 | 
			
		||||
 	struct ethhdr ethhdr;
 | 
			
		||||
 	const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source;
 | 
			
		||||
+	bool mesh = false;
 | 
			
		||||
 
 | 
			
		||||
 	if (unlikely(ieee80211_has_a4(hdr->frame_control))) {
 | 
			
		||||
 		check_da = NULL;
 | 
			
		||||
@@ -2746,6 +2916,8 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
 | 
			
		||||
 			break;
 | 
			
		||||
 		case NL80211_IFTYPE_MESH_POINT:
 | 
			
		||||
 			check_sa = NULL;
 | 
			
		||||
+			check_da = NULL;
 | 
			
		||||
+			mesh = true;
 | 
			
		||||
 			break;
 | 
			
		||||
 		default:
 | 
			
		||||
 			break;
 | 
			
		||||
@@ -2763,17 +2935,29 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
 | 
			
		||||
 	ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
 | 
			
		||||
 				 rx->sdata->vif.type,
 | 
			
		||||
 				 rx->local->hw.extra_tx_headroom,
 | 
			
		||||
-				 check_da, check_sa);
 | 
			
		||||
+				 check_da, check_sa, mesh);
 | 
			
		||||
 
 | 
			
		||||
 	while (!skb_queue_empty(&frame_list)) {
 | 
			
		||||
 		rx->skb = __skb_dequeue(&frame_list);
 | 
			
		||||
 
 | 
			
		||||
-		if (!ieee80211_frame_allowed(rx, fc)) {
 | 
			
		||||
-			dev_kfree_skb(rx->skb);
 | 
			
		||||
+		res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb);
 | 
			
		||||
+		switch (res) {
 | 
			
		||||
+		case RX_QUEUED:
 | 
			
		||||
 			continue;
 | 
			
		||||
+		case RX_CONTINUE:
 | 
			
		||||
+			break;
 | 
			
		||||
+		default:
 | 
			
		||||
+			goto free;
 | 
			
		||||
 		}
 | 
			
		||||
 
 | 
			
		||||
+		if (!ieee80211_frame_allowed(rx, fc))
 | 
			
		||||
+			goto free;
 | 
			
		||||
+
 | 
			
		||||
 		ieee80211_deliver_skb(rx);
 | 
			
		||||
+		continue;
 | 
			
		||||
+
 | 
			
		||||
+free:
 | 
			
		||||
+		dev_kfree_skb(rx->skb);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	return RX_QUEUED;
 | 
			
		||||
@@ -2806,6 +2990,8 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx
 | 
			
		||||
 			if (!rx->sdata->u.mgd.use_4addr)
 | 
			
		||||
 				return RX_DROP_UNUSABLE;
 | 
			
		||||
 			break;
 | 
			
		||||
+		case NL80211_IFTYPE_MESH_POINT:
 | 
			
		||||
+			break;
 | 
			
		||||
 		default:
 | 
			
		||||
 			return RX_DROP_UNUSABLE;
 | 
			
		||||
 		}
 | 
			
		||||
@@ -2834,155 +3020,6 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx
 | 
			
		||||
 	return __ieee80211_rx_h_amsdu(rx, 0);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-#ifdef CPTCFG_MAC80211_MESH
 | 
			
		||||
-static ieee80211_rx_result
 | 
			
		||||
-ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
 | 
			
		||||
-{
 | 
			
		||||
-	struct ieee80211_hdr *fwd_hdr, *hdr;
 | 
			
		||||
-	struct ieee80211_tx_info *info;
 | 
			
		||||
-	struct ieee80211s_hdr *mesh_hdr;
 | 
			
		||||
-	struct sk_buff *skb = rx->skb, *fwd_skb;
 | 
			
		||||
-	struct ieee80211_local *local = rx->local;
 | 
			
		||||
-	struct ieee80211_sub_if_data *sdata = rx->sdata;
 | 
			
		||||
-	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
 | 
			
		||||
-	u16 ac, q, hdrlen;
 | 
			
		||||
-	int tailroom = 0;
 | 
			
		||||
-
 | 
			
		||||
-	hdr = (struct ieee80211_hdr *) skb->data;
 | 
			
		||||
-	hdrlen = ieee80211_hdrlen(hdr->frame_control);
 | 
			
		||||
-
 | 
			
		||||
-	/* make sure fixed part of mesh header is there, also checks skb len */
 | 
			
		||||
-	if (!pskb_may_pull(rx->skb, hdrlen + 6))
 | 
			
		||||
-		return RX_DROP_MONITOR;
 | 
			
		||||
-
 | 
			
		||||
-	mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
 | 
			
		||||
-
 | 
			
		||||
-	/* make sure full mesh header is there, also checks skb len */
 | 
			
		||||
-	if (!pskb_may_pull(rx->skb,
 | 
			
		||||
-			   hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr)))
 | 
			
		||||
-		return RX_DROP_MONITOR;
 | 
			
		||||
-
 | 
			
		||||
-	/* reload pointers */
 | 
			
		||||
-	hdr = (struct ieee80211_hdr *) skb->data;
 | 
			
		||||
-	mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
 | 
			
		||||
-
 | 
			
		||||
-	if (ieee80211_drop_unencrypted(rx, hdr->frame_control)) {
 | 
			
		||||
-		int offset = hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr) +
 | 
			
		||||
-			     sizeof(rfc1042_header);
 | 
			
		||||
-		__be16 ethertype;
 | 
			
		||||
-
 | 
			
		||||
-		if (!ether_addr_equal(hdr->addr1, rx->sdata->vif.addr) ||
 | 
			
		||||
-		    skb_copy_bits(rx->skb, offset, ðertype, 2) != 0 ||
 | 
			
		||||
-		    ethertype != rx->sdata->control_port_protocol)
 | 
			
		||||
-			return RX_DROP_MONITOR;
 | 
			
		||||
-	}
 | 
			
		||||
-
 | 
			
		||||
-	/* frame is in RMC, don't forward */
 | 
			
		||||
-	if (ieee80211_is_data(hdr->frame_control) &&
 | 
			
		||||
-	    is_multicast_ether_addr(hdr->addr1) &&
 | 
			
		||||
-	    mesh_rmc_check(rx->sdata, hdr->addr3, mesh_hdr))
 | 
			
		||||
-		return RX_DROP_MONITOR;
 | 
			
		||||
-
 | 
			
		||||
-	if (!ieee80211_is_data(hdr->frame_control))
 | 
			
		||||
-		return RX_CONTINUE;
 | 
			
		||||
-
 | 
			
		||||
-	if (!mesh_hdr->ttl)
 | 
			
		||||
-		return RX_DROP_MONITOR;
 | 
			
		||||
-
 | 
			
		||||
-	if (mesh_hdr->flags & MESH_FLAGS_AE) {
 | 
			
		||||
-		struct mesh_path *mppath;
 | 
			
		||||
-		char *proxied_addr;
 | 
			
		||||
-		char *mpp_addr;
 | 
			
		||||
-
 | 
			
		||||
-		if (is_multicast_ether_addr(hdr->addr1)) {
 | 
			
		||||
-			mpp_addr = hdr->addr3;
 | 
			
		||||
-			proxied_addr = mesh_hdr->eaddr1;
 | 
			
		||||
-		} else if ((mesh_hdr->flags & MESH_FLAGS_AE) ==
 | 
			
		||||
-			    MESH_FLAGS_AE_A5_A6) {
 | 
			
		||||
-			/* has_a4 already checked in ieee80211_rx_mesh_check */
 | 
			
		||||
-			mpp_addr = hdr->addr4;
 | 
			
		||||
-			proxied_addr = mesh_hdr->eaddr2;
 | 
			
		||||
-		} else {
 | 
			
		||||
-			return RX_DROP_MONITOR;
 | 
			
		||||
-		}
 | 
			
		||||
-
 | 
			
		||||
-		rcu_read_lock();
 | 
			
		||||
-		mppath = mpp_path_lookup(sdata, proxied_addr);
 | 
			
		||||
-		if (!mppath) {
 | 
			
		||||
-			mpp_path_add(sdata, proxied_addr, mpp_addr);
 | 
			
		||||
-		} else {
 | 
			
		||||
-			spin_lock_bh(&mppath->state_lock);
 | 
			
		||||
-			if (!ether_addr_equal(mppath->mpp, mpp_addr))
 | 
			
		||||
-				memcpy(mppath->mpp, mpp_addr, ETH_ALEN);
 | 
			
		||||
-			mppath->exp_time = jiffies;
 | 
			
		||||
-			spin_unlock_bh(&mppath->state_lock);
 | 
			
		||||
-		}
 | 
			
		||||
-		rcu_read_unlock();
 | 
			
		||||
-	}
 | 
			
		||||
-
 | 
			
		||||
-	/* Frame has reached destination.  Don't forward */
 | 
			
		||||
-	if (!is_multicast_ether_addr(hdr->addr1) &&
 | 
			
		||||
-	    ether_addr_equal(sdata->vif.addr, hdr->addr3))
 | 
			
		||||
-		return RX_CONTINUE;
 | 
			
		||||
-
 | 
			
		||||
-	ac = ieee802_1d_to_ac[skb->priority];
 | 
			
		||||
-	skb_set_queue_mapping(skb, ac);
 | 
			
		||||
-
 | 
			
		||||
-	if (!--mesh_hdr->ttl) {
 | 
			
		||||
-		if (!is_multicast_ether_addr(hdr->addr1))
 | 
			
		||||
-			IEEE80211_IFSTA_MESH_CTR_INC(ifmsh,
 | 
			
		||||
-						     dropped_frames_ttl);
 | 
			
		||||
-		goto out;
 | 
			
		||||
-	}
 | 
			
		||||
-
 | 
			
		||||
-	if (!ifmsh->mshcfg.dot11MeshForwarding)
 | 
			
		||||
-		goto out;
 | 
			
		||||
-
 | 
			
		||||
-	if (sdata->crypto_tx_tailroom_needed_cnt)
 | 
			
		||||
-		tailroom = IEEE80211_ENCRYPT_TAILROOM;
 | 
			
		||||
-
 | 
			
		||||
-	fwd_skb = skb_copy_expand(skb, local->tx_headroom +
 | 
			
		||||
-				       IEEE80211_ENCRYPT_HEADROOM,
 | 
			
		||||
-				  tailroom, GFP_ATOMIC);
 | 
			
		||||
-	if (!fwd_skb)
 | 
			
		||||
-		goto out;
 | 
			
		||||
-
 | 
			
		||||
-	fwd_skb->dev = sdata->dev;
 | 
			
		||||
-	fwd_hdr =  (struct ieee80211_hdr *) fwd_skb->data;
 | 
			
		||||
-	fwd_hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_RETRY);
 | 
			
		||||
-	info = IEEE80211_SKB_CB(fwd_skb);
 | 
			
		||||
-	memset(info, 0, sizeof(*info));
 | 
			
		||||
-	info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING;
 | 
			
		||||
-	info->control.vif = &rx->sdata->vif;
 | 
			
		||||
-	info->control.jiffies = jiffies;
 | 
			
		||||
-	if (is_multicast_ether_addr(fwd_hdr->addr1)) {
 | 
			
		||||
-		IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast);
 | 
			
		||||
-		memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
 | 
			
		||||
-		/* update power mode indication when forwarding */
 | 
			
		||||
-		ieee80211_mps_set_frame_flags(sdata, NULL, fwd_hdr);
 | 
			
		||||
-	} else if (!mesh_nexthop_lookup(sdata, fwd_skb)) {
 | 
			
		||||
-		/* mesh power mode flags updated in mesh_nexthop_lookup */
 | 
			
		||||
-		IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast);
 | 
			
		||||
-	} else {
 | 
			
		||||
-		/* unable to resolve next hop */
 | 
			
		||||
-		mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl,
 | 
			
		||||
-				   fwd_hdr->addr3, 0,
 | 
			
		||||
-				   WLAN_REASON_MESH_PATH_NOFORWARD,
 | 
			
		||||
-				   fwd_hdr->addr2);
 | 
			
		||||
-		IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route);
 | 
			
		||||
-		kfree_skb(fwd_skb);
 | 
			
		||||
-		return RX_DROP_MONITOR;
 | 
			
		||||
-	}
 | 
			
		||||
-
 | 
			
		||||
-	IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames);
 | 
			
		||||
-	ieee80211_add_pending_skb(local, fwd_skb);
 | 
			
		||||
- out:
 | 
			
		||||
-	if (is_multicast_ether_addr(hdr->addr1))
 | 
			
		||||
-		return RX_CONTINUE;
 | 
			
		||||
-	return RX_DROP_MONITOR;
 | 
			
		||||
-}
 | 
			
		||||
-#endif
 | 
			
		||||
-
 | 
			
		||||
 static ieee80211_rx_result debug_noinline
 | 
			
		||||
 ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
 | 
			
		||||
 {
 | 
			
		||||
@@ -2991,6 +3028,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_
 | 
			
		||||
 	struct net_device *dev = sdata->dev;
 | 
			
		||||
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
 | 
			
		||||
 	__le16 fc = hdr->frame_control;
 | 
			
		||||
+	static ieee80211_rx_result res;
 | 
			
		||||
 	bool port_control;
 | 
			
		||||
 	int err;
 | 
			
		||||
 
 | 
			
		||||
@@ -3017,6 +3055,10 @@ ieee80211_rx_h_data(struct ieee80211_rx_
 | 
			
		||||
 	if (unlikely(err))
 | 
			
		||||
 		return RX_DROP_UNUSABLE;
 | 
			
		||||
 
 | 
			
		||||
+	res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb);
 | 
			
		||||
+	if (res != RX_CONTINUE)
 | 
			
		||||
+		return res;
 | 
			
		||||
+
 | 
			
		||||
 	if (!ieee80211_frame_allowed(rx, fc))
 | 
			
		||||
 		return RX_DROP_MONITOR;
 | 
			
		||||
 
 | 
			
		||||
@@ -3987,10 +4029,6 @@ static void ieee80211_rx_handlers(struct
 | 
			
		||||
 		CALL_RXH(ieee80211_rx_h_defragment);
 | 
			
		||||
 		CALL_RXH(ieee80211_rx_h_michael_mic_verify);
 | 
			
		||||
 		/* must be after MMIC verify so header is counted in MPDU mic */
 | 
			
		||||
-#ifdef CPTCFG_MAC80211_MESH
 | 
			
		||||
-		if (ieee80211_vif_is_mesh(&rx->sdata->vif))
 | 
			
		||||
-			CALL_RXH(ieee80211_rx_h_mesh_fwding);
 | 
			
		||||
-#endif
 | 
			
		||||
 		CALL_RXH(ieee80211_rx_h_amsdu);
 | 
			
		||||
 		CALL_RXH(ieee80211_rx_h_data);
 | 
			
		||||
 
 | 
			
		||||
--- a/net/wireless/util.c
 | 
			
		||||
+++ b/net/wireless/util.c
 | 
			
		||||
@@ -542,7 +542,7 @@ unsigned int ieee80211_get_mesh_hdrlen(s
 | 
			
		||||
 }
 | 
			
		||||
 EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen);
 | 
			
		||||
 
 | 
			
		||||
-static bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto)
 | 
			
		||||
+bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto)
 | 
			
		||||
 {
 | 
			
		||||
 	const __be16 *hdr_proto = hdr + ETH_ALEN;
 | 
			
		||||
 
 | 
			
		||||
@@ -556,6 +556,49 @@ static bool ieee80211_get_8023_tunnel_pr
 | 
			
		||||
 
 | 
			
		||||
 	return true;
 | 
			
		||||
 }
 | 
			
		||||
+EXPORT_SYMBOL(ieee80211_get_8023_tunnel_proto);
 | 
			
		||||
+
 | 
			
		||||
+int ieee80211_strip_8023_mesh_hdr(struct sk_buff *skb)
 | 
			
		||||
+{
 | 
			
		||||
+	const void *mesh_addr;
 | 
			
		||||
+	struct {
 | 
			
		||||
+		struct ethhdr eth;
 | 
			
		||||
+		u8 flags;
 | 
			
		||||
+	} payload;
 | 
			
		||||
+	int hdrlen;
 | 
			
		||||
+	int ret;
 | 
			
		||||
+
 | 
			
		||||
+	ret = skb_copy_bits(skb, 0, &payload, sizeof(payload));
 | 
			
		||||
+	if (ret)
 | 
			
		||||
+		return ret;
 | 
			
		||||
+
 | 
			
		||||
+	hdrlen = sizeof(payload.eth) + __ieee80211_get_mesh_hdrlen(payload.flags);
 | 
			
		||||
+
 | 
			
		||||
+	if (likely(pskb_may_pull(skb, hdrlen + 8) &&
 | 
			
		||||
+		   ieee80211_get_8023_tunnel_proto(skb->data + hdrlen,
 | 
			
		||||
+						   &payload.eth.h_proto)))
 | 
			
		||||
+		hdrlen += ETH_ALEN + 2;
 | 
			
		||||
+	else if (!pskb_may_pull(skb, hdrlen))
 | 
			
		||||
+		return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+	mesh_addr = skb->data + sizeof(payload.eth) + ETH_ALEN;
 | 
			
		||||
+	switch (payload.flags & MESH_FLAGS_AE) {
 | 
			
		||||
+	case MESH_FLAGS_AE_A4:
 | 
			
		||||
+		memcpy(&payload.eth.h_source, mesh_addr, ETH_ALEN);
 | 
			
		||||
+		break;
 | 
			
		||||
+	case MESH_FLAGS_AE_A5_A6:
 | 
			
		||||
+		memcpy(&payload.eth, mesh_addr, 2 * ETH_ALEN);
 | 
			
		||||
+		break;
 | 
			
		||||
+	default:
 | 
			
		||||
+		break;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	pskb_pull(skb, hdrlen - sizeof(payload.eth));
 | 
			
		||||
+	memcpy(skb->data, &payload.eth, sizeof(payload.eth));
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+EXPORT_SYMBOL(ieee80211_strip_8023_mesh_hdr);
 | 
			
		||||
 
 | 
			
		||||
 int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
 | 
			
		||||
 				  const u8 *addr, enum nl80211_iftype iftype,
 | 
			
		||||
@@ -568,7 +611,6 @@ int ieee80211_data_to_8023_exthdr(struct
 | 
			
		||||
 	} payload;
 | 
			
		||||
 	struct ethhdr tmp;
 | 
			
		||||
 	u16 hdrlen;
 | 
			
		||||
-	u8 mesh_flags = 0;
 | 
			
		||||
 
 | 
			
		||||
 	if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
 | 
			
		||||
 		return -1;
 | 
			
		||||
@@ -589,12 +631,6 @@ int ieee80211_data_to_8023_exthdr(struct
 | 
			
		||||
 	memcpy(tmp.h_dest, ieee80211_get_DA(hdr), ETH_ALEN);
 | 
			
		||||
 	memcpy(tmp.h_source, ieee80211_get_SA(hdr), ETH_ALEN);
 | 
			
		||||
 
 | 
			
		||||
-	if (iftype == NL80211_IFTYPE_MESH_POINT &&
 | 
			
		||||
-	    skb_copy_bits(skb, hdrlen, &mesh_flags, 1) < 0)
 | 
			
		||||
-		return -1;
 | 
			
		||||
-
 | 
			
		||||
-	mesh_flags &= MESH_FLAGS_AE;
 | 
			
		||||
-
 | 
			
		||||
 	switch (hdr->frame_control &
 | 
			
		||||
 		cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
 | 
			
		||||
 	case cpu_to_le16(IEEE80211_FCTL_TODS):
 | 
			
		||||
@@ -608,17 +644,6 @@ int ieee80211_data_to_8023_exthdr(struct
 | 
			
		||||
 			     iftype != NL80211_IFTYPE_AP_VLAN &&
 | 
			
		||||
 			     iftype != NL80211_IFTYPE_STATION))
 | 
			
		||||
 			return -1;
 | 
			
		||||
-		if (iftype == NL80211_IFTYPE_MESH_POINT) {
 | 
			
		||||
-			if (mesh_flags == MESH_FLAGS_AE_A4)
 | 
			
		||||
-				return -1;
 | 
			
		||||
-			if (mesh_flags == MESH_FLAGS_AE_A5_A6 &&
 | 
			
		||||
-			    skb_copy_bits(skb, hdrlen +
 | 
			
		||||
-					  offsetof(struct ieee80211s_hdr, eaddr1),
 | 
			
		||||
-					  tmp.h_dest, 2 * ETH_ALEN) < 0)
 | 
			
		||||
-				return -1;
 | 
			
		||||
-
 | 
			
		||||
-			hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags);
 | 
			
		||||
-		}
 | 
			
		||||
 		break;
 | 
			
		||||
 	case cpu_to_le16(IEEE80211_FCTL_FROMDS):
 | 
			
		||||
 		if ((iftype != NL80211_IFTYPE_STATION &&
 | 
			
		||||
@@ -627,16 +652,6 @@ int ieee80211_data_to_8023_exthdr(struct
 | 
			
		||||
 		    (is_multicast_ether_addr(tmp.h_dest) &&
 | 
			
		||||
 		     ether_addr_equal(tmp.h_source, addr)))
 | 
			
		||||
 			return -1;
 | 
			
		||||
-		if (iftype == NL80211_IFTYPE_MESH_POINT) {
 | 
			
		||||
-			if (mesh_flags == MESH_FLAGS_AE_A5_A6)
 | 
			
		||||
-				return -1;
 | 
			
		||||
-			if (mesh_flags == MESH_FLAGS_AE_A4 &&
 | 
			
		||||
-			    skb_copy_bits(skb, hdrlen +
 | 
			
		||||
-					  offsetof(struct ieee80211s_hdr, eaddr1),
 | 
			
		||||
-					  tmp.h_source, ETH_ALEN) < 0)
 | 
			
		||||
-				return -1;
 | 
			
		||||
-			hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags);
 | 
			
		||||
-		}
 | 
			
		||||
 		break;
 | 
			
		||||
 	case cpu_to_le16(0):
 | 
			
		||||
 		if (iftype != NL80211_IFTYPE_ADHOC &&
 | 
			
		||||
@@ -646,7 +661,7 @@ int ieee80211_data_to_8023_exthdr(struct
 | 
			
		||||
 		break;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	if (likely(!is_amsdu &&
 | 
			
		||||
+	if (likely(!is_amsdu && iftype != NL80211_IFTYPE_MESH_POINT &&
 | 
			
		||||
 		   skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 &&
 | 
			
		||||
 		   ieee80211_get_8023_tunnel_proto(&payload, &tmp.h_proto))) {
 | 
			
		||||
 		/* remove RFC1042 or Bridge-Tunnel encapsulation */
 | 
			
		||||
@@ -722,7 +737,8 @@ __ieee80211_amsdu_copy_frag(struct sk_bu
 | 
			
		||||
 
 | 
			
		||||
 static struct sk_buff *
 | 
			
		||||
 __ieee80211_amsdu_copy(struct sk_buff *skb, unsigned int hlen,
 | 
			
		||||
-		       int offset, int len, bool reuse_frag)
 | 
			
		||||
+		       int offset, int len, bool reuse_frag,
 | 
			
		||||
+		       int min_len)
 | 
			
		||||
 {
 | 
			
		||||
 	struct sk_buff *frame;
 | 
			
		||||
 	int cur_len = len;
 | 
			
		||||
@@ -736,7 +752,7 @@ __ieee80211_amsdu_copy(struct sk_buff *s
 | 
			
		||||
 	 * in the stack later.
 | 
			
		||||
 	 */
 | 
			
		||||
 	if (reuse_frag)
 | 
			
		||||
-		cur_len = min_t(int, len, 32);
 | 
			
		||||
+		cur_len = min_t(int, len, min_len);
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * Allocate and reserve two bytes more for payload
 | 
			
		||||
@@ -746,6 +762,7 @@ __ieee80211_amsdu_copy(struct sk_buff *s
 | 
			
		||||
 	if (!frame)
 | 
			
		||||
 		return NULL;
 | 
			
		||||
 
 | 
			
		||||
+	frame->priority = skb->priority;
 | 
			
		||||
 	skb_reserve(frame, hlen + sizeof(struct ethhdr) + 2);
 | 
			
		||||
 	skb_copy_bits(skb, offset, skb_put(frame, cur_len), cur_len);
 | 
			
		||||
 
 | 
			
		||||
@@ -762,23 +779,37 @@ __ieee80211_amsdu_copy(struct sk_buff *s
 | 
			
		||||
 void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
 | 
			
		||||
 			      const u8 *addr, enum nl80211_iftype iftype,
 | 
			
		||||
 			      const unsigned int extra_headroom,
 | 
			
		||||
-			      const u8 *check_da, const u8 *check_sa)
 | 
			
		||||
+			      const u8 *check_da, const u8 *check_sa,
 | 
			
		||||
+			      bool mesh_control)
 | 
			
		||||
 {
 | 
			
		||||
 	unsigned int hlen = ALIGN(extra_headroom, 4);
 | 
			
		||||
 	struct sk_buff *frame = NULL;
 | 
			
		||||
 	int offset = 0, remaining;
 | 
			
		||||
-	struct ethhdr eth;
 | 
			
		||||
+	struct {
 | 
			
		||||
+		struct ethhdr eth;
 | 
			
		||||
+		uint8_t flags;
 | 
			
		||||
+	} hdr;
 | 
			
		||||
 	bool reuse_frag = skb->head_frag && !skb_has_frag_list(skb);
 | 
			
		||||
 	bool reuse_skb = false;
 | 
			
		||||
 	bool last = false;
 | 
			
		||||
+	int copy_len = sizeof(hdr.eth);
 | 
			
		||||
+
 | 
			
		||||
+	if (iftype == NL80211_IFTYPE_MESH_POINT)
 | 
			
		||||
+		copy_len = sizeof(hdr);
 | 
			
		||||
 
 | 
			
		||||
 	while (!last) {
 | 
			
		||||
 		unsigned int subframe_len;
 | 
			
		||||
-		int len;
 | 
			
		||||
+		int len, mesh_len = 0;
 | 
			
		||||
 		u8 padding;
 | 
			
		||||
 
 | 
			
		||||
-		skb_copy_bits(skb, offset, ð, sizeof(eth));
 | 
			
		||||
-		len = ntohs(eth.h_proto);
 | 
			
		||||
+		skb_copy_bits(skb, offset, &hdr, copy_len);
 | 
			
		||||
+		if (iftype == NL80211_IFTYPE_MESH_POINT)
 | 
			
		||||
+			mesh_len = __ieee80211_get_mesh_hdrlen(hdr.flags);
 | 
			
		||||
+		if (mesh_control)
 | 
			
		||||
+			len = le16_to_cpu(*(__le16 *)&hdr.eth.h_proto) + mesh_len;
 | 
			
		||||
+		else
 | 
			
		||||
+			len = ntohs(hdr.eth.h_proto);
 | 
			
		||||
+
 | 
			
		||||
 		subframe_len = sizeof(struct ethhdr) + len;
 | 
			
		||||
 		padding = (4 - subframe_len) & 0x3;
 | 
			
		||||
 
 | 
			
		||||
@@ -787,16 +818,16 @@ void ieee80211_amsdu_to_8023s(struct sk_
 | 
			
		||||
 		if (subframe_len > remaining)
 | 
			
		||||
 			goto purge;
 | 
			
		||||
 		/* mitigate A-MSDU aggregation injection attacks */
 | 
			
		||||
-		if (ether_addr_equal(eth.h_dest, rfc1042_header))
 | 
			
		||||
+		if (ether_addr_equal(hdr.eth.h_dest, rfc1042_header))
 | 
			
		||||
 			goto purge;
 | 
			
		||||
 
 | 
			
		||||
 		offset += sizeof(struct ethhdr);
 | 
			
		||||
 		last = remaining <= subframe_len + padding;
 | 
			
		||||
 
 | 
			
		||||
 		/* FIXME: should we really accept multicast DA? */
 | 
			
		||||
-		if ((check_da && !is_multicast_ether_addr(eth.h_dest) &&
 | 
			
		||||
-		     !ether_addr_equal(check_da, eth.h_dest)) ||
 | 
			
		||||
-		    (check_sa && !ether_addr_equal(check_sa, eth.h_source))) {
 | 
			
		||||
+		if ((check_da && !is_multicast_ether_addr(hdr.eth.h_dest) &&
 | 
			
		||||
+		     !ether_addr_equal(check_da, hdr.eth.h_dest)) ||
 | 
			
		||||
+		    (check_sa && !ether_addr_equal(check_sa, hdr.eth.h_source))) {
 | 
			
		||||
 			offset += len + padding;
 | 
			
		||||
 			continue;
 | 
			
		||||
 		}
 | 
			
		||||
@@ -808,7 +839,7 @@ void ieee80211_amsdu_to_8023s(struct sk_
 | 
			
		||||
 			reuse_skb = true;
 | 
			
		||||
 		} else {
 | 
			
		||||
 			frame = __ieee80211_amsdu_copy(skb, hlen, offset, len,
 | 
			
		||||
-						       reuse_frag);
 | 
			
		||||
+						       reuse_frag, 32 + mesh_len);
 | 
			
		||||
 			if (!frame)
 | 
			
		||||
 				goto purge;
 | 
			
		||||
 
 | 
			
		||||
@@ -819,10 +850,11 @@ void ieee80211_amsdu_to_8023s(struct sk_
 | 
			
		||||
 		frame->dev = skb->dev;
 | 
			
		||||
 		frame->priority = skb->priority;
 | 
			
		||||
 
 | 
			
		||||
-		if (likely(ieee80211_get_8023_tunnel_proto(frame->data, ð.h_proto)))
 | 
			
		||||
+		if (likely(iftype != NL80211_IFTYPE_MESH_POINT &&
 | 
			
		||||
+			   ieee80211_get_8023_tunnel_proto(frame->data, &hdr.eth.h_proto)))
 | 
			
		||||
 			skb_pull(frame, ETH_ALEN + 2);
 | 
			
		||||
 
 | 
			
		||||
-		memcpy(skb_push(frame, sizeof(eth)), ð, sizeof(eth));
 | 
			
		||||
+		memcpy(skb_push(frame, sizeof(hdr.eth)), &hdr.eth, sizeof(hdr.eth));
 | 
			
		||||
 		__skb_queue_tail(list, frame);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -1,62 +0,0 @@
 | 
			
		|||
From: Ryder Lee <ryder.lee@mediatek.com>
 | 
			
		||||
Date: Sat, 18 Feb 2023 01:49:25 +0800
 | 
			
		||||
Subject: [PATCH] wifi: mac80211: add LDPC related flags in ieee80211_bss_conf
 | 
			
		||||
 | 
			
		||||
This is utilized to pass LDPC configurations from user space
 | 
			
		||||
(i.e. hostapd) to driver.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
 | 
			
		||||
Link: https://lore.kernel.org/r/1de696aaa34efd77a926eb657b8c0fda05aaa177.1676628065.git.ryder.lee@mediatek.com
 | 
			
		||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
--- a/include/net/mac80211.h
 | 
			
		||||
+++ b/include/net/mac80211.h
 | 
			
		||||
@@ -653,6 +653,9 @@ struct ieee80211_fils_discovery {
 | 
			
		||||
  *	write-protected by sdata_lock and local->mtx so holding either is fine
 | 
			
		||||
  *	for read access.
 | 
			
		||||
  * @color_change_color: the bss color that will be used after the change.
 | 
			
		||||
+ * @ht_ldpc: in AP mode, indicates interface has HT LDPC capability.
 | 
			
		||||
+ * @vht_ldpc: in AP mode, indicates interface has VHT LDPC capability.
 | 
			
		||||
+ * @he_ldpc: in AP mode, indicates interface has HE LDPC capability.
 | 
			
		||||
  * @vht_su_beamformer: in AP mode, does this BSS support operation as an VHT SU
 | 
			
		||||
  *	beamformer
 | 
			
		||||
  * @vht_su_beamformee: in AP mode, does this BSS support operation as an VHT SU
 | 
			
		||||
@@ -744,6 +747,9 @@ struct ieee80211_bss_conf {
 | 
			
		||||
 	bool color_change_active;
 | 
			
		||||
 	u8 color_change_color;
 | 
			
		||||
 
 | 
			
		||||
+	bool ht_ldpc;
 | 
			
		||||
+	bool vht_ldpc;
 | 
			
		||||
+	bool he_ldpc;
 | 
			
		||||
 	bool vht_su_beamformer;
 | 
			
		||||
 	bool vht_su_beamformee;
 | 
			
		||||
 	bool vht_mu_beamformer;
 | 
			
		||||
--- a/net/mac80211/cfg.c
 | 
			
		||||
+++ b/net/mac80211/cfg.c
 | 
			
		||||
@@ -1252,7 +1252,15 @@ static int ieee80211_start_ap(struct wip
 | 
			
		||||
 	prev_beacon_int = link_conf->beacon_int;
 | 
			
		||||
 	link_conf->beacon_int = params->beacon_interval;
 | 
			
		||||
 
 | 
			
		||||
+	if (params->ht_cap)
 | 
			
		||||
+		link_conf->ht_ldpc =
 | 
			
		||||
+			params->ht_cap->cap_info &
 | 
			
		||||
+				cpu_to_le16(IEEE80211_HT_CAP_LDPC_CODING);
 | 
			
		||||
+
 | 
			
		||||
 	if (params->vht_cap) {
 | 
			
		||||
+		link_conf->vht_ldpc =
 | 
			
		||||
+			params->vht_cap->vht_cap_info &
 | 
			
		||||
+				cpu_to_le32(IEEE80211_VHT_CAP_RXLDPC);
 | 
			
		||||
 		link_conf->vht_su_beamformer =
 | 
			
		||||
 			params->vht_cap->vht_cap_info &
 | 
			
		||||
 				cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE);
 | 
			
		||||
@@ -1282,6 +1290,9 @@ static int ieee80211_start_ap(struct wip
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	if (params->he_cap) {
 | 
			
		||||
+		link_conf->he_ldpc =
 | 
			
		||||
+			params->he_cap->phy_cap_info[1] &
 | 
			
		||||
+				IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD;
 | 
			
		||||
 		link_conf->he_su_beamformer =
 | 
			
		||||
 			params->he_cap->phy_cap_info[3] &
 | 
			
		||||
 				IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER;
 | 
			
		||||
							
								
								
									
										6
									
								
								build.sh
									
										
									
									
									
								
							
							
						
						
									
										6
									
								
								build.sh
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -111,9 +111,9 @@ if [ "$OMR_OPENWRT" = "default" ]; then
 | 
			
		|||
		_get_repo feeds/${OMR_KERNEL}/packages https://github.com/openwrt/packages "8939b43659dabe9b737feee02976949ad0355adc"
 | 
			
		||||
		_get_repo feeds/${OMR_KERNEL}/luci https://github.com/openwrt/luci "3e14e055a177dec4bd3a4bd40883b56a6930fd7c"
 | 
			
		||||
	elif [ "$OMR_KERNEL" = "6.1" ]; then
 | 
			
		||||
		_get_repo "$OMR_TARGET/${OMR_KERNEL}/source" https://github.com/openwrt/openwrt "ce6ad123e76311d2a882054b4ea532d1bfb643c8"
 | 
			
		||||
		_get_repo feeds/${OMR_KERNEL}/packages https://github.com/openwrt/packages "f3a6491674ab451535e392b63e94a545abf3f292"
 | 
			
		||||
		_get_repo feeds/${OMR_KERNEL}/luci https://github.com/openwrt/luci "b17650fbd23ee9028b8a7aa55e3a9615ddf934f8"
 | 
			
		||||
		_get_repo "$OMR_TARGET/${OMR_KERNEL}/source" https://github.com/openwrt/openwrt "74e7f8ebbdc19c58ac59c792154041a6b3c124f5"
 | 
			
		||||
		_get_repo feeds/${OMR_KERNEL}/packages https://github.com/openwrt/packages "b738e42c4de80bcc59559c436618e42845d62fc1"
 | 
			
		||||
		_get_repo feeds/${OMR_KERNEL}/luci https://github.com/openwrt/luci "957a6313bd6371e5afae20573a43f5440948e66e"
 | 
			
		||||
	fi
 | 
			
		||||
elif [ "$OMR_OPENWRT" = "coolsnowwolfmix" ]; then
 | 
			
		||||
	_get_repo "$OMR_TARGET/${OMR_KERNEL}/source" https://github.com/coolsnowwolf/lede.git "master"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue